diff --git a/DEPS b/DEPS
index 42728e7f..15935e4 100644
--- a/DEPS
+++ b/DEPS
@@ -190,7 +190,7 @@
   # luci-go CIPD package version.
   # Make sure the revision is uploaded by infra-packagers builder.
   # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console
-  'luci_go': 'git_revision:01aa19ce019f7bf94712f3dd2538cf72a2a3451b',
+  'luci_go': 'git_revision:2ac8bd9cbc20824bb04a39b0f1b77178ace930b3',
 
   # This can be overridden, e.g. with custom_vars, to build clang from HEAD
   # instead of downloading the prebuilt pinned revision.
@@ -222,11 +222,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'cc29a39d42ac68a390e5e5a6da6e5b79394faf34',
+  'skia_revision': '224e3e257d06370581aed9e2450255a45c398362',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'fb195c9d92e66d45abbd1488b3a2e0e15a4c8ade',
+  'v8_revision': 'eff3248b5ca008c38746a8dafcfc602b8af08692',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -269,7 +269,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': '7d3880119eeff880e5c2108324ad97b28ed3e2ba',
+  'nacl_revision': 'c99c097393be34b251bf6052fe218dd25b588e6d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -293,7 +293,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': '4a3ec1268ebbfd6b268be5a643f1461fb96c920a',
+  'catapult_revision': '3345f09ed65020a999e108ea37d30b49c87e14ed',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -301,7 +301,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': '35c7fa3507224e2a9d584cf4a9a7af93b2605aae',
+  'devtools_frontend_revision': '1bab4fac8033bb66f763730694c0ab475f8c596c',
   # 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.
@@ -341,7 +341,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': '48de25e52a33098b8765ce3354d8cc50e86ad65a',
+  'dawn_revision': '2103fa629e98a30b2c5e93bcc002e40cbd3f6d5f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -581,7 +581,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '9e15d4d1ad54c5d5ca2048b4f2b0fe490c51a7ff',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'e77917902f563d81affa526bf72c62e2a43baad3',
       'condition': 'checkout_ios',
   },
 
@@ -738,7 +738,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'jiRYYawcc0irI4AKkkbC0H2fB0mv4vUpWlsqcDKOdMoC',
+          'version': '-umIXLPTAdxRy2iaK4QFSeOf4t7PAKglJP7ggvWhfRwC',
       },
     ],
     'condition': 'checkout_android',
@@ -1449,7 +1449,7 @@
       'packages': [
           {
               'package': 'fuchsia/third_party/aemu/linux-amd64',
-              'version': 'QunhZeUueNJF63FP9uXIb-TVJNazpdKD5TQAi_D7ZLEC'
+              'version': 'qX01xcawvl_sWzKM7dt-kmo0g3eQKDU33EjLMClSPwIC'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia',
@@ -1592,7 +1592,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e2aeec9de7a742ae131b2f56fc22de6b17b8d0e1',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '4e18a1fff3b34e2fab4c8f3e1fc2402716b54117',
+    Var('webrtc_git') + '/src.git' + '@' + '3fcd31c4e52957ca0c411f73fb56e7f8929d3697',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1653,7 +1653,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0795397ad4f5646f1953d92eca7194c3b8ff4304',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@758587f613f5abff5476a59c64d84b3f065c2d57',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/components/audio/audio_devices_pref_handler_impl.cc b/ash/components/audio/audio_devices_pref_handler_impl.cc
index e15db82..8386d6d 100644
--- a/ash/components/audio/audio_devices_pref_handler_impl.cc
+++ b/ash/components/audio/audio_devices_pref_handler_impl.cc
@@ -123,7 +123,7 @@
     std::string old_device_id = GetVersionedDeviceIdString(device, 1);
     device_volume_settings_->RemoveKey(old_device_id);
   }
-  device_volume_settings_->SetDouble(GetDeviceIdString(device), value);
+  device_volume_settings_->SetDoubleKey(GetDeviceIdString(device), value);
 
   SaveDevicesVolumePref();
 }
@@ -143,7 +143,7 @@
     SaveDevicesVolumePref();
   }
 
-  device_gain_settings_->SetDouble(device_id, value);
+  device_gain_settings_->SetDoubleKey(device_id, value);
   SaveDevicesGainPref();
 }
 
@@ -389,7 +389,7 @@
     // If there was no recorded value for deprecated device ID, use value from
     // global vloume pref.
     double old_volume = local_state_->GetDouble(prefs::kAudioVolumePercent);
-    device_volume_settings_->SetDouble(device_key, old_volume);
+    device_volume_settings_->SetDoubleKey(device_key, old_volume);
   }
   SaveDevicesVolumePref();
 }
diff --git a/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc b/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc
index d4954ab55..b1754897 100644
--- a/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc
+++ b/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc
@@ -121,7 +121,7 @@
       DictionaryPrefUpdate update(pref_service_.get(),
                                   prefs::kAudioDevicesVolumePercent);
       base::DictionaryValue* pref = update.Get();
-      pref->SetDouble(preset_key, kPresetState.sound_level);
+      pref->SetDoubleKey(preset_key, kPresetState.sound_level);
     }
 
     {
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index ffce455..d1e3c99 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -484,6 +484,11 @@
 const base::Feature kFilesArchivemount{"FilesArchivemount",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enable the updated banner framework.
+// https://crbug.com/1228128
+const base::Feature kFilesBannerFramework{"FilesBannerFramework",
+                                          base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables the System Web App (SWA) version of file manager.
 const base::Feature kFilesSWA{"FilesSWA", base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index f1b5f55a..1837cad 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -189,6 +189,8 @@
 extern const base::Feature kFamilyLinkOnSchoolDevice;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFastPair;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesArchivemount;
+COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const base::Feature kFilesBannerFramework;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesSWA;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kFilesSinglePartitionFormat;
diff --git a/ash/display/display_prefs.cc b/ash/display/display_prefs.cc
index 476f69c..b583b6e 100644
--- a/ash/display/display_prefs.cc
+++ b/ash/display/display_prefs.cc
@@ -550,7 +550,7 @@
 
       if (display::features::IsListAllDisplayModesEnabled()) {
         property_value.SetBoolean("interlaced", mode.is_interlaced());
-        property_value.SetDouble("refresh-rate", mode.refresh_rate());
+        property_value.SetDoubleKey("refresh-rate", mode.refresh_rate());
       }
     }
     if (!info.overscan_insets_in_dip().IsEmpty())
@@ -563,7 +563,7 @@
                        &property_value);
     }
 
-    property_value.SetDouble(kDisplayZoom, info.zoom_factor());
+    property_value.SetDoubleKey(kDisplayZoom, info.zoom_factor());
 
     pref_data->SetKey(base::NumberToString(id), std::move(property_value));
   }
@@ -715,7 +715,7 @@
 void StoreExternalDisplayMirrorInfo(PrefService* pref_service) {
   ListPrefUpdate update(pref_service, prefs::kExternalDisplayMirrorInfo);
   base::ListValue* pref_data = update.Get();
-  pref_data->Clear();
+  pref_data->ClearList();
   const std::set<int64_t>& external_display_mirror_info =
       GetDisplayManager()->external_display_mirror_info();
   for (const auto& id : external_display_mirror_info)
diff --git a/ash/display/display_prefs_unittest.cc b/ash/display/display_prefs_unittest.cc
index 1dfe9e0b..5590607 100644
--- a/ash/display/display_prefs_unittest.cc
+++ b/ash/display/display_prefs_unittest.cc
@@ -216,7 +216,7 @@
       const std::set<int64_t>& external_display_mirror_info) {
     ListPrefUpdate update(local_state(), prefs::kExternalDisplayMirrorInfo);
     base::ListValue* pref_data = update.Get();
-    pref_data->Clear();
+    pref_data->ClearList();
     for (const auto& id : external_display_mirror_info)
       pref_data->Append(base::Value(base::NumberToString(id)));
   }
diff --git a/ash/quick_pair/common/BUILD.gn b/ash/quick_pair/common/BUILD.gn
index 41d549a..0ba32d2 100644
--- a/ash/quick_pair/common/BUILD.gn
+++ b/ash/quick_pair/common/BUILD.gn
@@ -15,6 +15,8 @@
   sources = [
     "device.cc",
     "device.h",
+    "fast_pair/fast_pair_decoder.cc",
+    "fast_pair/fast_pair_decoder.h",
     "log_buffer.cc",
     "log_buffer.h",
     "logging.cc",
@@ -30,7 +32,11 @@
 
 source_set("unit_tests") {
   testonly = true
-  sources = [ "logging_unittest.cc" ]
+
+  sources = [
+    "fast_pair/fast_pair_decoder_unittest.cc",
+    "logging_unittest.cc",
+  ]
 
   deps = [
     ":common",
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_decoder.cc b/ash/quick_pair/common/fast_pair/fast_pair_decoder.cc
new file mode 100644
index 0000000..13781e52
--- /dev/null
+++ b/ash/quick_pair/common/fast_pair/fast_pair_decoder.cc
@@ -0,0 +1,88 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/quick_pair/common/fast_pair/fast_pair_decoder.h"
+
+#include <vector>
+#include "base/strings/string_number_conversions.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace {
+
+constexpr int kMinModelIdLength = 3;
+constexpr int kHeaderIndex = 0;
+constexpr int kHeaderLengthBitmask = 0b00011110;
+constexpr int kHeaderLengthOffset = 1;
+constexpr int kHeaderVersionBitmask = 0b11100000;
+constexpr int kHeaderVersionOffset = 5;
+constexpr int kMaxModelIdLength = 14;
+constexpr int kHeaderLength = 1;
+
+int GetVersion(const std::vector<uint8_t>* service_data) {
+  return service_data->size() == kMinModelIdLength
+             ? 0
+             : ((*service_data)[kHeaderIndex] & kHeaderVersionBitmask) >>
+                   kHeaderVersionOffset;
+}
+
+int GetIdLength(const std::vector<uint8_t>* service_data) {
+  return service_data->size() == kMinModelIdLength
+             ? kMinModelIdLength
+             : ((*service_data)[kHeaderIndex] & kHeaderLengthBitmask) >>
+                   kHeaderLengthOffset;
+}
+
+bool IsIdLengthValid(const std::vector<uint8_t>* service_data) {
+  int id_length = GetIdLength(service_data);
+  return kMinModelIdLength <= id_length && id_length <= kMaxModelIdLength &&
+         id_length + kHeaderLength <= static_cast<int>(service_data->size());
+}
+
+}  // namespace
+
+namespace ash {
+namespace quick_pair {
+namespace fast_pair_decoder {
+
+bool HasModelId(const std::vector<uint8_t>* service_data) {
+  return service_data != nullptr &&
+         (service_data->size() == kMinModelIdLength ||
+          // Header byte exists. We support only format version 0. (A different
+          // version indicates a breaking change in the format.)
+          (service_data->size() > kMinModelIdLength &&
+           GetVersion(service_data) == 0 && IsIdLengthValid(service_data)));
+}
+
+absl::optional<std::string> GetHexModelIdFromServiceData(
+    const std::vector<uint8_t>* service_data) {
+  if (service_data == nullptr || service_data->size() < kMinModelIdLength)
+    return absl::nullopt;
+  else if (service_data->size() == kMinModelIdLength)
+    // If the size is 3, all the bytes are the ID,
+    return base::HexEncode(service_data->data(), kMinModelIdLength);
+  else {
+    // Otherwise, the first byte is a header which contains the length of the
+    // big-endian model ID that follows. The model ID will be trimmed if it
+    // contains leading zeros.
+    int id_index = 1;
+    int end = id_index + GetIdLength(service_data);
+
+    // Ignore leading zeros.
+    while ((*service_data)[id_index] == 0 && end - id_index > kMinModelIdLength)
+      id_index++;
+
+    // Copy appropriate bytes to new array.
+    int bytes_size = end - id_index;
+    uint8_t bytes[bytes_size];
+
+    for (int i = 0; i < bytes_size; i++)
+      bytes[i] = (*service_data)[i + id_index];
+
+    return base::HexEncode(bytes, bytes_size);
+  }
+}
+
+}  // namespace fast_pair_decoder
+}  // namespace quick_pair
+}  // namespace ash
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_decoder.h b/ash/quick_pair/common/fast_pair/fast_pair_decoder.h
new file mode 100644
index 0000000..13d15ae
--- /dev/null
+++ b/ash/quick_pair/common/fast_pair/fast_pair_decoder.h
@@ -0,0 +1,27 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_DECODER_H_
+#define ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_DECODER_H_
+
+#include <vector>
+#include "base/component_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace ash {
+namespace quick_pair {
+namespace fast_pair_decoder {
+
+COMPONENT_EXPORT(QUICK_PAIR_COMMON)
+bool HasModelId(const std::vector<uint8_t>* service_data);
+
+COMPONENT_EXPORT(QUICK_PAIR_COMMON)
+absl::optional<std::string> GetHexModelIdFromServiceData(
+    const std::vector<uint8_t>* service_data);
+
+}  // namespace fast_pair_decoder
+}  // namespace quick_pair
+}  // namespace ash
+
+#endif  // ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_DECODER_H_
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_decoder_unittest.cc b/ash/quick_pair/common/fast_pair/fast_pair_decoder_unittest.cc
new file mode 100644
index 0000000..925cdaf
--- /dev/null
+++ b/ash/quick_pair/common/fast_pair/fast_pair_decoder_unittest.cc
@@ -0,0 +1,208 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/quick_pair/common/fast_pair/fast_pair_decoder.h"
+
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <vector>
+
+#include "base/strings/string_number_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace {
+
+const std::string kModelId = "AABBCC";
+const std::string kLongModelId = "1122334455667788";
+const std::string kPaddedModelId = "00001111";
+const std::string kTrimmedModelId = "001111";
+constexpr uint8_t kLongModelIdHeader = 0b00010000;
+constexpr uint8_t kPaddedLongModelIdHeader = 0b00001000;
+
+// Convenience class with Builder to create byte arrays which represent Fast
+// Pair Service Data.
+class FastPairServiceDataCreator {
+ public:
+  class Builder {
+   public:
+    Builder& SetHeader(uint8_t byte) {
+      header_ = byte;
+      return *this;
+    }
+
+    Builder& SetModelId(std::string model_id) {
+      model_id_ = model_id;
+      return *this;
+    }
+
+    Builder& AddExtraFieldHeader(uint8_t header) {
+      extra_field_headers_.push_back(header);
+      return *this;
+    }
+
+    Builder& AddExtraField(std::string field) {
+      extra_fields_.push_back(field);
+      return *this;
+    }
+
+    std::unique_ptr<FastPairServiceDataCreator> Build() {
+      return std::make_unique<FastPairServiceDataCreator>(
+          header_, model_id_, extra_field_headers_, extra_fields_);
+    }
+
+   private:
+    absl::optional<uint8_t> header_;
+    absl::optional<std::string> model_id_;
+    std::vector<uint8_t> extra_field_headers_;
+    std::vector<std::string> extra_fields_;
+  };
+
+  FastPairServiceDataCreator(absl::optional<uint8_t> header,
+                             absl::optional<std::string> model_id,
+                             std::vector<uint8_t> extra_field_headers,
+                             std::vector<std::string> extra_fields)
+      : header_(header),
+        model_id_(model_id),
+        extra_field_headers_(extra_field_headers),
+        extra_fields_(extra_fields) {}
+
+  std::vector<uint8_t> CreateServiceData() {
+    DCHECK_EQ(extra_field_headers_.size(), extra_fields_.size());
+
+    std::vector<uint8_t> service_data;
+
+    if (header_)
+      service_data.push_back(header_.value());
+
+    if (model_id_) {
+      std::vector<uint8_t> model_id_bytes;
+      base::HexStringToBytes(model_id_.value(), &model_id_bytes);
+      std::move(std::begin(model_id_bytes), std::end(model_id_bytes),
+                std::back_inserter(service_data));
+    }
+
+    for (size_t i = 0; i < extra_field_headers_.size(); i++) {
+      service_data.push_back(extra_field_headers_[i]);
+      std::vector<uint8_t> extra_field_bytes;
+      base::HexStringToBytes(extra_fields_[i], &extra_field_bytes);
+      std::move(std::begin(extra_field_bytes), std::end(extra_field_bytes),
+                std::back_inserter(service_data));
+    }
+
+    return service_data;
+  }
+
+ private:
+  absl::optional<uint8_t> header_;
+  absl::optional<std::string> model_id_;
+  std::vector<uint8_t> extra_field_headers_;
+  std::vector<std::string> extra_fields_;
+};
+
+}  // namespace
+
+namespace ash {
+namespace quick_pair {
+namespace fast_pair_decoder {
+
+class FastPairDecoderTest : public testing::Test {
+ protected:
+  bool HasModelIdString(std::string model_id) {
+    std::vector<uint8_t> bytes;
+    base::HexStringToBytes(model_id, &bytes);
+    return HasModelId(&bytes);
+  }
+};
+
+TEST_F(FastPairDecoderTest, HasModelId_ThreeByteFormat) {
+  EXPECT_TRUE(HasModelIdString(kModelId));
+}
+
+TEST_F(FastPairDecoderTest, HasModelId_TooShort) {
+  EXPECT_FALSE(HasModelIdString("11"));
+}
+
+TEST_F(FastPairDecoderTest, HasModelId_LongFormat) {
+  std::vector<uint8_t> bytes = FastPairServiceDataCreator::Builder()
+                                   .SetHeader(0b00001000)
+                                   .SetModelId("11223344")
+                                   .Build()
+                                   ->CreateServiceData();
+  EXPECT_TRUE(HasModelId(&bytes));
+
+  bytes = FastPairServiceDataCreator::Builder()
+              .SetHeader(0b00001010)
+              .SetModelId("1122334455")
+              .Build()
+              ->CreateServiceData();
+
+  EXPECT_TRUE(HasModelId(&bytes));
+}
+
+TEST_F(FastPairDecoderTest, HasModelId_LongInvalidVersion) {
+  std::vector<uint8_t> bytes = FastPairServiceDataCreator::Builder()
+                                   .SetHeader(0b00101000)
+                                   .SetModelId("11223344")
+                                   .Build()
+                                   ->CreateServiceData();
+  EXPECT_FALSE(HasModelId(&bytes));
+}
+
+TEST_F(FastPairDecoderTest, HasModelId_LongInvalidLength) {
+  std::vector<uint8_t> bytes = FastPairServiceDataCreator::Builder()
+                                   .SetHeader(0b00001010)
+                                   .SetModelId("11223344")
+                                   .Build()
+                                   ->CreateServiceData();
+  EXPECT_FALSE(HasModelId(&bytes));
+
+  bytes = FastPairServiceDataCreator::Builder()
+              .SetHeader(0b00000010)
+              .SetModelId("11223344")
+              .Build()
+              ->CreateServiceData();
+
+  EXPECT_FALSE(HasModelId(&bytes));
+}
+
+TEST_F(FastPairDecoderTest, GetHexModelIdFromServiceData_NoResultForNullData) {
+  EXPECT_EQ(GetHexModelIdFromServiceData(nullptr), absl::nullopt);
+}
+
+TEST_F(FastPairDecoderTest, GetHexModelIdFromServiceData_NoResultForEmptyData) {
+  std::vector<uint8_t> empty;
+  EXPECT_EQ(GetHexModelIdFromServiceData(&empty), absl::nullopt);
+}
+
+TEST_F(FastPairDecoderTest, GetHexModelIdFromServiceData_ThreeByteData) {
+  std::vector<uint8_t> bytes;
+  base::HexStringToBytes(kModelId, &bytes);
+  EXPECT_EQ(GetHexModelIdFromServiceData(&bytes), kModelId);
+}
+
+TEST_F(FastPairDecoderTest, GetHexModelIdFromServiceData_LongModelId) {
+  std::vector<uint8_t> service_data = FastPairServiceDataCreator::Builder()
+                                          .SetHeader(kLongModelIdHeader)
+                                          .SetModelId(kLongModelId)
+                                          .Build()
+                                          ->CreateServiceData();
+
+  EXPECT_EQ(GetHexModelIdFromServiceData(&service_data), kLongModelId);
+}
+
+TEST_F(FastPairDecoderTest, GetHexModelIdFromServiceData_LongModelIdTrimmed) {
+  std::vector<uint8_t> service_data = FastPairServiceDataCreator::Builder()
+                                          .SetHeader(kPaddedLongModelIdHeader)
+                                          .SetModelId(kPaddedModelId)
+                                          .Build()
+                                          ->CreateServiceData();
+
+  EXPECT_EQ(GetHexModelIdFromServiceData(&service_data), kTrimmedModelId);
+}
+
+}  // namespace fast_pair_decoder
+}  // namespace quick_pair
+}  // namespace ash
diff --git a/ash/system/power/power_button_controller_unittest.cc b/ash/system/power/power_button_controller_unittest.cc
index 20bbf6ba..fd2faa9 100644
--- a/ash/system/power/power_button_controller_unittest.cc
+++ b/ash/system/power/power_button_controller_unittest.cc
@@ -1103,8 +1103,8 @@
       default:
         return;
     }
-    position_info.SetDouble(PowerButtonController::kPositionField,
-                            kPowerButtonPercentage);
+    position_info.SetDoubleKey(PowerButtonController::kPositionField,
+                               kPowerButtonPercentage);
 
     std::string json_position_info;
     base::JSONWriter::Write(position_info, &json_position_info);
diff --git a/ash/wallpaper/wallpaper_view.cc b/ash/wallpaper/wallpaper_view.cc
index 43f159c..d03ffba 100644
--- a/ash/wallpaper/wallpaper_view.cc
+++ b/ash/wallpaper/wallpaper_view.cc
@@ -221,8 +221,9 @@
   *out_wallpaper_view = wallpaper_view;
   int animation_type =
       controller->ShouldShowInitialAnimation()
-          ? WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE
-          : wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE;
+          ? static_cast<int>(
+                WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE)
+          : static_cast<int>(wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
   aura::Window* wallpaper_window = wallpaper_widget->GetNativeWindow();
   ::wm::SetWindowVisibilityAnimationType(wallpaper_window, animation_type);
 
diff --git a/ash/wm/desks/desks_restore_util.cc b/ash/wm/desks/desks_restore_util.cc
index f20b6c98..02ed046d 100644
--- a/ash/wm/desks/desks_restore_util.cc
+++ b/ash/wm/desks/desks_restore_util.cc
@@ -206,7 +206,7 @@
 
   ListPrefUpdate name_update(primary_user_prefs, prefs::kDesksNamesList);
   base::ListValue* name_pref_data = name_update.Get();
-  name_pref_data->Clear();
+  name_pref_data->ClearList();
 
   const auto& desks = DesksController::Get()->desks();
   for (const auto& desk : desks) {
@@ -234,7 +234,7 @@
   // Save per-desk metrics.
   ListPrefUpdate metrics_update(primary_user_prefs, prefs::kDesksMetricsList);
   base::ListValue* metrics_pref_data = metrics_update.Get();
-  metrics_pref_data->Clear();
+  metrics_pref_data->ClearList();
 
   auto* desks_controller = DesksController::Get();
   const auto& desks = desks_controller->desks();
diff --git a/ash/wm/workspace/backdrop_controller.cc b/ash/wm/workspace/backdrop_controller.cc
index bb7921a..ef92dec 100644
--- a/ash/wm/workspace/backdrop_controller.cc
+++ b/ash/wm/workspace/backdrop_controller.cc
@@ -549,9 +549,10 @@
     return;
 
   ScopedWindowVisibilityAnimationTypeResetter resetter{
-      backdrop_window_, WindowState::Get(window_having_backdrop_)->CanMaximize()
-                            ? WINDOW_VISIBILITY_ANIMATION_TYPE_STEP_END
-                            : ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE};
+      backdrop_window_,
+      WindowState::Get(window_having_backdrop_)->CanMaximize()
+          ? static_cast<int>(WINDOW_VISIBILITY_ANIMATION_TYPE_STEP_END)
+          : static_cast<int>(::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE)};
   backdrop_->Show();
 }
 
diff --git a/base/android/orderfile/orderfile_call_graph_instrumentation.cc b/base/android/orderfile/orderfile_call_graph_instrumentation.cc
index f8bc3cc0..1b08826 100644
--- a/base/android/orderfile/orderfile_call_graph_instrumentation.cc
+++ b/base/android/orderfile/orderfile_call_graph_instrumentation.cc
@@ -240,11 +240,11 @@
 
   // This can get very large as it  constructs the whole data structure in
   // memory before dumping it to the file.
-  DictionaryValue root;
+  Value root(Value::Type::DICTIONARY);
   uint32_t total_calls_count = g_calls_count.load(std::memory_order_relaxed);
   root.SetStringKey("total_calls_count",
                     base::StringPrintf("%" PRIu32, total_calls_count));
-  ListValue call_graph;
+  Value call_graph(Value::Type::LIST);
   for (size_t i = 0; i < kMaxElements; i++) {
     auto caller_index =
         callee_map[i].load(std::memory_order_relaxed) * kTotalBuckets;
@@ -252,14 +252,14 @@
       // This callee was never called.
       continue;
 
-    DictionaryValue callee_element;
+    Value callee_element(Value::Type::DICTIONARY);
     uint32_t callee_offset = i * 4;
     callee_element.SetStringKey("index",
                                 base::StringPrintf("%" PRIuS, caller_index));
     callee_element.SetStringKey("callee_offset",
                                 base::StringPrintf("%" PRIu32, callee_offset));
     std::string offset_str;
-    ListValue callers_list;
+    Value callers_list(Value::Type::LIST);
     for (size_t j = 0; j < kTotalBuckets; j++) {
       uint32_t caller_offset =
           g_caller_offset[caller_index + j].load(std::memory_order_relaxed);
@@ -278,7 +278,7 @@
         // No misses.
         continue;
 
-      DictionaryValue caller_count;
+      Value caller_count(Value::Type::DICTIONARY);
       caller_count.SetStringKey("caller_offset",
                                 base::StringPrintf("%" PRIu32, caller_offset));
       caller_count.SetStringKey("count", base::StringPrintf("%" PRIu32, count));
diff --git a/base/json/json_writer.h b/base/json/json_writer.h
index d66b46f..a9e11dd 100644
--- a/base/json/json_writer.h
+++ b/base/json/json_writer.h
@@ -41,7 +41,7 @@
   // The output string is overwritten and not appended.
   //
   // TODO(tc): Should we generate json if it would be invalid json (e.g.,
-  // |node| is not a DictionaryValue/ListValue or if there are inf/-inf float
+  // |node| is not a dictionary/list Value or if there are inf/-inf float
   // values)? Return true on success and false on failure.
   static bool Write(const Value& node,
                     std::string* json,
diff --git a/base/task/thread_pool/task_tracker.cc b/base/task/thread_pool/task_tracker.cc
index 44c6d52..cf87a31 100644
--- a/base/task/thread_pool/task_tracker.cc
+++ b/base/task/thread_pool/task_tracker.cc
@@ -66,7 +66,7 @@
 };
 
 void TaskTracingInfo::AppendAsTraceFormat(std::string* out) const {
-  DictionaryValue dict;
+  Value dict(Value::Type::DICTIONARY);
 
   dict.SetStringKey("task_priority",
                     base::TaskPriorityToString(task_traits_.priority()));
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/UserActionTester.java b/base/test/android/javatests/src/org/chromium/base/test/util/UserActionTester.java
index 88e3551..74b33dab 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/util/UserActionTester.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/util/UserActionTester.java
@@ -4,6 +4,8 @@
 
 package org.chromium.base.test.util;
 
+import androidx.annotation.GuardedBy;
+
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.metrics.RecordUserAction;
 
@@ -14,6 +16,7 @@
  * A util class that records UserActions.
  */
 public class UserActionTester implements RecordUserAction.UserActionCallback {
+    @GuardedBy("mActions")
     private List<String> mActions;
 
     public UserActionTester() {
@@ -37,15 +40,22 @@
 
     @Override
     public void onActionRecorded(String action) {
-        mActions.add(action);
+        synchronized (mActions) {
+            mActions.add(action);
+        }
     }
 
+    /**
+     * @return A copy of the current list of recorded UserActions.
+     */
     public List<String> getActions() {
-        return mActions;
+        synchronized (mActions) {
+            return new ArrayList<>(mActions);
+        }
     }
 
     @Override
     public String toString() {
-        return "Actions: " + mActions.toString();
+        return "Actions: " + getActions();
     }
 }
diff --git a/base/trace_event/trace_config_unittest.cc b/base/trace_event/trace_config_unittest.cc
index 0ae79f5..cb707d4 100644
--- a/base/trace_event/trace_config_unittest.cc
+++ b/base/trace_event/trace_config_unittest.cc
@@ -284,7 +284,7 @@
   CheckDefaultTraceConfigBehavior(tc_empty_json_string);
 
   // Constructor from dictionary value.
-  DictionaryValue dict;
+  Value dict(Value::Type::DICTIONARY);
   TraceConfig tc_dict(dict);
   EXPECT_STREQ("", tc_dict.ToCategoryFilterString().c_str());
   EXPECT_STREQ(kDefaultTraceConfigString, tc_dict.ToString().c_str());
@@ -333,7 +333,7 @@
 
 TEST(TraceConfigTest, TraceConfigFromDict) {
   // Passing in empty dictionary will result in default trace config.
-  DictionaryValue dict;
+  Value dict(Value::Type::DICTIONARY);
   TraceConfig tc(dict);
   EXPECT_STREQ(kDefaultTraceConfigString, tc.ToString().c_str());
   EXPECT_EQ(RECORD_UNTIL_FULL, tc.GetTraceRecordMode());
diff --git a/base/trace_event/trace_event_memory_overhead.cc b/base/trace_event/trace_event_memory_overhead.cc
index 34c785a..9f316739 100644
--- a/base/trace_event/trace_event_memory_overhead.cc
+++ b/base/trace_event/trace_event_memory_overhead.cc
@@ -103,33 +103,28 @@
       Add(kBaseValue, sizeof(Value));
       break;
 
-    case Value::Type::STRING: {
+    case Value::Type::STRING:
       Add(kBaseValue, sizeof(Value));
       AddString(value.GetString());
-    } break;
+      break;
 
-    case Value::Type::BINARY: {
+    case Value::Type::BINARY:
       Add(kBaseValue, sizeof(Value) + value.GetBlob().size());
-    } break;
+      break;
 
-    case Value::Type::DICTIONARY: {
-      const DictionaryValue* dictionary_value = nullptr;
-      value.GetAsDictionary(&dictionary_value);
-      Add(kBaseValue, sizeof(DictionaryValue));
-      for (DictionaryValue::Iterator it(*dictionary_value); !it.IsAtEnd();
-           it.Advance()) {
-        AddString(it.key());
-        AddValue(it.value());
+    case Value::Type::DICTIONARY:
+      Add(kBaseValue, sizeof(Value));
+      for (const auto& pair : value.DictItems()) {
+        AddString(pair.first);
+        AddValue(pair.second);
       }
-    } break;
+      break;
 
-    case Value::Type::LIST: {
-      const ListValue* list_value = nullptr;
-      value.GetAsList(&list_value);
-      Add(kBaseValue, sizeof(ListValue));
-      for (const auto& v : list_value->GetList())
+    case Value::Type::LIST:
+      Add(kBaseValue, sizeof(Value));
+      for (const auto& v : value.GetList())
         AddValue(v);
-    } break;
+      break;
 
     default:
       NOTREACHED();
diff --git a/base/values.cc b/base/values.cc
index c6bc817..1bd214d 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -1576,15 +1576,6 @@
   list().emplace_back(in_value);
 }
 
-bool ListValue::Insert(size_t index, std::unique_ptr<Value> in_value) {
-  DCHECK(in_value);
-  if (index > list().size())
-    return false;
-
-  list().insert(list().begin() + index, std::move(*in_value));
-  return true;
-}
-
 void ListValue::Swap(ListValue* other) {
   CHECK(other->is_list());
   list().swap(other->list());
diff --git a/base/values.h b/base/values.h
index 33424506..186ceb8 100644
--- a/base/values.h
+++ b/base/values.h
@@ -878,12 +878,6 @@
   void AppendString(StringPiece in_value);
   void AppendString(const std::u16string& in_value);
 
-  using Value::Insert;
-  // Insert a Value at index.
-  // Returns true if successful, or false if the index was out of range.
-  // DEPRECATED, use `Value::Insert()` instead.
-  bool Insert(size_t index, std::unique_ptr<Value> in_value);
-
   // Swaps contents with the `other` list.
   // DEPRECATED, use `GetList()::swap()` instead.
   void Swap(ListValue* other);
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 96bcc3a..73a5c45 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -1490,7 +1490,7 @@
   ListValue list;
   list.Append(std::make_unique<Value>());
   EXPECT_FALSE(list.GetList().empty());
-  list.Clear();
+  list.ClearList();
   EXPECT_TRUE(list.GetList().empty());
 }
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index f6b07a68..e157ee9 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1598,6 +1598,8 @@
         # Flags NaCl (Clang 3.7) and Xcode 9.2 (Clang clang-900.0.39.2) do not
         # recognize.
         cflags += [
+          "-Wenum-compare-conditional",
+
           # An ABI compat warning we don't care about, https://crbug.com/1102157
           # TODO(thakis): Push this to the (few) targets that need it,
           # instead of having a global flag.
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 8d33813f..aa378246 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-5.20210712.3.1
+5.20210713.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 8d33813f..aa378246 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-5.20210712.3.1
+5.20210713.0.1
diff --git a/chrome/VERSION b/chrome/VERSION
index 2c6b136..1e49a7a 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=93
 MINOR=0
-BUILD=4574
+BUILD=4575
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index eb705d1b..3b1ac214 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -901,6 +901,7 @@
     "//chrome/browser/android/browserservices/constants:java",
     "//chrome/browser/android/browserservices/intents:java",
     "//chrome/browser/android/browserservices/intents:junit",
+    "//chrome/browser/android/browserservices/metrics:java",
     "//chrome/browser/android/browserservices/verification:java",
     "//chrome/browser/android/lifecycle:java",
     "//chrome/browser/android/webapps/launchpad:junit_tests",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 68c12c4..995825b7 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -193,7 +193,6 @@
   "java/src/org/chromium/chrome/browser/browserservices/SessionHandler.java",
   "java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java",
   "java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivitySettingsLauncher.java",
-  "java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityUmaRecorder.java",
   "java/src/org/chromium/chrome/browser/browserservices/digitalgoods/AcknowledgeConverter.java",
   "java/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsAdapter.java",
   "java/src/org/chromium/chrome/browser/browserservices/digitalgoods/DigitalGoodsConverter.java",
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
index 23d8b7e..474ee9f 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -477,6 +477,7 @@
             view = (RecyclerView) mHybridListRenderer.bind(mContentManager);
             view.setId(R.id.feed_stream_recycler_view);
             view.setClipToPadding(false);
+            view.setBackgroundColor(mActivity.getResources().getColor(R.color.default_bg_color));
         } else {
             view = null;
         }
diff --git a/chrome/android/java/res/layout/password_no_result.xml b/chrome/android/java/res/layout/password_no_result.xml
index 2d069175..0db8197 100644
--- a/chrome/android/java/res/layout/password_no_result.xml
+++ b/chrome/android/java/res/layout/password_no_result.xml
@@ -9,13 +9,14 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <FrameLayout
-        style="@style/Card"
+    <org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:layout_marginStart="16dp"
-        android:layout_marginEnd="16dp">
+        android:layout_marginEnd="16dp"
+        android:foreground="@drawable/button_borderless_compat"
+        style="@style/MaterialCardStyle">
 
         <org.chromium.ui.widget.TextViewWithLeading
             android:layout_width="match_parent"
@@ -27,6 +28,6 @@
             android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
             app:leading="@dimen/text_size_medium_leading" />
 
-    </FrameLayout>
+    </org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow>
 
 </FrameLayout>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java
index 9e4e7b1..6deef9e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java
@@ -8,6 +8,7 @@
 import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL;
 
 import org.chromium.base.StrictModeContext;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java
index 1cbaa95..1e905c1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java
@@ -13,6 +13,7 @@
 
 import org.chromium.base.Log;
 import org.chromium.chrome.browser.ChromeApplicationImpl;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.webapk.lib.common.WebApkConstants;
@@ -46,7 +47,8 @@
             finish();
             return;
         }
-        new TrustedWebActivityUmaRecorder(ChromeBrowserInitializer.getInstance())
+        new TrustedWebActivityUmaRecorder(
+                ChromeBrowserInitializer.getInstance()::runNowOrAfterFullBrowserStarted)
                 .recordOpenedSettingsViaManageSpace();
 
         if (isWebApk) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/QualityEnforcer.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/QualityEnforcer.java
index 7e0285a..9beca76 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/QualityEnforcer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/QualityEnforcer.java
@@ -19,6 +19,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.browserservices.constants.QualityEnforcementViolationType;
 import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.ui.controller.Verifier;
 import org.chromium.chrome.browser.browserservices.ui.controller.trustedwebactivity.ClientPackageNameProvider;
 import org.chromium.chrome.browser.browserservices.verification.OriginVerifierStatics;
@@ -128,7 +129,7 @@
 
     private void trigger(
             Tab tab, @QualityEnforcementViolationType int type, String url, int httpStatusCode) {
-        mUmaRecorder.recordQualityEnforcementViolation(tab, type);
+        mUmaRecorder.recordQualityEnforcementViolation(tab.getWebContents(), type);
 
         if (ChromeFeatureList.isEnabled(
                     ChromeFeatureList.TRUSTED_WEB_ACTIVITY_QUALITY_ENFORCEMENT_WARNING)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java
index 788651d8..fe72c93db 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java
@@ -4,8 +4,8 @@
 
 package org.chromium.chrome.browser.browserservices;
 
-import static org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder.DelegatedNotificationSmallIconFallback.FALLBACK_ICON_NOT_PROVIDED;
-import static org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder.DelegatedNotificationSmallIconFallback.NO_FALLBACK;
+import static org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder.DelegatedNotificationSmallIconFallback.FALLBACK_ICON_NOT_PROVIDED;
+import static org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder.DelegatedNotificationSmallIconFallback.NO_FALLBACK;
 import static org.chromium.chrome.browser.browserservices.permissiondelegation.InstalledWebappGeolocationBridge.EXTRA_NEW_LOCATION_ERROR_CALLBACK;
 
 import android.app.Notification;
@@ -37,8 +37,9 @@
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeApplicationImpl;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder.DelegatedNotificationSmallIconFallback;
 import org.chromium.chrome.browser.browserservices.constants.LocationUpdateError;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder.DelegatedNotificationSmallIconFallback;
 import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionManager;
 import org.chromium.chrome.browser.notifications.NotificationBuilderBase;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/LocationPermissionUpdater.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/LocationPermissionUpdater.java
index fe9dcda..ca92021 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/LocationPermissionUpdater.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/LocationPermissionUpdater.java
@@ -11,7 +11,7 @@
 import org.chromium.base.Log;
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.browser.browserservices.TrustedWebActivityClient;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.components.content_settings.ContentSettingsType;
 import org.chromium.components.embedder_support.util.Origin;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManager.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManager.java
index 59a2124c..9ca5f4d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManager.java
@@ -26,7 +26,7 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.chrome.browser.ChromeApplicationImpl;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.components.content_settings.ContentSettingValues;
 import org.chromium.components.content_settings.ContentSettingsType;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java
index 40a9c301..5141eef 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/sharing/TwaSharingController.java
@@ -14,11 +14,11 @@
 
 import org.chromium.base.Function;
 import org.chromium.base.Promise;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder.ShareRequestMethod;
 import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider;
 import org.chromium.chrome.browser.browserservices.intents.WebApkExtras;
 import org.chromium.chrome.browser.browserservices.intents.WebApkShareTarget;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder.ShareRequestMethod;
 import org.chromium.chrome.browser.browserservices.ui.controller.Verifier;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureController.java
index 6b459f94..ba98fc32 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureController.java
@@ -5,7 +5,7 @@
 package org.chromium.chrome.browser.browserservices.ui.controller.trustedwebactivity;
 
 import org.chromium.chrome.browser.browserservices.BrowserServicesStore;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.ui.TrustedWebActivityModel;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier;
 import org.chromium.chrome.browser.browserservices.ui.controller.DisclosureController;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorder.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorder.java
index 61e2e7f..235545eb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorder.java
@@ -7,13 +7,14 @@
 import android.os.SystemClock;
 
 import org.chromium.chrome.browser.ActivityTabProvider;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationState;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationStatus;
 import org.chromium.chrome.browser.dependency_injection.ActivityScope;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver;
+import org.chromium.chrome.browser.tab.Tab;
 
 import javax.inject.Inject;
 
@@ -70,7 +71,10 @@
         mLastStateChangeTimestampMs = SystemClock.elapsedRealtime();
 
         if (mInVerifiedOrigin && !mTwaOpenedRecorded) {
-            mRecorder.recordTwaOpened(mTabProvider.get());
+            Tab tab = mTabProvider.get();
+            if (tab != null) {
+                mRecorder.recordTwaOpened(tab.getWebContents());
+            }
             mTwaOpenedRecorded = true;
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/TrustedWebActivityCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/TrustedWebActivityCoordinator.java
index af0b8dd..8b4bb743 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/TrustedWebActivityCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/TrustedWebActivityCoordinator.java
@@ -5,8 +5,8 @@
 package org.chromium.chrome.browser.browserservices.ui.trustedwebactivity;
 
 import org.chromium.chrome.browser.browserservices.QualityEnforcer;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.ui.SharedActivityCoordinator;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationStatus;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java
index 584578a..51c2d23 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorView.java
@@ -37,9 +37,6 @@
 import org.chromium.ui.resources.AndroidResourceType;
 import org.chromium.ui.resources.ResourceManager;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * The is the {@link View} displaying the ui compositor results; including webpages and tabswitcher.
  */
@@ -75,7 +72,7 @@
 
     private View mRootView;
     private boolean mPreloadedResources;
-    private List<Runnable> mDrawingFinishedCallbacks;
+    private Runnable mDrawingFinishedCallback;
 
     // True while the compositor view is in VR Browser mode (obsolescent), or in a WebXR
     // "immersive-ar" session with DOM Overlay enabled. This disables SurfaceControl while active.
@@ -308,7 +305,7 @@
         mResourceManager = CompositorViewJni.get().getResourceManager(
                 mNativeCompositorView, CompositorView.this);
 
-        // Redraw in case there are callbacks pending |mDrawingFinishedCallbacks|.
+        // Redraw in case there are callbacks pending |mDrawingFinishedCallback|.
         CompositorViewJni.get().setNeedsComposite(mNativeCompositorView, CompositorView.this);
     }
 
@@ -385,10 +382,10 @@
 
     @Override
     public void surfaceRedrawNeededAsync(Runnable drawingFinished) {
-        if (mDrawingFinishedCallbacks == null) {
-            mDrawingFinishedCallbacks = new ArrayList<>();
-        }
-        mDrawingFinishedCallbacks.add(drawingFinished);
+        // Do not hold onto more than one draw callback, to prevent deadlock.
+        // See https://crbug.com/1174273 and https://crbug.com/1223299 for more details.
+        runDrawFinishedCallback();
+        mDrawingFinishedCallback = drawingFinished;
         if (mNativeCompositorView != 0) {
             CompositorViewJni.get().setNeedsComposite(mNativeCompositorView, CompositorView.this);
         }
@@ -517,9 +514,30 @@
             mCompositorSurfaceManager.doneWithUnownedSurface();
         }
 
-        // Only run our draw finished callbacks if the frame we swapped was the correct size.
+        // We must be careful about deferring draw callbacks, else Android can get into a bad state.
+        // However, we can still reduce some types of visible jank by deferring these carefully.
+        //
+        // In particular, a callback that is sent to us as part of WindowManager's "first draw" will
+        // defer putting buffers on the screen.  So, if we wait until we swap a correctly-sized
+        // buffer, the user won't see the previous ones.  That's generally an improvement over the
+        // clipping / guttering / stretching that would happen with the incorrectly-sized buffers.
+        //
+        // At other times, holding onto this draw callback doesn't change what's on the screen;
+        // SurfaceFlinger will still show each buffer.  What happens instead is that only WM
+        // transactions are deferred, like in the previous case, but it doesn't do us any good.
+        //
+        // Further, holding onto callbacks can prevent us from getting a surfaceCreated if the WM's
+        // transaction is blocked.  This can lead to problems when chrome is re-launched.
+        //
+        // Our strategy is as follows:
+        //
+        //  - Defer at most one draw callback.  If we get a second, immediately call back the first.
+        //  - If we are holding a draw callback when our surface is destroyed, then call it back.
+        //  - Otherwise, defer the callback until we swap the right size buffer.
+        //
+        // See https://crbug.com/1174273 and https://crbug.com/1223299 for more details.
         if (swappedCurrentSize) {
-            runDrawFinishedCallbacks();
+            runDrawFinishedCallback();
         }
 
         mRenderHost.didSwapBuffers(swappedCurrentSize);
@@ -591,16 +609,15 @@
         mCompositorSurfaceManager.setVisibility(visibility);
         // Clear out any outstanding callbacks that won't run if set to invisible.
         if (visibility == View.INVISIBLE) {
-            runDrawFinishedCallbacks();
+            runDrawFinishedCallback();
         }
     }
 
-    private void runDrawFinishedCallbacks() {
-        List<Runnable> runnables = mDrawingFinishedCallbacks;
-        mDrawingFinishedCallbacks = null;
-        if (runnables == null) return;
-        for (Runnable r : runnables) {
-            r.run();
+    private void runDrawFinishedCallback() {
+        Runnable runnable = mDrawingFinishedCallback;
+        mDrawingFinishedCallback = null;
+        if (runnable != null) {
+            runnable.run();
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java
index e20ea41..34ff0a3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java
@@ -39,7 +39,6 @@
     TrustedWebActivityPermissionManager resolveTwaPermissionManager();
     PermissionUpdater resolveTwaPermissionUpdater();
     TrustedWebActivityClient resolveTrustedWebActivityClient();
-
     ExternalAuthUtils resolveExternalAuthUtils();
 
     CustomTabsClientFileProcessor resolveCustomTabsFileProcessor();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java
index 1549505b..01461e5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java
@@ -14,6 +14,7 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.chrome.browser.WarmupManager;
 import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionStore;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor;
@@ -76,6 +77,16 @@
     }
 
     @Provides
+    public TrustedWebActivityUmaRecorder.DeferredTaskHandler provideTwaUmaRecorderTaskHandler() {
+        return new TrustedWebActivityUmaRecorder.DeferredTaskHandler() {
+            @Override
+            public void doWhenNativeLoaded(Runnable runnable) {
+                provideChromeBrowserInitializer().runNowOrAfterFullBrowserStarted(runnable);
+            }
+        };
+    }
+
+    @Provides
     @Singleton
     public TrustedWebActivityServiceConnectionPool providesTwaServiceConnectionManager(
             @Named(APP_CONTEXT) Context context) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncService.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncService.java
index 24ab0f59a..8db8688d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncService.java
@@ -13,8 +13,8 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.components.signin.base.CoreAccountInfo;
 import org.chromium.components.signin.base.GoogleServiceAuthError;
-import org.chromium.components.sync.KeyRetrievalTriggerForUMA;
 import org.chromium.components.sync.PassphraseType;
+import org.chromium.components.sync.TrustedVaultUserActionTriggerForUMA;
 
 import java.util.Date;
 import java.util.Set;
@@ -307,7 +307,7 @@
      * Records TrustedVaultKeyRetrievalTrigger histogram.
      */
     public abstract void recordKeyRetrievalTrigger(
-            @KeyRetrievalTriggerForUMA int keyRetrievalTrigger);
+            @TrustedVaultUserActionTriggerForUMA int keyRetrievalTrigger);
 
     /** @return Whether the user should be offered to opt in to trusted vault encryption. */
     public abstract boolean shouldOfferTrustedVaultOptIn();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncServiceImpl.java
index 788cbdc5..b582337 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncServiceImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncServiceImpl.java
@@ -16,9 +16,9 @@
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.components.signin.base.CoreAccountInfo;
 import org.chromium.components.signin.base.GoogleServiceAuthError;
-import org.chromium.components.sync.KeyRetrievalTriggerForUMA;
 import org.chromium.components.sync.ModelType;
 import org.chromium.components.sync.PassphraseType;
+import org.chromium.components.sync.TrustedVaultUserActionTriggerForUMA;
 
 import java.util.Date;
 import java.util.HashSet;
@@ -333,7 +333,8 @@
     }
 
     @Override
-    public void recordKeyRetrievalTrigger(@KeyRetrievalTriggerForUMA int keyRetrievalTrigger) {
+    public void recordKeyRetrievalTrigger(
+            @TrustedVaultUserActionTriggerForUMA int keyRetrievalTrigger) {
         SyncServiceImplJni.get().recordKeyRetrievalTrigger(
                 mSyncServiceAndroidBridge, keyRetrievalTrigger);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java
index f7a10994..3175aee 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java
@@ -36,8 +36,8 @@
 import org.chromium.chrome.browser.sync.TrustedVaultClient;
 import org.chromium.components.signin.base.CoreAccountInfo;
 import org.chromium.components.signin.base.GoogleServiceAuthError;
-import org.chromium.components.sync.KeyRetrievalTriggerForUMA;
 import org.chromium.components.sync.StopSource;
+import org.chromium.components.sync.TrustedVaultUserActionTriggerForUMA;
 import org.chromium.ui.widget.Toast;
 
 import java.lang.annotation.Retention;
@@ -440,7 +440,7 @@
      */
     public static void openTrustedVaultKeyRetrievalDialog(
             Fragment fragment, CoreAccountInfo accountInfo, int requestCode) {
-        SyncService.get().recordKeyRetrievalTrigger(KeyRetrievalTriggerForUMA.SETTINGS);
+        SyncService.get().recordKeyRetrievalTrigger(TrustedVaultUserActionTriggerForUMA.SETTINGS);
         openTrustedVaultDialogForPendingIntent(fragment, accountInfo, requestCode,
                 TrustedVaultClient.get().createKeyRetrievalIntent(accountInfo));
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/TrustedVaultKeyRetrievalProxyActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/TrustedVaultKeyRetrievalProxyActivity.java
index f23f3d06..bee9e7d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/TrustedVaultKeyRetrievalProxyActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/TrustedVaultKeyRetrievalProxyActivity.java
@@ -13,7 +13,7 @@
 import org.chromium.chrome.browser.init.AsyncInitializationActivity;
 import org.chromium.chrome.browser.sync.SyncService;
 import org.chromium.chrome.browser.sync.TrustedVaultClient;
-import org.chromium.components.sync.KeyRetrievalTriggerForUMA;
+import org.chromium.components.sync.TrustedVaultUserActionTriggerForUMA;
 
 /**
  * {@link TrustedVaultKeyRetrievalProxyActivity} has no own UI and just launches real key retrieval
@@ -73,7 +73,8 @@
         super.finishNativeInitialization();
         // Activity might be restored and this shouldn't cause recording the histogram second time.
         if (getSavedInstanceState() == null) {
-            SyncService.get().recordKeyRetrievalTrigger(KeyRetrievalTriggerForUMA.NOTIFICATION);
+            SyncService.get().recordKeyRetrievalTrigger(
+                    TrustedVaultUserActionTriggerForUMA.NOTIFICATION);
         }
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/metrics/TabbedActivityLaunchCauseMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/metrics/TabbedActivityLaunchCauseMetricsTest.java
index 8e94580f..00c98e40 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/metrics/TabbedActivityLaunchCauseMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/metrics/TabbedActivityLaunchCauseMetricsTest.java
@@ -44,6 +44,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.FlakyTest;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
@@ -238,6 +239,7 @@
 
     @Test
     @MediumTest
+    @FlakyTest(message = "https://crbug.com/1224738")
     public void testServiceWorkerTabLaunch() throws Throwable {
         final int count = 1 + histogramCountForValue(LaunchCauseMetrics.LaunchCause.NOTIFICATION);
         mJniMocker.mock(ServiceTabLauncherJni.TEST_HOOKS, mServiceTabLauncherJni);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
index ee73306..296982c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/MainIntentBehaviorMetricsIntegrationTest.java
@@ -68,7 +68,6 @@
     }
 
     @MediumTest
-    @DisabledTest(message = "crbug.com/1225878")
     @Test
     public void testBackgroundDuration_24hrs() {
         assertBackgroundDurationLogged(
@@ -76,7 +75,6 @@
     }
 
     @MediumTest
-    @DisabledTest(message = "crbug.com/1225878")
     @Test
     public void testBackgroundDuration_12hrs() {
         assertBackgroundDurationLogged(
@@ -84,7 +82,6 @@
     }
 
     @MediumTest
-    @DisabledTest(message = "crbug.com/1225878")
     @Test
     public void testBackgroundDuration_6hrs() {
         assertBackgroundDurationLogged(
@@ -92,14 +89,12 @@
     }
 
     @MediumTest
-    @DisabledTest(message = "crbug.com/1225878")
     @Test
     public void testBackgroundDuration_1hr() {
         assertBackgroundDurationLogged(HOURS_IN_MS, "MobileStartup.MainIntentReceived.After1Hour");
     }
 
     @MediumTest
-    @DisabledTest(message = "crbug.com/1225878")
     @Test
     public void testBackgroundDuration_0hr() {
         assertBackgroundDurationLogged(0, null);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorderTest.java
index a57d25a5..ff01edfc 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorderTest.java
@@ -25,6 +25,7 @@
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/QualityEnforcerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/QualityEnforcerUnitTest.java
index 9575fa5..b1fa5e7a 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/QualityEnforcerUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/QualityEnforcerUnitTest.java
@@ -33,6 +33,7 @@
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.app.ChromeActivity;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.ui.controller.Verifier;
 import org.chromium.chrome.browser.browserservices.ui.controller.trustedwebactivity.ClientPackageNameProvider;
 import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java
index 732f1b04..6932bc3 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java
@@ -34,6 +34,7 @@
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionManager;
 import org.chromium.chrome.browser.notifications.NotificationBuilderBase;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/permissiondelegation/LocationPermissionUpdaterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/permissiondelegation/LocationPermissionUpdaterTest.java
index b225066..185f4c4 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/permissiondelegation/LocationPermissionUpdaterTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/permissiondelegation/LocationPermissionUpdaterTest.java
@@ -31,7 +31,7 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.browserservices.TrustedWebActivityClient;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManagerTest.java
index e5f8f5d4..04eeecf 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManagerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManagerTest.java
@@ -38,7 +38,7 @@
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.components.content_settings.ContentSettingValues;
 import org.chromium.components.content_settings.ContentSettingsType;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureControllerTest.java
index 83a10c15..54633e9 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureControllerTest.java
@@ -32,7 +32,7 @@
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.browserservices.BrowserServicesStore;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.ui.TrustedWebActivityModel;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationState;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorderTest.java
index d0261ab..32777fd 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorderTest.java
@@ -8,6 +8,7 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -24,11 +25,13 @@
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.browser.ActivityTabProvider;
-import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder;
+import org.chromium.chrome.browser.browserservices.metrics.TrustedWebActivityUmaRecorder;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationState;
 import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationStatus;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.content_public.browser.WebContents;
 
 import java.util.concurrent.TimeUnit;
 
@@ -59,6 +62,11 @@
                 .addVerificationObserver(mVerificationObserverCaptor.capture());
         mRecorder = new TrustedWebActivityOpenTimeRecorder(
                 mLifecycleDispatcher, mCurrentPageVerifier, mUmaRecorder, mTabProvider);
+
+        Tab tab = mock(Tab.class);
+        WebContents webContents = mock(WebContents.class);
+        when(mTabProvider.get()).thenReturn(tab);
+        when(tab.getWebContents()).thenReturn(webContents);
     }
 
     @Test
diff --git a/chrome/app/bookmarks_strings.grdp b/chrome/app/bookmarks_strings.grdp
index 85a5cc2..68a270c 100644
--- a/chrome/app/bookmarks_strings.grdp
+++ b/chrome/app/bookmarks_strings.grdp
@@ -379,6 +379,12 @@
   <message name="IDS_BOOKMARK_MANAGER_MENU_IMPORT" desc="Title of the bookmark toolbar dropdown menu item that imports bookmarks.">
     Import bookmarks
   </message>
+  <message name="IDS_BOOKMARK_MANAGER_MENU_IMPORT_BEGAN" desc="Accessibility text for after the user selects bookmarks to import.">
+    Importing bookmarks...
+  </message>
+  <message name="IDS_BOOKMARK_MANAGER_MENU_IMPORT_ENDED" desc="Accessibility text for after the bookmarks manager has finished importing bookmarks.">
+    Bookmarks imported.
+  </message>
   <message name="IDS_BOOKMARK_MANAGER_MENU_OPEN_ALL" desc="Menu title for opening all urls in a bookmark folder">
     Open all
   </message>
diff --git a/chrome/app/bookmarks_strings_grdp/IDS_BOOKMARK_MANAGER_MENU_IMPORT_BEGAN.png.sha1 b/chrome/app/bookmarks_strings_grdp/IDS_BOOKMARK_MANAGER_MENU_IMPORT_BEGAN.png.sha1
new file mode 100644
index 0000000..51ade46
--- /dev/null
+++ b/chrome/app/bookmarks_strings_grdp/IDS_BOOKMARK_MANAGER_MENU_IMPORT_BEGAN.png.sha1
@@ -0,0 +1 @@
+3f8d2c5d1ec040e1686406b786b4b7eb6a087c5f
\ No newline at end of file
diff --git a/chrome/app/bookmarks_strings_grdp/IDS_BOOKMARK_MANAGER_MENU_IMPORT_ENDED.png.sha1 b/chrome/app/bookmarks_strings_grdp/IDS_BOOKMARK_MANAGER_MENU_IMPORT_ENDED.png.sha1
new file mode 100644
index 0000000..6ff225f3
--- /dev/null
+++ b/chrome/app/bookmarks_strings_grdp/IDS_BOOKMARK_MANAGER_MENU_IMPORT_ENDED.png.sha1
@@ -0,0 +1 @@
+e2591ce566d2273329af430e00d2a2c91a117cea
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 36b55b9..5c9fd16 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -4595,12 +4595,21 @@
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_TITLE" desc="The title of the dialog that allow users to register their fingerprint.">
     Unlock faster with your fingerprint
   </message>
+  <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_TITLE_CHILD" desc="The title of the dialog that allow users to register their fingerprint, when a child account is in use.">
+    Unlock faster with fingerprint
+  </message>
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION" desc="The label that explains that the fingerprint sensor is in the power button.">
     Touch the power button with your finger. Your data is stored securely and never leaves your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>.
   </message>
+  <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION_CHILD" desc="The label that explains that the fingerprint sensor is in the power button, when a child account is in use.">
+    To set up fingerprint, have your child touch the power button. Your child’s fingerprint data is stored securely and never leaves this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>.
+  </message>
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION" desc="The label that explains the location of the fingerprint sensor on the device.">
     Touch the fingerprint sensor with your finger. Your data is stored securely and never leaves your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>.
   </message>
+  <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD" desc="The label that explains the location of the fingerprint sensor on the device, when a child account is in use.">
+    To set up fingerprint, have your child touch the fingerprint sensor. Your child’s fingerprint data is stored securely and never leaves this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>.
+  </message>
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_PROGRESS_TITLE" desc="The title of the dialog that shows where the fingerprint sensor is.">
     Lift, then touch again
   </message>
@@ -4610,6 +4619,9 @@
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_SUCCESS_DESCRIPTION" desc="The label that shows when fingerprint enrollment is successful.">
     When you see this icon, use your fingerprint for identification or to approve purchases.
   </message>
+  <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_SUCCESS_DESCRIPTION_CHILD" desc="The label that shows when fingerprint enrollment is successful, when a child account is in use.">
+    When your child sees this icon, a fingerprint can be used for identification or to approve purchases.
+  </message>
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_BUTTON_SKIP" desc="In fingerprint setup screen, button label to skip the fingerprint setup.">
     Skip
   </message>
@@ -4631,6 +4643,9 @@
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_MOVE_FINGER" desc="Text in the fingerprint setup screen telling users to lift their finger to capture the different parts of fingerprint.">
     Keep lifting your finger to add the different parts of your fingerprint
   </message>
+  <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_MOVE_FINGER_CHILD" desc="Text in the fingerprint setup screen telling users to lift their finger to capture the different parts of fingerprint, when a child account is in use.">
+    Have your child keep lifting their finger to save the fingerprint
+  </message>
   <message name="IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_TRY_AGAIN" desc="Text in the fingerprint setup screen telling users to scan their finger again.">
     Try again.
   </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_SUCCESS_DESCRIPTION_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_SUCCESS_DESCRIPTION_CHILD.png.sha1
new file mode 100644
index 0000000..3788971
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_SUCCESS_DESCRIPTION_CHILD.png.sha1
@@ -0,0 +1 @@
+25206a0de3d976ac44bce4d5bd65f28ece0def53
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_MOVE_FINGER_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_MOVE_FINGER_CHILD.png.sha1
new file mode 100644
index 0000000..8b0f8e5
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_MOVE_FINGER_CHILD.png.sha1
@@ -0,0 +1 @@
+0cb5da1c6391e83c8eced5aa4b666de7678c48f2
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD.png.sha1
new file mode 100644
index 0000000..43d91795
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD.png.sha1
@@ -0,0 +1 @@
+8c35f8504f026b6218110c4e497c1b0919504aa6
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION_CHILD.png.sha1
new file mode 100644
index 0000000..baa72d1
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION_CHILD.png.sha1
@@ -0,0 +1 @@
+5464f91fa463084fbd2c0cc0ecbb2b44fb23d1e1
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_TITLE_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_TITLE_CHILD.png.sha1
new file mode 100644
index 0000000..43d91795
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_OOBE_FINGERPINT_SETUP_SCREEN_TITLE_CHILD.png.sha1
@@ -0,0 +1 @@
+8c35f8504f026b6218110c4e497c1b0919504aa6
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 5c72821..76970d08 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4225,6 +4225,9 @@
     {"files-archivemount", flag_descriptions::kFilesArchivemountName,
      flag_descriptions::kFilesArchivemountDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kFilesArchivemount)},
+    {"files-banner-framework", flag_descriptions::kFilesBannerFrameworkName,
+     flag_descriptions::kFilesBannerFrameworkDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(chromeos::features::kFilesBannerFramework)},
     {"files-filters-in-recents", flag_descriptions::kFiltersInRecentsName,
      flag_descriptions::kFiltersInRecentsDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kFiltersInRecents)},
diff --git a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
index 58269018..23b069c 100644
--- a/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
+++ b/chrome/browser/accessibility/accessibility_extension_api_chromeos.cc
@@ -618,6 +618,10 @@
       enabled = ::features::IsSelectToSpeakNavigationControlEnabled();
       break;
     case accessibility_private::AccessibilityFeature::
+        ACCESSIBILITY_FEATURE_ENHANCEDNETWORKVOICES:
+      enabled = ::features::IsEnhancedNetworkVoicesEnabled();
+      break;
+    case accessibility_private::AccessibilityFeature::
         ACCESSIBILITY_FEATURE_NONE:
       return RespondNow(Error("Unrecognized feature"));
   }
diff --git a/chrome/browser/android/browserservices/metrics/BUILD.gn b/chrome/browser/android/browserservices/metrics/BUILD.gn
index 1400bbb7..95bb796c 100644
--- a/chrome/browser/android/browserservices/metrics/BUILD.gn
+++ b/chrome/browser/android/browserservices/metrics/BUILD.gn
@@ -8,6 +8,7 @@
   sources = [
     "java/src/org/chromium/chrome/browser/browserservices/metrics/BrowserServicesTimingMetrics.java",
     "java/src/org/chromium/chrome/browser/browserservices/metrics/OriginVerifierMetricsRecorder.java",
+    "java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java",
     "java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUkmRecorder.java",
     "java/src/org/chromium/chrome/browser/browserservices/metrics/WebApkUmaRecorder.java",
   ]
@@ -15,6 +16,11 @@
     "//base:base_java",
     "//chrome/browser/android/browserservices/constants:java",
     "//components/browser_ui/util/android:java",
+    "//components/content_settings/android:content_settings_enums_java",
+    "//components/ukm/android:java",
+    "//content/public/android:content_java",
+    "//third_party/android_deps:dagger_java",
+    "//third_party/android_deps:javax_inject_javax_inject_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
   ]
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
diff --git a/chrome/browser/android/browserservices/metrics/DEPS b/chrome/browser/android/browserservices/metrics/DEPS
new file mode 100644
index 0000000..838459a9
--- /dev/null
+++ b/chrome/browser/android/browserservices/metrics/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+content/public/android/java/src/org/chromium/content_public",
+]
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityUmaRecorder.java b/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java
similarity index 83%
rename from chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityUmaRecorder.java
rename to chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java
index 56672f5..45ddd164 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityUmaRecorder.java
+++ b/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.browserservices;
+package org.chromium.chrome.browser.browserservices.metrics;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
@@ -13,10 +13,9 @@
 import org.chromium.base.task.TaskTraits;
 import org.chromium.chrome.browser.browserservices.constants.LocationUpdateError;
 import org.chromium.chrome.browser.browserservices.constants.QualityEnforcementViolationType;
-import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
-import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.components.content_settings.ContentSettingsType;
 import org.chromium.components.ukm.UkmRecorder;
+import org.chromium.content_public.browser.WebContents;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -62,21 +61,29 @@
         int NUM_ENTRIES = 4;
     }
 
-    private final ChromeBrowserInitializer mBrowserInitializer;
+    /**
+     * A callback for adding task to run when full browser initialization is done.
+     */
+    public interface DeferredTaskHandler {
+        /* Call to add task to run after full browser started.*/
+        void doWhenNativeLoaded(Runnable runnable);
+    }
+
+    private final DeferredTaskHandler mDeferredTaskHandler;
 
     @Inject
-    public TrustedWebActivityUmaRecorder(ChromeBrowserInitializer browserInitializer) {
-        mBrowserInitializer = browserInitializer;
+    public TrustedWebActivityUmaRecorder(DeferredTaskHandler taskHandler) {
+        mDeferredTaskHandler = taskHandler;
     }
 
     /**
      * Records that a Trusted Web Activity has been opened.
      */
-    public void recordTwaOpened(@Nullable Tab tab) {
+    public void recordTwaOpened(@Nullable WebContents webContents) {
         RecordUserAction.record("BrowserServices.TwaOpened");
-        if (tab != null) {
+        if (webContents != null) {
             new UkmRecorder.Bridge().recordEventWithBooleanMetric(
-                    tab.getWebContents(), "TrustedWebActivity.Open", "HasOccurred");
+                    webContents, "TrustedWebActivity.Open", "HasOccurred");
         }
     }
 
@@ -139,8 +146,8 @@
      * settings.
      */
     public void recordOpenedSettingsViaManageSpace() {
-        doWhenNativeLoaded(() ->
-            RecordUserAction.record("TrustedWebActivity.OpenedSettingsViaManageSpace"));
+        mDeferredTaskHandler.doWhenNativeLoaded(
+                () -> RecordUserAction.record("TrustedWebActivity.OpenedSettingsViaManageSpace"));
     }
 
     /**
@@ -158,23 +165,21 @@
      * Uses {@link TaskTraits#BEST_EFFORT} in order to not get in the way of loading the page.
      */
     public void recordSplashScreenUsage(boolean wasShown) {
-        doWhenNativeLoaded(() ->
+        // clang-format off
+        mDeferredTaskHandler.doWhenNativeLoaded(() ->
                 PostTask.postTask(TaskTraits.BEST_EFFORT, () ->
                         RecordHistogram.recordBooleanHistogram(
                                 "TrustedWebActivity.SplashScreenShown", wasShown)
                 ));
+        // clang-format on
     }
 
     /**
      * Records the fact that data was shared via a TWA.
      */
     public void recordShareTargetRequest(@ShareRequestMethod int method) {
-        RecordHistogram.recordEnumeratedHistogram("TrustedWebActivity.ShareTargetRequest",
-                method, ShareRequestMethod.NUM_ENTRIES);
-    }
-
-    private void doWhenNativeLoaded(Runnable runnable) {
-        mBrowserInitializer.runNowOrAfterFullBrowserStarted(runnable);
+        RecordHistogram.recordEnumeratedHistogram(
+                "TrustedWebActivity.ShareTargetRequest", method, ShareRequestMethod.NUM_ENTRIES);
     }
 
     public void recordLocationDelegationEnrolled(boolean enrolled) {
@@ -217,14 +222,16 @@
     }
 
     public void recordQualityEnforcementViolation(
-            Tab tab, @QualityEnforcementViolationType int type) {
+            WebContents webContents, @QualityEnforcementViolationType int type) {
         RecordHistogram.recordEnumeratedHistogram("TrustedWebActivity.QualityEnforcementViolation",
                 type, QualityEnforcementViolationType.MAX_VALUE + 1);
 
-        new UkmRecorder.Bridge().recordEventWithIntegerMetric(tab.getWebContents(),
-                /* eventName = */ "TrustedWebActivity.QualityEnforcementViolation",
-                /* metricName = */ "ViolationType",
-                /* metricValue = */ type);
+        if (webContents != null) {
+            new UkmRecorder.Bridge().recordEventWithIntegerMetric(webContents,
+                    /* eventName = */ "TrustedWebActivity.QualityEnforcementViolation",
+                    /* metricName = */ "ViolationType",
+                    /* metricValue = */ type);
+        }
     }
 
     public void recordQualityEnforcementViolationCrashed(
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc
index 2087c17..d29d111 100644
--- a/chrome/browser/android/tab_web_contents_delegate_android.cc
+++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -37,7 +37,6 @@
 #include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
 #include "chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
@@ -66,6 +65,7 @@
 #include "components/navigation_interception/intercept_navigation_delegate.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
 #include "components/paint_preview/buildflags/buildflags.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
 #include "components/security_state/content/content_utils.h"
 #include "content/public/browser/file_select_listener.h"
 #include "content/public/browser/navigation_entry.h"
diff --git a/chrome/browser/apps/app_service/app_icon_factory.cc b/chrome/browser/apps/app_service/app_icon_factory.cc
index 7984163..164ea49 100644
--- a/chrome/browser/apps/app_service/app_icon_factory.cc
+++ b/chrome/browser/apps/app_service/app_icon_factory.cc
@@ -28,8 +28,8 @@
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "components/favicon/core/favicon_service.h"
diff --git a/chrome/browser/apps/app_service/app_icon_factory.h b/chrome/browser/apps/app_service/app_icon_factory.h
index 43b70b54..b039cfc9 100644
--- a/chrome/browser/apps/app_service/app_icon_factory.h
+++ b/chrome/browser/apps/app_service/app_icon_factory.h
@@ -12,7 +12,7 @@
 #include "base/callback_forward.h"
 #include "base/files/file_path.h"
 #include "build/chromeos_buildflags.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/services/app_service/public/mojom/app_service.mojom.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "ui/gfx/image/image_skia.h"
diff --git a/chrome/browser/apps/app_service/launch_utils.cc b/chrome/browser/apps/app_service/launch_utils.cc
index 8d73455..0aa0d65 100644
--- a/chrome/browser/apps/app_service/launch_utils.cc
+++ b/chrome/browser/apps/app_service/launch_utils.cc
@@ -14,9 +14,9 @@
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/webui_url_constants.h"
@@ -58,8 +58,8 @@
     DCHECK(extension->is_app());
     return true;
   }
-  web_app::AppRegistrar& registrar =
-      web_app::WebAppProviderBase::GetProviderBase(profile)->registrar();
+  web_app::WebAppRegistrar& registrar =
+      web_app::WebAppProvider::GetForWebApps(profile)->registrar();
   return registrar.IsInstalled(app_id);
 }
 
@@ -81,8 +81,8 @@
     extensions::TabHelper::FromWebContents(web_contents)
         ->SetExtensionAppById(app_id);
   } else {
-    web_app::AppRegistrar& registrar =
-        web_app::WebAppProviderBase::GetProviderBase(profile)->registrar();
+    web_app::WebAppRegistrar& registrar =
+        web_app::WebAppProvider::GetForWebApps(profile)->registrar();
     web_app::WebAppTabHelper::FromWebContents(web_contents)
         ->SetAppId(registrar.IsInstalled(app_id) ? app_id : std::string());
     extensions::TabHelper::FromWebContents(web_contents)
diff --git a/chrome/browser/apps/app_service/webapk/webapk_install_task.cc b/chrome/browser/apps/app_service/webapk/webapk_install_task.cc
index 29fcc45..8cd6d87 100644
--- a/chrome/browser/apps/app_service/webapk/webapk_install_task.cc
+++ b/chrome/browser/apps/app_service/webapk/webapk_install_task.cc
@@ -19,9 +19,9 @@
 #include "chrome/browser/apps/app_service/webapk/webapk_prefs.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/mojom/webapk.mojom.h"
@@ -234,7 +234,7 @@
 WebApkInstallTask::WebApkInstallTask(Profile* profile,
                                      const std::string& app_id)
     : profile_(profile),
-      web_app_provider_(web_app::WebAppProviderBase::GetProviderBase(profile_)),
+      web_app_provider_(web_app::WebAppProvider::GetForWebApps(profile_)),
       app_id_(app_id),
       package_name_to_update_(
           webapk_prefs::GetWebApkPackageName(profile_, app_id_)),
diff --git a/chrome/browser/apps/app_service/webapk/webapk_install_task.h b/chrome/browser/apps/app_service/webapk/webapk_install_task.h
index f9482ac..c3e0644 100644
--- a/chrome/browser/apps/app_service/webapk/webapk_install_task.h
+++ b/chrome/browser/apps/app_service/webapk/webapk_install_task.h
@@ -30,7 +30,7 @@
 }
 
 namespace web_app {
-class WebAppProviderBase;
+class WebAppProvider;
 }
 
 namespace apps {
@@ -73,7 +73,7 @@
   void DeliverResult(WebApkInstallStatus status);
 
   Profile* const profile_;
-  web_app::WebAppProviderBase* web_app_provider_;
+  web_app::WebAppProvider* web_app_provider_;
 
   arc::mojom::WebApkInfoPtr web_apk_info_;
   const std::string app_id_;
diff --git a/chrome/browser/apps/app_service/webapk/webapk_manager.cc b/chrome/browser/apps/app_service/webapk/webapk_manager.cc
index 6f7cf59..1bf5905 100644
--- a/chrome/browser/apps/app_service/webapk/webapk_manager.cc
+++ b/chrome/browser/apps/app_service/webapk/webapk_manager.cc
@@ -13,8 +13,8 @@
 #include "chrome/browser/apps/app_service/webapk/webapk_prefs.h"
 #include "chrome/browser/ash/apps/apk_web_app_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/arc/mojom/app.mojom.h"
 #include "components/arc/session/connection_holder.h"
 #include "components/services/app_service/public/mojom/types.mojom-shared.h"
@@ -29,7 +29,7 @@
 WebApkManager::WebApkManager(Profile* profile)
     : profile_(profile),
       web_app_registrar_(
-          web_app::WebAppProviderBase::GetProviderBase(profile)->registrar()),
+          web_app::WebAppProvider::GetForWebApps(profile)->registrar()),
       initialized_(false) {
   proxy_ = AppServiceProxyFactory::GetForProfile(profile);
   apk_service_ = ash::ApkWebAppService::Get(profile_);
diff --git a/chrome/browser/apps/app_service/webapk/webapk_manager.h b/chrome/browser/apps/app_service/webapk/webapk_manager.h
index 0eb92f3..98c4a7d 100644
--- a/chrome/browser/apps/app_service/webapk/webapk_manager.h
+++ b/chrome/browser/apps/app_service/webapk/webapk_manager.h
@@ -10,7 +10,7 @@
 
 #include "base/scoped_observation.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/arc/mojom/intent_helper.mojom-forward.h"
 #include "components/services/app_service/public/cpp/app_registry_cache.h"
 
@@ -57,7 +57,7 @@
   AppServiceProxyBase* proxy_;
   ash::ApkWebAppService* apk_service_;
   ArcAppListPrefs* app_list_prefs_;
-  web_app::AppRegistrar& web_app_registrar_;
+  web_app::WebAppRegistrar& web_app_registrar_;
 
   bool initialized_;
 
diff --git a/chrome/browser/apps/digital_goods/util.cc b/chrome/browser/apps/digital_goods/util.cc
index 6d8c169..bdc2fe6 100644
--- a/chrome/browser/apps/digital_goods/util.cc
+++ b/chrome/browser/apps/digital_goods/util.cc
@@ -8,8 +8,8 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "content/public/browser/render_document_host_user_data.h"
 #include "content/public/browser/web_contents.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -47,7 +47,7 @@
 }
 
 std::string GetScope(content::RenderFrameHost* render_frame_host) {
-  web_app::AppRegistrar& registrar =
+  web_app::WebAppRegistrar& registrar =
       web_app::WebAppProvider::Get(
           Profile::FromBrowserContext(render_frame_host->GetBrowserContext()))
           ->registrar();
diff --git a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
index efb6bd096..5f4611b 100644
--- a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
+++ b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
@@ -18,10 +18,9 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/common/chrome_features.h"
@@ -167,8 +166,8 @@
 
   Profile* const profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
-  web_app::WebAppProviderBase* provider =
-      web_app::WebAppProviderBase::GetProviderBase(profile);
+  web_app::WebAppProvider* provider =
+      web_app::WebAppProvider::GetForWebApps(profile);
   if (!provider)
     return absl::nullopt;
 
diff --git a/chrome/browser/apps/intent_helper/intent_picker_internal.cc b/chrome/browser/apps/intent_helper/intent_picker_internal.cc
index c72c1db8..47e960a 100644
--- a/chrome/browser/apps/intent_helper/intent_picker_internal.cc
+++ b/chrome/browser/apps/intent_helper/intent_picker_internal.cc
@@ -13,9 +13,9 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/intent_picker_tab_helper.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_contents.h"
 #include "components/page_load_metrics/browser/page_load_metrics_util.h"
 #include "content/public/browser/navigation_handle.h"
@@ -75,7 +75,7 @@
   if (!app_id)
     return apps;
 
-  auto* const provider = web_app::WebAppProviderBase::GetProviderBase(profile);
+  auto* const provider = web_app::WebAppProvider::GetForWebApps(profile);
   if (provider->registrar().GetAppUserDisplayMode(*app_id) ==
       web_app::DisplayMode::kBrowser) {
     return apps;
diff --git a/chrome/browser/ash/apps/apk_web_app_installer_browsertest.cc b/chrome/browser/ash/apps/apk_web_app_installer_browsertest.cc
index d1a60a705..ce219ef 100644
--- a/chrome/browser/ash/apps/apk_web_app_installer_browsertest.cc
+++ b/chrome/browser/ash/apps/apk_web_app_installer_browsertest.cc
@@ -22,11 +22,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/arc/test/arc_util_test_support.h"
 #include "components/arc/test/connection_holder_util.h"
 #include "components/arc/test/fake_app_instance.h"
@@ -171,7 +171,8 @@
   }
 
  protected:
-  base::ScopedObservation<web_app::AppRegistrar, web_app::AppRegistrarObserver>
+  base::ScopedObservation<web_app::WebAppRegistrar,
+                          web_app::AppRegistrarObserver>
       observation_{this};
   ArcAppListPrefs* arc_app_list_prefs_ = nullptr;
   web_app::WebAppProvider* provider_ = nullptr;
diff --git a/chrome/browser/ash/apps/apk_web_app_service.cc b/chrome/browser/ash/apps/apk_web_app_service.cc
index 8184d4f..8e1e47c 100644
--- a/chrome/browser/ash/apps/apk_web_app_service.cc
+++ b/chrome/browser/ash/apps/apk_web_app_service.cc
@@ -13,13 +13,13 @@
 #include "chrome/browser/ash/apps/apk_web_app_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "components/arc/mojom/app.mojom.h"
 #include "components/arc/session/connection_holder.h"
@@ -129,7 +129,7 @@
 
 absl::optional<std::string> ApkWebAppService::GetPackageNameForWebApp(
     const GURL& url) {
-  web_app::AppRegistrar& registrar =
+  web_app::WebAppRegistrar& registrar =
       web_app::WebAppProvider::Get(profile_)->registrar();
   absl::optional<web_app::AppId> app_id = registrar.FindAppWithUrlInScope(url);
   if (!app_id)
diff --git a/chrome/browser/ash/apps/apk_web_app_service.h b/chrome/browser/ash/apps/apk_web_app_service.h
index 0b1b590..302b253 100644
--- a/chrome/browser/ash/apps/apk_web_app_service.h
+++ b/chrome/browser/ash/apps/apk_web_app_service.h
@@ -15,9 +15,9 @@
 #include "base/scoped_observation.h"
 #include "chrome/browser/ash/apps/apk_web_app_installer.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 class ArcAppListPrefs;
@@ -112,7 +112,8 @@
   ArcAppListPrefs* arc_app_list_prefs_;
   web_app::WebAppProvider* provider_;
 
-  base::ScopedObservation<web_app::AppRegistrar, web_app::AppRegistrarObserver>
+  base::ScopedObservation<web_app::WebAppRegistrar,
+                          web_app::AppRegistrarObserver>
       registrar_observer_{this};
 
   base::ScopedObservation<ArcAppListPrefs, ArcAppListPrefs::Observer>
diff --git a/chrome/browser/ash/arc/accessibility/accessibility_info_data_wrapper.cc b/chrome/browser/ash/arc/accessibility/accessibility_info_data_wrapper.cc
index 27aef004..e97b72c 100644
--- a/chrome/browser/ash/arc/accessibility/accessibility_info_data_wrapper.cc
+++ b/chrome/browser/ash/arc/accessibility/accessibility_info_data_wrapper.cc
@@ -8,6 +8,8 @@
 #include "chrome/browser/ash/arc/accessibility/geometry_util.h"
 #include "components/exo/wm_helper.h"
 #include "ui/compositor/layer.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
@@ -29,7 +31,7 @@
   aura::Window* window = tree_source_->GetWindow();
   AccessibilityInfoDataWrapper* root = tree_source_->GetRoot();
   gfx::Rect info_data_bounds = GetBounds();
-  gfx::RectF& out_bounds = out_data->relative_bounds.bounds;
+  gfx::RectF& out_bounds_px = out_data->relative_bounds.bounds;
 
   if (window && root && exo::WMHelper::HasInstance()) {
     if (tree_source_->is_notification() ||
@@ -38,7 +40,7 @@
       const gfx::Rect& root_bounds = root->GetBounds();
       info_data_bounds.Offset(-1 * root_bounds.x(), -1 * root_bounds.y());
 
-      out_bounds = ScaleAndroidPxToChromePx(info_data_bounds, window);
+      out_bounds_px = ScaleAndroidPxToChromePx(info_data_bounds, window);
       out_data->relative_bounds.offset_container_id = root->GetId();
     } else {
       // For the root node of application tree, populate the bounds to be
@@ -52,6 +54,14 @@
                                                 ->GetBoundsInScreen()
                                                 .origin());
 
+      // Android sends bounds in display coordinate.
+      // Make window bounds relative to display so that we can compute the
+      // actual offset of a11y window bounds from ash window.
+      // TODO(hirokisato): Android pi sends different coordinate.
+      const display::Display display =
+          display::Screen::GetScreen()->GetDisplayNearestView(window);
+      root_origin.Offset(-display.bounds().x(), -display.bounds().y());
+
       // Adjust the origin because a maximized window has an offset in Android.
       root_origin.Offset(0, -1 * GetChromeWindowHeightOffsetInDip(window));
 
@@ -59,13 +69,13 @@
       root_origin.Scale(
           window->GetToplevelWindow()->layer()->device_scale_factor());
 
-      out_bounds = ScaleAndroidPxToChromePx(info_data_bounds, window);
-      out_bounds.Offset(-1 * root_origin.x(), -1 * root_origin.y());
+      out_bounds_px = ScaleAndroidPxToChromePx(info_data_bounds, window);
+      out_bounds_px.Offset(-1 * root_origin.x(), -1 * root_origin.y());
     }
   } else {
     // We cannot compute global bounds, so use the raw bounds.
-    out_bounds.SetRect(info_data_bounds.x(), info_data_bounds.y(),
-                       info_data_bounds.width(), info_data_bounds.height());
+    out_bounds_px.SetRect(info_data_bounds.x(), info_data_bounds.y(),
+                          info_data_bounds.width(), info_data_bounds.height());
   }
 }
 
diff --git a/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.cc
index 1a65865..85c45a1 100644
--- a/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.cc
+++ b/chrome/browser/ash/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -36,6 +36,8 @@
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/window.h"
 #include "ui/compositor/layer.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/views/controls/native/native_view_host.h"
@@ -100,6 +102,10 @@
   bounds_in_screen.Offset(0,
                           arc::GetChromeWindowHeightOffsetInDip(active_window));
 
+  const display::Display display =
+      display::Screen::GetScreen()->GetDisplayNearestView(active_window);
+  bounds_in_screen.Offset(display.bounds().x(), display.bounds().y());
+
   bool is_editable = arc::GetBooleanProperty(
       node_data, arc::mojom::AccessibilityBooleanProperty::EDITABLE);
 
diff --git a/chrome/browser/ash/arc/accessibility/geometry_util.h b/chrome/browser/ash/arc/accessibility/geometry_util.h
index e67d692..ad3c58f 100644
--- a/chrome/browser/ash/arc/accessibility/geometry_util.h
+++ b/chrome/browser/ash/arc/accessibility/geometry_util.h
@@ -5,8 +5,6 @@
 #ifndef CHROME_BROWSER_ASH_ARC_ACCESSIBILITY_GEOMETRY_UTIL_H_
 #define CHROME_BROWSER_ASH_ARC_ACCESSIBILITY_GEOMETRY_UTIL_H_
 
-// TODO(hirokisato): support multiple display.
-
 namespace gfx {
 class Rect;
 class RectF;
diff --git a/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper_unittest.cc b/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper_unittest.cc
index 1ee3658..f5f36fe 100644
--- a/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper_unittest.cc
+++ b/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper_unittest.cc
@@ -28,10 +28,10 @@
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h"
 #include "chrome/browser/web_applications/test/test_web_app_provider.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/arc/mojom/app.mojom.h"
@@ -48,7 +48,7 @@
 #include "url/gurl.h"
 
 using web_app::GenerateAppId;
-using web_app::WebAppProviderBase;
+using web_app::WebAppProvider;
 
 namespace ash {
 namespace app_time {
@@ -184,7 +184,7 @@
 
     if (app_id.app_type() == apps::mojom::AppType::kWeb) {
       base::RunLoop run_loop;
-      WebAppProviderBase::GetProviderBase(&profile_)
+      WebAppProvider::GetForWebApps(&profile_)
           ->install_finalizer()
           .UninstallExternalWebApp(
               app_id.app_id(),
@@ -221,7 +221,7 @@
     }
 
     if (app_id.app_type() == apps::mojom::AppType::kWeb) {
-      WebAppProviderBase::GetProviderBase(&profile_)
+      WebAppProvider::GetForWebApps(&profile_)
           ->registry_controller()
           .SetAppIsDisabled(app_id.app_id(), disabled);
       task_environment_.RunUntilIdle();
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc
index d539763..5a73e44 100644
--- a/chrome/browser/ash/crostini/crostini_manager.cc
+++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -153,28 +153,28 @@
   std::string name;
   switch (state) {
     case mojom::InstallerState::kStart:
-      name = "Crostini.RestarterTimeInState.Start";
+      name = "Crostini.RestarterTimeInState2.Start";
       break;
     case mojom::InstallerState::kInstallImageLoader:
-      name = "Crostini.RestarterTimeInState.InstallImageLoader";
+      name = "Crostini.RestarterTimeInState2.InstallImageLoader";
       break;
     case mojom::InstallerState::kCreateDiskImage:
-      name = "Crostini.RestarterTimeInState.CreateDiskImage";
+      name = "Crostini.RestarterTimeInState2.CreateDiskImage";
       break;
     case mojom::InstallerState::kStartTerminaVm:
-      name = "Crostini.RestarterTimeInState.StartTerminaVm";
+      name = "Crostini.RestarterTimeInState2.StartTerminaVm";
       break;
     case mojom::InstallerState::kStartLxd:
-      name = "Crostini.RestarterTimeInState.StartLxd";
+      name = "Crostini.RestarterTimeInState2.StartLxd";
       break;
     case mojom::InstallerState::kCreateContainer:
-      name = "Crostini.RestarterTimeInState.CreateContainer";
+      name = "Crostini.RestarterTimeInState2.CreateContainer";
       break;
     case mojom::InstallerState::kSetupContainer:
-      name = "Crostini.RestarterTimeInState.SetupContainer";
+      name = "Crostini.RestarterTimeInState2.SetupContainer";
       break;
     case mojom::InstallerState::kStartContainer:
-      name = "Crostini.RestarterTimeInState.StartContainer";
+      name = "Crostini.RestarterTimeInState2.StartContainer";
       break;
     case mojom::InstallerState::kConfigureContainer:
       NOTREACHED();
@@ -466,7 +466,12 @@
   };
 
   void StartStage(mojom::InstallerState stage) {
-    EmitTimeInStageHistogram(base::TimeTicks::Now() - stage_start_, stage);
+    int finished_stage = static_cast<int>(stage) - 1;
+    if (finished_stage >= 0) {
+      EmitTimeInStageHistogram(
+          base::TimeTicks::Now() - stage_start_,
+          static_cast<mojom::InstallerState>(finished_stage));
+    }
     this->stage_ = stage;
     stage_start_ = base::TimeTicks::Now();
     DCHECK(stage_timeouts_.find(stage) != stage_timeouts_.end());
@@ -483,6 +488,7 @@
 
   void FinishRestart(CrostiniResult result) {
     DCHECK(!is_aborted_);
+    EmitTimeInStageHistogram(base::TimeTicks::Now() - stage_start_, stage_);
 
     // FinishRestart will delete this, so it's not safe to call any methods
     // after this point.
diff --git a/chrome/browser/ash/crostini/crostini_manager_unittest.cc b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
index 6e02c15b16..ae73587 100644
--- a/chrome/browser/ash/crostini/crostini_manager_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
@@ -829,8 +829,9 @@
   EXPECT_EQ(container_info.value().username,
             DefaultContainerUserNameForProfile(profile()));
   ExpectRestarterUmaCount(1);
+  histogram_tester_.ExpectTotalCount("Crostini.RestarterTimeInState2.Start", 1);
   histogram_tester_.ExpectTotalCount(
-      "Crostini.RestarterTimeInState.StartTerminaVm", 1);
+      "Crostini.RestarterTimeInState2.StartContainer", 1);
   histogram_tester_.ExpectBucketCount(
       "Crostini.SetUpLxdContainerUser.UnknownResult", false, 1);
 }
@@ -934,6 +935,10 @@
   EXPECT_EQ(fake_concierge_client_->create_disk_image_call_count(), 0);
   ExpectCrostiniRestartResult(CrostiniResult::INSTALL_IMAGE_LOADER_TIMED_OUT);
   ExpectRestarterUmaCount(1);
+  histogram_tester_.ExpectTotalCount(
+      "Crostini.RestarterTimeInState2.InstallImageLoader", 1);
+  histogram_tester_.ExpectTotalCount(
+      "Crostini.RestarterTimeInState2.CreateDiskImage", 0);
 }
 
 TEST_F(CrostiniManagerRestartTest, AbortOnDiskImageCreated) {
@@ -948,6 +953,10 @@
   EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
+  histogram_tester_.ExpectTotalCount(
+      "Crostini.RestarterTimeInState2.InstallImageLoader", 1);
+  histogram_tester_.ExpectTotalCount(
+      "Crostini.RestarterTimeInState2.CreateDiskImage", 0);
 }
 
 TEST_F(CrostiniManagerRestartTest, TimeoutDuringCreateDiskImage) {
diff --git a/chrome/browser/ash/file_manager/web_file_tasks.cc b/chrome/browser/ash/file_manager/web_file_tasks.cc
index 999e5fa..a8e3bdd 100644
--- a/chrome/browser/ash/file_manager/web_file_tasks.cc
+++ b/chrome/browser/ash/file_manager/web_file_tasks.cc
@@ -17,11 +17,11 @@
 #include "chrome/browser/ash/file_manager/file_tasks.h"
 #include "chrome/browser/ash/file_manager/filesystem_api_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id_constants.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/webui_url_constants.h"
 #include "extensions/browser/api/file_handlers/app_file_handler_util.h"
 #include "extensions/browser/entry_info.h"
@@ -57,9 +57,9 @@
     }
   }
 
-  web_app::WebAppProviderBase* provider =
-      web_app::WebAppProviderBase::GetProviderBase(profile);
-  web_app::AppRegistrar& registrar = provider->registrar();
+  web_app::WebAppProvider* provider =
+      web_app::WebAppProvider::GetForWebApps(profile);
+  web_app::WebAppRegistrar& registrar = provider->registrar();
   web_app::OsIntegrationManager& os_integration_manager =
       provider->os_integration_manager();
 
@@ -121,9 +121,9 @@
                     const TaskDescriptor& task,
                     const std::vector<storage::FileSystemURL>& file_system_urls,
                     FileTaskFinishedCallback done) {
-  web_app::WebAppProviderBase* provider =
-      web_app::WebAppProviderBase::GetProviderBase(profile);
-  web_app::AppRegistrar& registrar = provider->registrar();
+  web_app::WebAppProvider* provider =
+      web_app::WebAppProvider::GetForWebApps(profile);
+  web_app::WebAppRegistrar& registrar = provider->registrar();
 
   if (!registrar.IsInstalled(task.app_id)) {
     std::move(done).Run(
diff --git a/chrome/browser/ash/file_manager/web_file_tasks_unittest.cc b/chrome/browser/ash/file_manager/web_file_tasks_unittest.cc
index 3f0a1dc0..490d923f 100644
--- a/chrome/browser/ash/file_manager/web_file_tasks_unittest.cc
+++ b/chrome/browser/ash/file_manager/web_file_tasks_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ash/file_manager/file_tasks.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/test/test_file_handler_manager.h"
 #include "chrome/browser/web_applications/test/test_os_integration_manager.h"
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.cc
index 3f1df0d4..568bc99 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.cc
@@ -155,7 +155,7 @@
     const AccountId& account_id,
     const EasyUnlockDeviceKeyDataList& data_list,
     base::ListValue* device_list) {
-  device_list->Clear();
+  device_list->ClearList();
   for (size_t i = 0; i < data_list.size(); ++i) {
     std::unique_ptr<base::DictionaryValue> device_dict(
         new base::DictionaryValue);
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
index 0d167d7..bba66c8 100644
--- a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
@@ -756,7 +756,7 @@
   if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) {
     ListPrefUpdate prefs_users_update(GetLocalState(),
                                       user_manager::kRegularUsersPref);
-    prefs_users_update->Clear();
+    prefs_users_update->ClearList();
     for (user_manager::UserList::iterator it = users_.begin();
          it != users_.end();) {
       const AccountId account_id = (*it)->GetAccountId();
@@ -1014,7 +1014,7 @@
   // us to clean up associated data if they disappear from policy.
   ListPrefUpdate prefs_device_local_accounts_update(
       GetLocalState(), kDeviceLocalAccountsWithSavedData);
-  prefs_device_local_accounts_update->Clear();
+  prefs_device_local_accounts_update->ClearList();
   for (const auto& account : device_local_accounts)
     prefs_device_local_accounts_update->AppendString(account.user_id);
 
diff --git a/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl_unittest.cc
index 5a4296e3..629218f 100644
--- a/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl_unittest.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_rules_manager_impl_unittest.cc
@@ -521,7 +521,7 @@
   rules_2.Append(dlp_test_util::CreateRule(
       "rule #1", "Block", std::move(src_urls_2), std::move(dst_urls_2),
       /*dst_components=*/base::Value(base::Value::Type::LIST),
-      std::move(restrictions_1)));
+      std::move(restrictions_2)));
 
   UpdatePolicyPref(std::move(rules_2));
 
diff --git a/chrome/browser/ash/power/auto_screen_brightness/light_provider_mojo_unittest.cc b/chrome/browser/ash/power/auto_screen_brightness/light_provider_mojo_unittest.cc
index 3ff3a503..a8984f33 100644
--- a/chrome/browser/ash/power/auto_screen_brightness/light_provider_mojo_unittest.cc
+++ b/chrome/browser/ash/power/auto_screen_brightness/light_provider_mojo_unittest.cc
@@ -11,9 +11,9 @@
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
 #include "chrome/browser/ash/power/auto_screen_brightness/fake_observer.h"
+#include "chromeos/components/sensors/ash/sensor_hal_dispatcher.h"
 #include "chromeos/components/sensors/fake_sensor_device.h"
 #include "chromeos/components/sensors/fake_sensor_hal_server.h"
-#include "chromeos/components/sensors/sensor_hal_dispatcher.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace ash {
diff --git a/chrome/browser/ash/web_applications/system_web_app_integration_test.cc b/chrome/browser/ash/web_applications/system_web_app_integration_test.cc
index d358f7a..5446d3d 100644
--- a/chrome/browser/ash/web_applications/system_web_app_integration_test.cc
+++ b/chrome/browser/ash/web_applications/system_web_app_integration_test.cc
@@ -44,8 +44,8 @@
   EXPECT_EQ(GetManager().GetAppIdForSystemApp(app_type), app_id);
   EXPECT_TRUE(GetManager().IsSystemWebApp(app_id));
 
-  web_app::AppRegistrar& registrar =
-      web_app::WebAppProviderBase::GetProviderBase(profile())->registrar();
+  web_app::WebAppRegistrar& registrar =
+      web_app::WebAppProvider::GetForWebApps(profile())->registrar();
   EXPECT_EQ(title, registrar.GetAppShortName(app_id));
   EXPECT_EQ(base::ASCIIToUTF16(title),
             app_browser->window()->GetNativeWindow()->GetTitle());
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc
index f0e0aae..5d00d86 100644
--- a/chrome/browser/autofill/form_structure_browsertest.cc
+++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -254,7 +254,8 @@
   return std::move(response);
 }
 
-IN_PROC_BROWSER_TEST_P(FormStructureBrowserTest, DataDrivenHeuristics) {
+// Times out on all platforms.  http://crbug.com/1216328
+IN_PROC_BROWSER_TEST_P(FormStructureBrowserTest, DISABLED_DataDrivenHeuristics) {
   // Prints the path of the test to be executed.
   LOG(INFO) << GetParam().MaybeAsASCII();
   bool is_expected_to_pass =
diff --git a/chrome/browser/badging/badge_manager.cc b/chrome/browser/badging/badge_manager.cc
index f24512773..8ad1154 100644
--- a/chrome/browser/badging/badge_manager.cc
+++ b/chrome/browser/badging/badge_manager.cc
@@ -17,9 +17,9 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/ukm/app_source_url_recorder.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -43,7 +43,7 @@
                              const base::Clock* clock,
                              Profile* profile) {
   const base::Time last_badging_time =
-      web_app::WebAppProviderBase::GetProviderBase(profile)
+      web_app::WebAppProvider::GetForWebApps(profile)
           ->registrar()
           .GetAppLastBadgingTime(app_id);
   return clock->Now() < last_badging_time + time_frame;
@@ -57,7 +57,7 @@
     return;
   }
 
-  web_app::WebAppProviderBase::GetProviderBase(profile)
+  web_app::WebAppProvider::GetForWebApps(profile)
       ->registry_controller()
       .SetAppLastBadgingTime(app_id, clock->Now());
 }
@@ -250,12 +250,12 @@
   if (!contents)
     return std::vector<std::tuple<web_app::AppId, GURL>>{};
 
-  auto* provider = web_app::WebAppProviderBase::GetProviderBase(
+  auto* provider = web_app::WebAppProvider::GetForWebApps(
       Profile::FromBrowserContext(contents->GetBrowserContext()));
   if (!provider)
     return std::vector<std::tuple<web_app::AppId, GURL>>{};
 
-  const web_app::AppRegistrar& registrar = provider->registrar();
+  const web_app::WebAppRegistrar& registrar = provider->registrar();
   const absl::optional<web_app::AppId> app_id =
       registrar.FindAppWithUrlInScope(frame->GetLastCommittedURL());
   if (!app_id)
@@ -273,12 +273,12 @@
   if (!render_process_host)
     return std::vector<std::tuple<web_app::AppId, GURL>>{};
 
-  auto* provider = web_app::WebAppProviderBase::GetProviderBase(
+  auto* provider = web_app::WebAppProvider::GetForWebApps(
       Profile::FromBrowserContext(render_process_host->GetBrowserContext()));
   if (!provider)
     return std::vector<std::tuple<web_app::AppId, GURL>>{};
 
-  const web_app::AppRegistrar& registrar = provider->registrar();
+  const web_app::WebAppRegistrar& registrar = provider->registrar();
   std::vector<std::tuple<web_app::AppId, GURL>> app_ids_urls{};
   for (const auto& app_id : registrar.FindAppsInScope(scope_)) {
     app_ids_urls.push_back(
diff --git a/chrome/browser/badging/badge_manager_unittest.cc b/chrome/browser/badging/badge_manager_unittest.cc
index 6ae32be..0437471 100644
--- a/chrome/browser/badging/badge_manager_unittest.cc
+++ b/chrome/browser/badging/badge_manager_unittest.cc
@@ -13,9 +13,9 @@
 #include "chrome/browser/badging/badge_manager_delegate.h"
 #include "chrome/browser/badging/badge_manager_factory.h"
 #include "chrome/browser/badging/test_badge_manager_delegate.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/test/test_app_registry_controller.h"
 #include "chrome/browser/web_applications/test/test_web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/ukm/test_ukm_recorder.h"
 #include "content/public/test/browser_task_environment.h"
diff --git a/chrome/browser/badging/test_badge_manager_delegate.cc b/chrome/browser/badging/test_badge_manager_delegate.cc
index ae3b626..6603ee9 100644
--- a/chrome/browser/badging/test_badge_manager_delegate.cc
+++ b/chrome/browser/badging/test_badge_manager_delegate.cc
@@ -7,7 +7,7 @@
 #include "chrome/browser/badging/badge_manager.h"
 #include "chrome/browser/badging/badge_manager_delegate.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 
 namespace badging {
 
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc
index 25596a6..9382c2c 100644
--- a/chrome/browser/banners/app_banner_manager_desktop.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -83,7 +83,7 @@
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   extension_registry_ = extensions::ExtensionRegistry::Get(profile);
-  auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
   // May be null in unit tests e.g. TabDesktopMediaListTest.*.
   if (provider)
     registrar_observation_.Observe(&provider->registrar());
@@ -148,8 +148,8 @@
       .has_value();
 }
 
-web_app::AppRegistrar& AppBannerManagerDesktop::registrar() {
-  auto* provider = web_app::WebAppProviderBase::GetProviderBase(
+web_app::WebAppRegistrar& AppBannerManagerDesktop::registrar() {
+  auto* provider = web_app::WebAppProvider::GetForWebApps(
       Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
   DCHECK(provider);
   return provider->registrar();
diff --git a/chrome/browser/banners/app_banner_manager_desktop.h b/chrome/browser/banners/app_banner_manager_desktop.h
index 42c689e..f350e4d6 100644
--- a/chrome/browser/banners/app_banner_manager_desktop.h
+++ b/chrome/browser/banners/app_banner_manager_desktop.h
@@ -10,9 +10,9 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/webapps/browser/banners/app_banner_manager.h"
 #include "content/public/browser/web_contents_user_data.h"
 
@@ -73,7 +73,7 @@
   friend class content::WebContentsUserData<AppBannerManagerDesktop>;
   friend class FakeAppBannerManagerDesktop;
 
-  web_app::AppRegistrar& registrar();
+  web_app::WebAppRegistrar& registrar();
 
   // AppBannerManager overrides.
   bool ShouldAllowWebAppReplacementInstall() override;
@@ -93,7 +93,8 @@
 
   extensions::ExtensionRegistry* extension_registry_;
 
-  base::ScopedObservation<web_app::AppRegistrar, web_app::AppRegistrarObserver>
+  base::ScopedObservation<web_app::WebAppRegistrar,
+                          web_app::AppRegistrarObserver>
       registrar_observation_{this};
 
   base::WeakPtrFactory<AppBannerManagerDesktop> weak_factory_{this};
diff --git a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
index 006ed0ab..4ac1b3b 100644
--- a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
@@ -30,7 +30,7 @@
 #include "chrome/browser/web_applications/components/externally_managed_app_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/webapps/browser/banners/app_banner_metrics.h"
@@ -313,7 +313,7 @@
   // Uninstall web app by policy.
   {
     base::RunLoop run_loop;
-    web_app::WebAppProviderBase::GetProviderBase(profile)
+    web_app::WebAppProvider::GetForWebApps(profile)
         ->externally_managed_app_manager()
         .UninstallApps({GetBannerURL()},
                        web_app::ExternalInstallSource::kExternalPolicy,
diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc
index d148223..33b0933 100644
--- a/chrome/browser/bookmarks/bookmark_html_writer.cc
+++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -153,14 +153,16 @@
 // Class responsible for the actual writing. Takes ownership of favicons_map.
 class Writer : public base::RefCountedThreadSafe<Writer> {
  public:
-  Writer(std::unique_ptr<base::Value> bookmarks,
+  Writer(base::Value bookmarks,
          const base::FilePath& path,
          BookmarkFaviconFetcher::URLFaviconMap* favicons_map,
          BookmarksExportObserver* observer)
       : bookmarks_(std::move(bookmarks)),
         path_(path),
         favicons_map_(favicons_map),
-        observer_(observer) {}
+        observer_(observer) {
+    DCHECK(bookmarks_.is_dict());
+  }
 
   // Writing bookmarks and favicons data to file.
   void DoWrite() {
@@ -169,35 +171,23 @@
       return;
     }
 
-    base::Value* roots = nullptr;
     if (!Write(kHeader)) {
       NotifyOnFinish(BookmarksExportObserver::Result::kCouldNotWriteHeader);
       return;
     }
 
-    if (bookmarks_->type() != base::Value::Type::DICTIONARY ||
-        !static_cast<base::DictionaryValue*>(bookmarks_.get())
-             ->Get(BookmarkCodec::kRootsKey, &roots) ||
-        roots->type() != base::Value::Type::DICTIONARY) {
-      NOTREACHED();  // Invalid type for roots key.
-    }
+    base::Value* roots = bookmarks_.FindDictKey(BookmarkCodec::kRootsKey);
+    DCHECK(roots);
 
-    base::DictionaryValue* roots_d_value =
-        static_cast<base::DictionaryValue*>(roots);
-    base::Value* root_folder_value;
-    base::Value* other_folder_value = nullptr;
-    base::Value* mobile_folder_value = nullptr;
-    if (!roots_d_value->Get(BookmarkCodec::kRootFolderNameKey,
-                            &root_folder_value) ||
-        root_folder_value->type() != base::Value::Type::DICTIONARY ||
-        !roots_d_value->Get(BookmarkCodec::kOtherBookmarkFolderNameKey,
-                            &other_folder_value) ||
-        other_folder_value->type() != base::Value::Type::DICTIONARY ||
-        !roots_d_value->Get(BookmarkCodec::kMobileBookmarkFolderNameKey,
-                            &mobile_folder_value) ||
-        mobile_folder_value->type() != base::Value::Type::DICTIONARY) {
-      NOTREACHED();  // Invalid type for root folder and/or other folder.
-    }
+    base::Value* root_folder_value =
+        roots->FindDictKey(BookmarkCodec::kRootFolderNameKey);
+    base::Value* other_folder_value =
+        roots->FindDictKey(BookmarkCodec::kOtherBookmarkFolderNameKey);
+    base::Value* mobile_folder_value =
+        roots->FindDictKey(BookmarkCodec::kMobileBookmarkFolderNameKey);
+    DCHECK(root_folder_value);
+    DCHECK(other_folder_value);
+    DCHECK(mobile_folder_value);
 
     IncrementIndent();
 
@@ -319,27 +309,31 @@
   }
 
   // Writes the node and all its children, returning true on success.
-  bool WriteNode(const base::DictionaryValue& value,
-                BookmarkNode::Type folder_type) {
-    std::string title, date_added_string, type_string;
-    if (!value.GetString(BookmarkCodec::kNameKey, &title) ||
-        !value.GetString(BookmarkCodec::kDateAddedKey, &date_added_string) ||
-        !value.GetString(BookmarkCodec::kTypeKey, &type_string) ||
-        (type_string != BookmarkCodec::kTypeURL &&
-         type_string != BookmarkCodec::kTypeFolder))  {
+  bool WriteNode(const base::Value& value, BookmarkNode::Type folder_type) {
+    DCHECK(value.is_dict());
+    const std::string* title_ptr = value.FindStringKey(BookmarkCodec::kNameKey);
+    const std::string* date_added_string =
+        value.FindStringKey(BookmarkCodec::kDateAddedKey);
+    const std::string* type_string =
+        value.FindStringKey(BookmarkCodec::kTypeKey);
+    if (!title_ptr || !date_added_string || !type_string ||
+        (*type_string != BookmarkCodec::kTypeURL &&
+         *type_string != BookmarkCodec::kTypeFolder)) {
       NOTREACHED();
       return false;
     }
 
-    if (type_string == BookmarkCodec::kTypeURL) {
-      std::string url_string;
-      if (!value.GetString(BookmarkCodec::kURLKey, &url_string)) {
+    std::string title = *title_ptr;
+    if (*type_string == BookmarkCodec::kTypeURL) {
+      const std::string* url_string =
+          value.FindStringKey(BookmarkCodec::kURLKey);
+      if (!url_string) {
         NOTREACHED();
         return false;
       }
 
       std::string favicon_string;
-      auto itr = favicons_map_->find(url_string);
+      auto itr = favicons_map_->find(*url_string);
       if (itr != favicons_map_->end()) {
         scoped_refptr<base::RefCountedMemory> data(itr->second.get());
         std::string favicon_base64_encoded;
@@ -350,30 +344,24 @@
         favicon_string = favicon_url.spec();
       }
 
-      if (!WriteIndent() ||
-          !Write(kBookmarkStart) ||
-          !Write(url_string, ATTRIBUTE_VALUE) ||
-          !Write(kAddDate) ||
-          !WriteTime(date_added_string) ||
+      if (!WriteIndent() || !Write(kBookmarkStart) ||
+          !Write(*url_string, ATTRIBUTE_VALUE) || !Write(kAddDate) ||
+          !WriteTime(*date_added_string) ||
           (!favicon_string.empty() &&
-              (!Write(kIcon) ||
-               !Write(favicon_string, ATTRIBUTE_VALUE))) ||
-          !Write(kBookmarkAttributeEnd) ||
-          !Write(title, CONTENT) ||
-          !Write(kBookmarkEnd) ||
-          !Write(kNewline)) {
+           (!Write(kIcon) || !Write(favicon_string, ATTRIBUTE_VALUE))) ||
+          !Write(kBookmarkAttributeEnd) || !Write(title, CONTENT) ||
+          !Write(kBookmarkEnd) || !Write(kNewline)) {
         return false;
       }
       return true;
     }
 
     // Folder.
-    std::string last_modified_date;
-    const base::Value* child_values = nullptr;
-    if (!value.GetString(BookmarkCodec::kDateModifiedKey,
-                         &last_modified_date) ||
-        !value.Get(BookmarkCodec::kChildrenKey, &child_values) ||
-        child_values->type() != base::Value::Type::LIST) {
+    const std::string* last_modified_date =
+        value.FindStringKey(BookmarkCodec::kDateModifiedKey);
+    const base::Value* child_values =
+        value.FindListKey(BookmarkCodec::kChildrenKey);
+    if (!last_modified_date || !child_values) {
       NOTREACHED();
       return false;
     }
@@ -382,11 +370,9 @@
       // The other/mobile folder name are not written out. This gives the effect
       // of making the contents of the 'other folder' be a sibling to the
       // bookmark bar folder.
-      if (!WriteIndent() ||
-          !Write(kFolderStart) ||
-          !WriteTime(date_added_string) ||
-          !Write(kLastModified) ||
-          !WriteTime(last_modified_date)) {
+      if (!WriteIndent() || !Write(kFolderStart) ||
+          !WriteTime(*date_added_string) || !Write(kLastModified) ||
+          !WriteTime(*last_modified_date)) {
         return false;
       }
       if (folder_type == BookmarkNode::BOOKMARK_BAR) {
@@ -408,19 +394,13 @@
     }
 
     // Write the children.
-    const base::ListValue* children =
-        static_cast<const base::ListValue*>(child_values);
-    for (size_t i = 0; i < children->GetSize(); ++i) {
-      const base::Value* child_value;
-      if (!children->Get(i, &child_value) ||
-          child_value->type() != base::Value::Type::DICTIONARY) {
+    for (const base::Value& child_value : child_values->GetList()) {
+      if (!child_value.is_dict()) {
         NOTREACHED();
         return false;
       }
-      if (!WriteNode(*static_cast<const base::DictionaryValue*>(child_value),
-                     BookmarkNode::FOLDER)) {
+      if (!WriteNode(child_value, BookmarkNode::FOLDER))
         return false;
-      }
     }
     if (folder_type != BookmarkNode::OTHER_NODE &&
         folder_type != BookmarkNode::MOBILE) {
@@ -437,7 +417,7 @@
 
   // The BookmarkModel as a base::Value. This value was generated from the
   // BookmarkCodec.
-  std::unique_ptr<base::Value> bookmarks_;
+  base::Value bookmarks_;
 
   // Path we're writing to.
   base::FilePath path_;
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index 8ac7b7f..0f388a1 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1166,30 +1166,6 @@
     return completion_observer.failed_data_types();
   }
 
-  void ExpectRemoveLoginsByURLAndTime(
-      password_manager::MockPasswordStore* store) {
-    EXPECT_CALL(*store, RemoveLoginsByURLAndTime)
-        .WillOnce(
-            testing::WithArgs<3, 4>([](auto callback, auto sync_callback) {
-              std::move(callback).Run();
-              if (sync_callback)
-                std::move(sync_callback).Run(false);
-            }));
-  }
-
-  void ExpectRemoveLoginsByURLAndTimeWithFilter(
-      password_manager::MockPasswordStore* store,
-      base::RepeatingCallback<bool(const GURL&)> filter) {
-    EXPECT_CALL(*store, RemoveLoginsByURLAndTime(ProbablySameFilter(filter), _,
-                                                 _, _, _))
-        .WillOnce(
-            testing::WithArgs<3, 4>([](auto callback, auto sync_callback) {
-              std::move(callback).Run();
-              if (sync_callback)
-                std::move(sync_callback).Run(false);
-            }));
-  }
-
   void BlockUntilOriginDataRemoved(
       const base::Time& delete_begin,
       const base::Time& delete_end,
@@ -1442,7 +1418,7 @@
   // Expect that passwords will be deleted, as they do not depend
   // on |prefs::kAllowDeletingBrowserHistory|.
   RemovePasswordsTester tester(GetProfile());
-  ExpectRemoveLoginsByURLAndTime(tester.profile_store());
+  EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _));
 
   uint64_t removal_mask =
       constants::DATA_TYPE_HISTORY | constants::DATA_TYPE_PASSWORDS;
@@ -2018,7 +1994,9 @@
   base::RepeatingCallback<bool(const GURL&)> filter =
       BrowsingDataFilterBuilder::BuildNoopFilter();
 
-  ExpectRemoveLoginsByURLAndTimeWithFilter(tester.profile_store(), filter);
+  EXPECT_CALL(*tester.profile_store(),
+              RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _))
+      .WillOnce(Return(password_manager::PasswordStoreChangeList()));
 
   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
                                 constants::DATA_TYPE_PASSWORDS, false);
@@ -2034,7 +2012,9 @@
   builder->AddRegisterableDomain(kTestRegisterableDomain1);
   base::RepeatingCallback<bool(const GURL&)> filter = builder->BuildUrlFilter();
 
-  ExpectRemoveLoginsByURLAndTimeWithFilter(tester.profile_store(), filter);
+  EXPECT_CALL(*tester.profile_store(),
+              RemoveLoginsByURLAndTimeImpl(ProbablySameFilter(filter), _, _))
+      .WillOnce(Return(password_manager::PasswordStoreChangeList()));
   BlockUntilOriginDataRemoved(base::Time(), base::Time::Max(),
                               constants::DATA_TYPE_PASSWORDS,
                               std::move(builder));
@@ -2060,7 +2040,8 @@
   base::RepeatingCallback<bool(const GURL&)> empty_filter =
       BrowsingDataFilterBuilder::BuildNoopFilter();
 
-  ExpectRemoveLoginsByURLAndTime(tester.profile_store());
+  EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _))
+      .WillOnce(Return(password_manager::PasswordStoreChangeList()));
   EXPECT_CALL(*tester.profile_store(),
               DisableAutoSignInForOriginsImpl(ProbablySameFilter(empty_filter)))
       .WillOnce(Return(password_manager::PasswordStoreChangeList()));
@@ -3100,9 +3081,12 @@
        RemovePasswordsByTimeOnly_WithAccountStore) {
   RemovePasswordsTester tester(GetProfile());
 
-  ExpectRemoveLoginsByURLAndTime(tester.profile_store());
+  EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _))
+      .WillOnce(Return(password_manager::PasswordStoreChangeList()));
+
   // Only DATA_TYPE_PASSWORDS is cleared. Accounts passwords are not affected.
-  EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTime).Times(0);
+  EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _))
+      .Times(0);
 
   BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
                                 constants::DATA_TYPE_PASSWORDS, false);
@@ -3112,8 +3096,11 @@
        RemoveAccountPasswordsByTimeOnly_WithAccountStore) {
   RemovePasswordsTester tester(GetProfile());
 
-  EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTime).Times(0);
-  ExpectRemoveLoginsByURLAndTime(tester.account_store());
+  EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _))
+      .Times(0);
+
+  EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _))
+      .WillOnce(Return(password_manager::PasswordStoreChangeList()));
   // For the account store, the remover delegate also waits until all the
   // deletions have propagated to the Sync server. Pretend that happens
   // immediately.
@@ -3128,13 +3115,19 @@
        RemoveAccountPasswordsByTimeOnly_WithAccountStore_Failure) {
   RemovePasswordsTester tester(GetProfile());
 
-  EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTime).Times(0);
-  ExpectRemoveLoginsByURLAndTime(tester.account_store());
+  EXPECT_CALL(*tester.profile_store(), RemoveLoginsByURLAndTimeImpl(_, _, _))
+      .Times(0);
+
+  EXPECT_CALL(*tester.account_store(), RemoveLoginsByURLAndTimeImpl(_, _, _))
+      .WillOnce(Return(password_manager::PasswordStoreChangeList()));
   // For the account store, the remover delegate also waits until all the
   // deletions have propagated to the Sync server. In this test, that never
   // happens.
   EXPECT_CALL(*tester.account_metadata_store(), HasUnsyncedDeletions())
       .WillRepeatedly(Return(true));
+  // Bypass the (usually 30-second) timeout until the PasswordStore reports
+  // failure.
+  tester.account_store()->SetSyncTaskTimeoutForTest(base::TimeDelta());
 
   uint64_t failed_data_types = BlockUntilBrowsingDataRemoved(
       base::Time(), base::Time::Max(), constants::DATA_TYPE_ACCOUNT_PASSWORDS,
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index be93859..dff0a32 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -396,7 +396,7 @@
     ListPrefUpdate update(g_browser_process->local_state(),
                           prefs::kProfilesLastActive);
     base::ListValue* profile_list = update.Get();
-    profile_list->Clear();
+    profile_list->ClearList();
   }
 
   StartupProfileInfo profile_info;
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 9dc1d01..10b6f44 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -473,7 +473,7 @@
   auto* provider = web_app::WebAppProvider::Get(profile);
   if (!provider)
     return;
-  web_app::AppRegistrar& registrar = provider->registrar();
+  web_app::WebAppRegistrar& registrar = provider->registrar();
 
   // Create a vector of all PWA-launcher paths in |profile_dir|.
   std::vector<base::FilePath> pwa_launcher_paths;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index e1d5350..80da80b 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -177,9 +177,9 @@
 #include "chrome/browser/ui/webui/log_web_ui_url.h"
 #include "chrome/browser/usb/frame_usb_services.h"
 #include "chrome/browser/vr/vr_tab_helper.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_constants.h"
@@ -3359,15 +3359,15 @@
       if (browser && browser->app_controller() &&
           browser->app_controller()->HasAppId()) {
         const web_app::AppId& app_id = browser->app_controller()->GetAppId();
-        const web_app::AppRegistrar& registrar =
-            web_app::WebAppProviderBase::GetProviderBase(profile)->registrar();
+        const web_app::WebAppRegistrar& registrar =
+            web_app::WebAppProvider::GetForWebApps(profile)->registrar();
         if (registrar.IsLocallyInstalled(app_id))
           web_prefs->web_app_scope = registrar.GetAppScope(app_id);
 
         if (browser->app_controller()->is_for_system_web_app()) {
           auto system_app_type = browser->app_controller()->system_app_type();
           const web_app::SystemWebAppManager& system_web_app_manager =
-              web_app::WebAppProviderBase::GetProviderBase(profile)
+              web_app::WebAppProvider::GetForWebApps(profile)
                   ->system_web_app_manager();
           web_prefs->allow_scripts_to_close_windows =
               system_web_app_manager.AllowScriptsToCloseWindows(
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc
index 6d3fc7d..b84c4549 100644
--- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc
+++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc
@@ -18,7 +18,7 @@
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chromeos/components/multidevice/logging/logging.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
@@ -71,7 +71,7 @@
     const web_app::AppId& app_id,
     Profile* profile,
     SuccessCallback callback) {
-  auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
   if (!provider) {
     std::move(callback).Run(false);
     return;
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
index 2e989d9..6b38514f 100644
--- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -110,11 +110,10 @@
 #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
 #include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/crostini_installer/crostini_installer_ui.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/api/autotest_private.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -1830,8 +1829,8 @@
 ExtensionFunction::ResponseAction
 AutotestPrivateWaitForSystemWebAppsInstallFunction::Run() {
   Profile* profile = Profile::FromBrowserContext(browser_context());
-  web_app::WebAppProviderBase* provider =
-      web_app::WebAppProviderBase::GetProviderBase(profile);
+  web_app::WebAppProvider* provider =
+      web_app::WebAppProvider::GetForWebApps(profile);
 
   if (!provider)
     return RespondNow(Error("Web Apps are not available for profile."));
@@ -1857,8 +1856,8 @@
 ExtensionFunction::ResponseAction
 AutotestPrivateGetRegisteredSystemWebAppsFunction::Run() {
   Profile* profile = Profile::FromBrowserContext(browser_context());
-  web_app::WebAppProviderBase* provider =
-      web_app::WebAppProviderBase::GetProviderBase(profile);
+  web_app::WebAppProvider* provider =
+      web_app::WebAppProvider::GetForWebApps(profile);
 
   if (!provider)
     return RespondNow(Error("Web Apps are not available for profile."));
@@ -1892,8 +1891,8 @@
 ExtensionFunction::ResponseAction
 AutotestPrivateIsSystemWebAppOpenFunction::Run() {
   Profile* profile = Profile::FromBrowserContext(browser_context());
-  web_app::WebAppProviderBase* provider =
-      web_app::WebAppProviderBase::GetProviderBase(profile);
+  web_app::WebAppProvider* provider =
+      web_app::WebAppProvider::GetForWebApps(profile);
 
   if (!provider)
     return RespondNow(Error("Web Apps are not available for profile."));
@@ -4096,7 +4095,7 @@
                        base::OnceCallback<void(const web_app::AppId&)> callback)
       : callback_(std::move(callback)) {
     observation_.Observe(
-        &web_app::WebAppProviderBase::GetProviderBase(profile)->registrar());
+        &web_app::WebAppProvider::GetForWebApps(profile)->registrar());
   }
   ~PWARegistrarObserver() override {}
 
@@ -4106,7 +4105,8 @@
   }
 
  private:
-  base::ScopedObservation<web_app::AppRegistrar, web_app::AppRegistrarObserver>
+  base::ScopedObservation<web_app::WebAppRegistrar,
+                          web_app::AppRegistrarObserver>
       observation_{this};
   base::OnceCallback<void(const web_app::AppId&)> callback_;
 
diff --git a/chrome/browser/chromeos/extensions/info_private_apitest.cc b/chrome/browser/chromeos/extensions/info_private_apitest.cc
index d98008c7..fffbc46 100644
--- a/chrome/browser/chromeos/extensions/info_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/info_private_apitest.cc
@@ -45,7 +45,8 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(ChromeOSInfoPrivateTest, TestGetAndSet) {
+// Flaky crashes. https://crbug.com/1226266
+IN_PROC_BROWSER_TEST_F(ChromeOSInfoPrivateTest, DISABLED_TestGetAndSet) {
   // Set the initial timezone different from what JS function
   // timezoneSetTest() will attempt to set.
   profile()->GetPrefs()->SetString(prefs::kUserTimezone, "America/Los_Angeles");
diff --git a/chrome/browser/chromeos/full_restore/app_launch_handler.cc b/chrome/browser/chromeos/full_restore/app_launch_handler.cc
index 2242264..d0b76e6 100644
--- a/chrome/browser/chromeos/full_restore/app_launch_handler.cc
+++ b/chrome/browser/chromeos/full_restore/app_launch_handler.cc
@@ -59,34 +59,6 @@
   return restore_data_ && !restore_data_->app_id_to_launch_list().empty();
 }
 
-void AppLaunchHandler::LaunchApps() {
-  // If there is no launch list from the restore data, we don't need to handle
-  // launching.
-  const auto& launch_list = restore_data_->app_id_to_launch_list();
-  if (launch_list.empty())
-    return;
-
-  // Observe AppRegistryCache to get the notification when the app is ready.
-  DCHECK(
-      apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile_));
-  auto* cache = &apps::AppServiceProxyFactory::GetForProfile(profile_)
-                     ->AppRegistryCache();
-  Observe(cache);
-
-  // Add the app to `app_ids` if there is a launch list from the restore data
-  // for the app.
-  std::set<std::string> app_ids;
-  cache->ForEachApp([&app_ids, &launch_list](const apps::AppUpdate& update) {
-    if (update.Readiness() == apps::mojom::Readiness::kReady &&
-        launch_list.find(update.AppId()) != launch_list.end()) {
-      app_ids.insert(update.AppId());
-    }
-  });
-
-  for (const auto& app_id : app_ids)
-    LaunchApp(cache->GetAppType(app_id), app_id);
-}
-
 void AppLaunchHandler::OnAppUpdate(const apps::AppUpdate& update) {
   if (!restore_data_ || !update.ReadinessChanged())
     return;
@@ -119,15 +91,44 @@
   apps::AppRegistryCache::Observer::Observe(nullptr);
 }
 
+void AppLaunchHandler::LaunchApps() {
+  // If there is no launch list from the restore data, we don't need to handle
+  // launching.
+  const auto& launch_list = restore_data_->app_id_to_launch_list();
+  if (launch_list.empty())
+    return;
+
+  // Observe AppRegistryCache to get the notification when the app is ready.
+  DCHECK(
+      apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile_));
+  auto* cache = &apps::AppServiceProxyFactory::GetForProfile(profile_)
+                     ->AppRegistryCache();
+  Observe(cache);
+
+  // Add the app to `app_ids` if there is a launch list from the restore data
+  // for the app.
+  std::set<std::string> app_ids;
+  cache->ForEachApp([&app_ids, &launch_list](const apps::AppUpdate& update) {
+    if (update.Readiness() == apps::mojom::Readiness::kReady &&
+        launch_list.find(update.AppId()) != launch_list.end()) {
+      app_ids.insert(update.AppId());
+    }
+  });
+
+  for (const auto& app_id : app_ids) {
+    // Chrome browser web pages are restored separately, so we don't need to
+    // launch browser windows.
+    if (app_id == extension_misc::kChromeAppId)
+      continue;
+
+    LaunchApp(cache->GetAppType(app_id), app_id);
+  }
+}
+
 void AppLaunchHandler::LaunchApp(apps::mojom::AppType app_type,
                                  const std::string& app_id) {
   DCHECK(restore_data_);
-
-  // For the Chrome browser, the browser session restore is used to restore the
-  // web pages, so we don't need to launch the app.
-  if (app_id == extension_misc::kChromeAppId) {
-    return;
-  }
+  DCHECK_NE(app_id, extension_misc::kChromeAppId);
 
   const auto it = restore_data_->app_id_to_launch_list().find(app_id);
   if (it == restore_data_->app_id_to_launch_list().end() ||
diff --git a/chrome/browser/chromeos/full_restore/app_launch_handler.h b/chrome/browser/chromeos/full_restore/app_launch_handler.h
index 9014b988..f77710b5 100644
--- a/chrome/browser/chromeos/full_restore/app_launch_handler.h
+++ b/chrome/browser/chromeos/full_restore/app_launch_handler.h
@@ -31,17 +31,20 @@
   // Returns true if there are some restore data. Otherwise, returns false.
   bool HasRestoreData();
 
-  void LaunchApps();
-
   // apps::AppRegistryCache::Observer:
   void OnAppUpdate(const apps::AppUpdate& update) override;
   void OnAppRegistryCacheWillBeDestroyed(
       apps::AppRegistryCache* cache) override;
 
  protected:
+  // Note: LaunchApps does not launch browser windows, this is handled
+  // separately.
+  void LaunchApps();
+
+  virtual base::WeakPtr<AppLaunchHandler> GetWeakPtrAppLaunchHandler() = 0;
+
   Profile* profile_;
   std::unique_ptr<::full_restore::RestoreData> restore_data_;
-  virtual base::WeakPtr<AppLaunchHandler> GetWeakPtrAppLaunchHandler() = 0;
 
  private:
   void LaunchApp(apps::mojom::AppType app_type, const std::string& app_id);
@@ -51,7 +54,6 @@
       const std::string& app_id,
       const ::full_restore::RestoreData::LaunchList& launch_list);
 
-  virtual void LaunchBrowser() = 0;
   virtual void RecordRestoredAppLaunch(apps::AppTypeName app_type_name) = 0;
 };
 
diff --git a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc
index 83adbbc..cc2fe4ae 100644
--- a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc
+++ b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc
@@ -65,6 +65,11 @@
 // |kCpuRestrictCoresCondition|.
 constexpr int kCpuRestrictCoresCondition = 2;
 
+constexpr char kRestoredAppWindowCountHistogram[] =
+    "Apps.RestoreArcWindowCount";
+
+constexpr char kRestoredArcAppResultHistogram[] = "Apps.RestoreArcAppsResult";
+
 constexpr char kArcGhostWindowLaunchHistogram[] = "Apps.ArcGhostWindowLaunch";
 
 }  // namespace
@@ -282,6 +287,9 @@
       }
     }
   }
+
+  base::UmaHistogramCounts100(kRestoredAppWindowCountHistogram,
+                              windows_.size() + no_stack_windows_.size());
 }
 
 void ArcAppLaunchHandler::PrepareAppLaunching(const std::string& app_id) {
@@ -359,16 +367,27 @@
 
 bool ArcAppLaunchHandler::CanLaunchApp() {
   if (should_apply_cpu_restirction_) {
-    if (GetCpuUsageRate() >= kCpuUsageThreshold)
+    int cpu_usage_rate = GetCpuUsageRate();
+    if (cpu_usage_rate >= kCpuUsageThreshold) {
+      LOG(WARNING) << "CPU usage rate is too high to restore Arc apps: "
+                   << cpu_usage_rate;
       return false;
+    }
   }
 
   switch (pressure_level_) {
     case chromeos::ResourcedClient::PressureLevel::NONE:
       return true;
     case chromeos::ResourcedClient::PressureLevel::MODERATE:
-    case chromeos::ResourcedClient::PressureLevel::CRITICAL:
+    case chromeos::ResourcedClient::PressureLevel::CRITICAL: {
+      LOG(WARNING)
+          << "Stop restoring Arc apps due to memory pressure: "
+          << (pressure_level_ ==
+                      chromeos::ResourcedClient::PressureLevel::MODERATE
+                  ? "MODERATE"
+                  : "CRITICAL");
       return false;
+    }
   }
 }
 
@@ -385,8 +404,10 @@
 }
 
 void ArcAppLaunchHandler::MaybeLaunchApp() {
-  if (!first_run_ && !CanLaunchApp())
+  if (!first_run_ && !CanLaunchApp()) {
+    MaybeReStartTimer(kAppLaunchCheckingDelay);
     return;
+  }
 
   for (auto it = pending_windows_.begin(); it != pending_windows_.end(); ++it) {
     if (IsAppReady(it->app_id)) {
@@ -574,6 +595,12 @@
   stop_restore_timer_.reset();
 
   StopCpuUsageCount();
+
+  base::UmaHistogramEnumeration(
+      kRestoredArcAppResultHistogram,
+      windows_.empty() && no_stack_windows_.empty() && pending_windows_.empty()
+          ? RestoreResult::kFinish
+          : RestoreResult::kNotFinish);
 }
 
 int ArcAppLaunchHandler::GetCpuUsageRate() {
diff --git a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h
index b01be15..f2d89e0 100644
--- a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h
+++ b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h
@@ -43,6 +43,16 @@
   }
 };
 
+// This is used for logging, so do not remove or reorder existing entries.
+enum class RestoreResult {
+  kFinish = 0,
+  kNotFinish = 1,
+
+  // Add any new values above this one, and update kMaxValue to the highest
+  // enumerator value.
+  kMaxValue = kNotFinish,
+};
+
 // The restoration process might be blocked by some issues, e.g. the memory
 // pressure, CPU rate, etc. However we don't want to have the restoration
 // process taking too long to interact the normal usage. So if the restoration
diff --git a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.h b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.h
index 75d9aca..a0f567a 100644
--- a/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.h
+++ b/chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.h
@@ -72,8 +72,11 @@
   // true, launches apps based on the restore data when apps are ready.
   void MaybeRestore();
 
+  // Goes through the normal startup browser session restore flow for launching
+  // browsers.
+  void LaunchBrowser();
+
   // AppLaunchHandler:
-  void LaunchBrowser() override;
   void RecordRestoredAppLaunch(apps::AppTypeName app_type_name) override;
 
   bool should_restore_ = false;
diff --git a/chrome/browser/chromeos/full_restore/full_restore_service.cc b/chrome/browser/chromeos/full_restore/full_restore_service.cc
index e85506010..dc2bb80 100644
--- a/chrome/browser/chromeos/full_restore/full_restore_service.cc
+++ b/chrome/browser/chromeos/full_restore/full_restore_service.cc
@@ -43,6 +43,12 @@
 const char kRestoreSettingHistogramName[] = "Apps.RestoreSetting";
 const char kRestoreInitSettingHistogramName[] = "Apps.RestoreInitSetting";
 
+constexpr char kWindowCountHistogramPrefix[] = "Apps.WindowCount.";
+constexpr char kRestoreHistogramSuffix[] = "Restore";
+constexpr char kNotRestoreHistogramSuffix[] = "NotRestore";
+constexpr char kCloseByUserHistogramSuffix[] = "CloseByUser";
+constexpr char kCloseNotByUserHistogramSuffix[] = "CloseNotByUser";
+
 // static
 FullRestoreService* FullRestoreService::GetForProfile(Profile* profile) {
   return static_cast<FullRestoreService*>(
@@ -128,6 +134,8 @@
     RecordRestoreAction(
         notification_->id(),
         by_user ? RestoreAction::kCloseByUser : RestoreAction::kCloseNotByUser);
+    RecordWindowCount(by_user ? kCloseByUserHistogramSuffix
+                              : kCloseNotByUserHistogramSuffix);
   }
 }
 void FullRestoreService::Click(const absl::optional<int>& button_index,
@@ -153,7 +161,10 @@
 
   if (button_index.value() ==
       static_cast<int>(RestoreNotificationButtonIndex::kRestore)) {
+    RecordWindowCount(kRestoreHistogramSuffix);
     Restore();
+  } else {
+    RecordWindowCount(kNotRestoreHistogramSuffix);
   }
 
   if (!is_shut_down_) {
@@ -254,6 +265,12 @@
          !::first_run::IsChromeFirstRun();
 }
 
+void FullRestoreService::RecordWindowCount(const std::string& restore_action) {
+  base::UmaHistogramCounts100(
+      kWindowCountHistogramPrefix + restore_action,
+      ::full_restore::FullRestoreSaveHandler::GetInstance()->window_count());
+}
+
 ScopedRestoreForTesting::ScopedRestoreForTesting() {
   g_restore_for_testing = false;
 }
diff --git a/chrome/browser/chromeos/full_restore/full_restore_service.h b/chrome/browser/chromeos/full_restore/full_restore_service.h
index 1c8d0b68..0464c93 100644
--- a/chrome/browser/chromeos/full_restore/full_restore_service.h
+++ b/chrome/browser/chromeos/full_restore/full_restore_service.h
@@ -93,6 +93,10 @@
   // Chrome is run. Otherwise, returns false.
   bool ShouldShowNotification();
 
+  // Records the new window count when the user takes action on the full restore
+  // notification.
+  void RecordWindowCount(const std::string& restore_action);
+
   Profile* profile_ = nullptr;
   PrefChangeRegistrar pref_change_registrar_;
 
diff --git a/chrome/browser/chromeos/input_method/grammar_manager.cc b/chrome/browser/chromeos/input_method/grammar_manager.cc
index 4c11785..9cd060a 100644
--- a/chrome/browser/chromeos/input_method/grammar_manager.cc
+++ b/chrome/browser/chromeos/input_method/grammar_manager.cc
@@ -23,7 +23,7 @@
 using text_utils::FindLastSentence;
 using text_utils::Sentence;
 
-constexpr base::TimeDelta kCheckDelay = base::TimeDelta::FromMilliseconds(500);
+constexpr base::TimeDelta kCheckDelay = base::TimeDelta::FromSeconds(2);
 
 void RecordGrammarAction(GrammarActions action) {
   base::UmaHistogramEnumeration("InputMethod.Assistive.Grammar.Actions",
@@ -69,6 +69,7 @@
   if (context_id != context_id_) {
     last_text_ = u"";
     last_sentence_ = Sentence();
+    new_to_context_ = true;
   }
   context_id_ = context_id;
   text_input_flags_ = text_input_flags;
@@ -130,21 +131,33 @@
   if (suggestion_shown_)
     DismissSuggestion();
 
-  if (text != last_text_) {
-    last_text_ = text;
+  bool text_updated = text != last_text_;
+  last_text_ = text;
+
+  if (new_to_context_) {
+    new_to_context_ = false;
+  } else if (text_updated) {
+    ui::IMEInputContextHandlerInterface* input_context =
+        ui::IMEBridge::Get()->GetInputContextHandler();
+    if (!input_context)
+      return;
 
     // Grammar check is cpu consuming, so we only send request to ml service
     // when the user has finished a sentence or stopped typing for some time.
     Sentence last_sentence = FindLastSentence(text, cursor_pos);
     if (last_sentence_ != last_sentence) {
       last_sentence_ = last_sentence;
+      input_context->ClearGrammarFragments(last_sentence.original_range);
       Check(last_sentence);
     }
 
+    Sentence current_sentence = FindCurrentSentence(text, cursor_pos);
+    input_context->ClearGrammarFragments(current_sentence.original_range);
+
     delay_timer_.Start(
         FROM_HERE, kCheckDelay,
         base::BindOnce(&GrammarManager::Check, base::Unretained(this),
-                       FindCurrentSentence(text, cursor_pos)));
+                       current_sentence));
     return;
   }
 
@@ -185,13 +198,6 @@
   if (!IsValidSentence(last_text_, sentence))
     return;
 
-  ui::IMEInputContextHandlerInterface* input_context =
-      ui::IMEBridge::Get()->GetInputContextHandler();
-  if (!input_context)
-    return;
-
-  input_context->ClearGrammarFragments(sentence.original_range);
-
   grammar_client_->RequestTextCheck(
       profile_, sentence.text,
       base::BindOnce(&GrammarManager::OnGrammarCheckDone,
diff --git a/chrome/browser/chromeos/input_method/grammar_manager.h b/chrome/browser/chromeos/input_method/grammar_manager.h
index 51b6172e..cf8f3370 100644
--- a/chrome/browser/chromeos/input_method/grammar_manager.h
+++ b/chrome/browser/chromeos/input_method/grammar_manager.h
@@ -81,6 +81,7 @@
   std::unique_ptr<GrammarServiceClient> grammar_client_;
   SuggestionHandlerInterface* suggestion_handler_;
   int context_id_ = 0;
+  bool new_to_context_ = true;
   std::u16string last_text_;
   base::OneShotTimer delay_timer_;
   ui::GrammarFragment current_fragment_;
diff --git a/chrome/browser/chromeos/input_method/grammar_manager_unittest.cc b/chrome/browser/chromeos/input_method/grammar_manager_unittest.cc
index 3db77f5..4fd5945 100644
--- a/chrome/browser/chromeos/input_method/grammar_manager_unittest.cc
+++ b/chrome/browser/chromeos/input_method/grammar_manager_unittest.cc
@@ -121,8 +121,9 @@
   base::HistogramTester histogram_tester;
 
   manager.OnFocus(1, /*text_input_flags=*/0);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   auto grammar_fragments =
       mock_ime_input_context_handler_.get_grammar_fragments();
@@ -141,8 +142,9 @@
   base::HistogramTester histogram_tester;
 
   manager.OnFocus(1, ui::TEXT_INPUT_FLAG_SPELLCHECK_OFF);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   auto grammar_fragments =
       mock_ime_input_context_handler_.get_grammar_fragments();
@@ -158,9 +160,10 @@
                          &mock_suggestion_handler);
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error. And another error.", 20,
                                    20);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(100));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(250));
 
   auto grammar_fragments =
       mock_ime_input_context_handler_.get_grammar_fragments();
@@ -176,9 +179,10 @@
                          &mock_suggestion_handler);
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error. And another error.", 20,
                                    20);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   auto grammar_fragments =
       mock_ime_input_context_handler_.get_grammar_fragments();
@@ -196,8 +200,9 @@
                          &mock_suggestion_handler);
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   auto grammar_fragments =
       mock_ime_input_context_handler_.get_grammar_fragments();
@@ -215,8 +220,9 @@
                          &mock_suggestion_handler);
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   auto grammar_fragments =
       mock_ime_input_context_handler_.get_grammar_fragments();
@@ -225,7 +231,7 @@
   EXPECT_EQ(grammar_fragments[0].suggestion, "correct");
 
   manager.OnSurroundingTextChanged(u"There is a new error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   auto updated_grammar_fragments =
       mock_ime_input_context_handler_.get_grammar_fragments();
@@ -242,8 +248,9 @@
   base::HistogramTester histogram_tester;
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   AssistiveWindowProperties expected_properties;
   expected_properties.type = ui::ime::AssistiveWindowType::kGrammarSuggestion;
@@ -269,8 +276,9 @@
                          &mock_suggestion_handler);
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   AssistiveWindowProperties expected_properties;
   expected_properties.type = ui::ime::AssistiveWindowType::kGrammarSuggestion;
@@ -297,8 +305,9 @@
   mock_ime_input_context_handler_.Reset();
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   EXPECT_CALL(mock_suggestion_handler, SetAssistiveWindowProperties(1, _, _));
   manager.OnSurroundingTextChanged(u"There is error.", 10, 10);
@@ -336,8 +345,9 @@
   mock_ime_input_context_handler_.Reset();
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   EXPECT_CALL(mock_suggestion_handler, SetAssistiveWindowProperties(1, _, _));
   manager.OnSurroundingTextChanged(u"There is error.", 10, 10);
@@ -375,8 +385,9 @@
   mock_ime_input_context_handler_.Reset();
 
   manager.OnFocus(1);
+  manager.OnSurroundingTextChanged(u"", 0, 0);
   manager.OnSurroundingTextChanged(u"There is error.", 0, 0);
-  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(1000));
+  task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(2500));
 
   EXPECT_EQ(mock_ime_input_context_handler_.get_grammar_fragments().size(), 1);
   EXPECT_CALL(mock_suggestion_handler, SetAssistiveWindowProperties(1, _, _));
diff --git a/chrome/browser/chromeos/printing/usb_printer_util.cc b/chrome/browser/chromeos/printing/usb_printer_util.cc
index 3908bcfa..0ba5ac2 100644
--- a/chrome/browser/chromeos/printing/usb_printer_util.cc
+++ b/chrome/browser/chromeos/printing/usb_printer_util.cc
@@ -14,6 +14,7 @@
 
 #include "base/big_endian.h"
 #include "base/callback_helpers.h"
+#include "base/containers/span.h"
 #include "base/hash/md5.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
@@ -55,7 +56,7 @@
 void OnControlTransfer(mojo::Remote<device::mojom::UsbDevice> device,
                        GetDeviceIdCallback cb,
                        device::mojom::UsbTransferStatus status,
-                       const std::vector<uint8_t>& data) {
+                       base::span<const uint8_t> data) {
   if (status != device::mojom::UsbTransferStatus::COMPLETED || data.empty()) {
     return std::move(cb).Run({});
   }
diff --git a/chrome/browser/content_settings/sound_content_setting_observer_browsertest.cc b/chrome/browser/content_settings/sound_content_setting_observer_browsertest.cc
index 990a6814..5132d9b 100644
--- a/chrome/browser/content_settings/sound_content_setting_observer_browsertest.cc
+++ b/chrome/browser/content_settings/sound_content_setting_observer_browsertest.cc
@@ -244,8 +244,9 @@
 // SoundContentSettingObserver::ReadyToCommitNavigation() with NavigationHandle
 // URL, it uses a page that has a sub frame to make sure that it's called with
 // the correct URL.
+// Flaky crashes. https://crbug.com/1228609
 IN_PROC_BROWSER_TEST_F(SoundContentSettingObserverBrowserTest,
-                       AddAutoplayFlagsInPrerendering) {
+                       DISABLED_AddAutoplayFlagsInPrerendering) {
   // Sets up the embedded test server to serve the test javascript file.
   net::test_server::EmbeddedTestServerHandle test_server_handle;
   ASSERT_TRUE(test_server_handle =
diff --git a/chrome/browser/devtools/device/devtools_android_bridge_browsertest.cc b/chrome/browser/devtools/device/devtools_android_bridge_browsertest.cc
index 30ae2f7a0..fdebfa3 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge_browsertest.cc
+++ b/chrome/browser/devtools/device/devtools_android_bridge_browsertest.cc
@@ -75,7 +75,7 @@
   EXPECT_STREQ("somehost:2000", AllTargetsString(provider).c_str());
 
   invocations = called;
-  list.Clear();
+  list.ClearList();
   service->Set(prefs::kDevToolsTCPDiscoveryConfig, list);
 
   EXPECT_LT(invocations, called);
diff --git a/chrome/browser/devtools/device/usb/android_usb_device.cc b/chrome/browser/devtools/device/usb/android_usb_device.cc
index 6023d1c..cc953bb 100644
--- a/chrome/browser/devtools/device/usb/android_usb_device.cc
+++ b/chrome/browser/devtools/device/usb/android_usb_device.cc
@@ -334,7 +334,7 @@
 }
 
 void AndroidUsbDevice::ParseHeader(UsbTransferStatus status,
-                                   const std::vector<uint8_t>& buffer) {
+                                   base::span<const uint8_t> buffer) {
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   if (status == UsbTransferStatus::TIMEOUT) {
@@ -390,7 +390,7 @@
                                  uint32_t data_length,
                                  uint32_t data_check,
                                  UsbTransferStatus status,
-                                 const std::vector<uint8_t>& buffer) {
+                                 base::span<const uint8_t> buffer) {
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   if (status == UsbTransferStatus::TIMEOUT) {
diff --git a/chrome/browser/devtools/device/usb/android_usb_device.h b/chrome/browser/devtools/device/usb/android_usb_device.h
index e69c9f7..a93dd6b1 100644
--- a/chrome/browser/devtools/device/usb/android_usb_device.h
+++ b/chrome/browser/devtools/device/usb/android_usb_device.h
@@ -14,6 +14,7 @@
 #include <vector>
 
 #include "base/containers/queue.h"
+#include "base/containers/span.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
@@ -110,7 +111,7 @@
 
   void ReadHeader();
   void ParseHeader(device::mojom::UsbTransferStatus status,
-                   const std::vector<uint8_t>& buffer);
+                   base::span<const uint8_t> buffer);
 
   void ReadBody(std::unique_ptr<AdbMessage> message,
                 uint32_t data_length,
@@ -119,7 +120,7 @@
                  uint32_t data_length,
                  uint32_t data_check,
                  device::mojom::UsbTransferStatus status,
-                 const std::vector<uint8_t>& buffer);
+                 base::span<const uint8_t> buffer);
 
   void HandleIncoming(std::unique_ptr<AdbMessage> message);
 
diff --git a/chrome/browser/download/internal/android/java/res/layout/download_manager_audio.xml b/chrome/browser/download/internal/android/java/res/layout/download_manager_audio.xml
index f5929ee..6c21ec28 100644
--- a/chrome/browser/download/internal/android/java/res/layout/download_manager_audio.xml
+++ b/chrome/browser/download/internal/android/java/res/layout/download_manager_audio.xml
@@ -4,95 +4,102 @@
      found in the LICENSE file.
 -->
 
-<RelativeLayout
+<org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="114dp"
-    android:background="@drawable/hairline_border_card_background">
+    style="@style/MaterialCardStyle">
 
-    <org.chromium.components.browser_ui.widget.async_image.AsyncImageView
-        android:id="@+id/thumbnail"
-        android:layout_width="80dp"
-        android:layout_height="80dp"
-        android:layout_marginEnd="8dp"
-        android:layout_marginTop="16dp"
-        android:layout_marginBottom="16dp"
-        android:layout_marginStart="16dp"
-        android:scaleType="centerCrop"
-        app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
-        app:cornerRadiusTopEnd="@dimen/download_manager_thumbnail_corner_radius"
-        app:cornerRadiusBottomStart="@dimen/download_manager_thumbnail_corner_radius"
-        app:cornerRadiusBottomEnd="@dimen/download_manager_thumbnail_corner_radius"
-        style="@style/AsyncImageView"
-        tools:ignore="ContentDescription" />
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
 
-    <include layout="@layout/list_menu_button"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:layout_alignTop="@id/thumbnail"
-        android:layout_alignParentEnd="true"
-        android:paddingTop="12dp" />
+        <org.chromium.components.browser_ui.widget.async_image.AsyncImageView
+            android:id="@+id/thumbnail"
+            android:layout_width="80dp"
+            android:layout_height="80dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginTop="16dp"
+            android:layout_marginBottom="16dp"
+            android:layout_marginStart="16dp"
+            android:scaleType="centerCrop"
+            app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
+            app:cornerRadiusTopEnd="@dimen/download_manager_thumbnail_corner_radius"
+            app:cornerRadiusBottomStart="@dimen/download_manager_thumbnail_corner_radius"
+            app:cornerRadiusBottomEnd="@dimen/download_manager_thumbnail_corner_radius"
+            style="@style/AsyncImageView"
+            tools:ignore="ContentDescription" />
 
-    <TextView
-        android:id="@+id/title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toEndOf="@id/thumbnail"
-        android:layout_toStartOf="@+id/more"
-        android:layout_marginStart="16dp"
-        android:layout_alignTop="@id/thumbnail"
-        android:minHeight="40dp"
-        android:maxLines="2"
-        android:ellipsize="end"
-        android:textAppearance="@style/TextAppearance.TextLarge.Primary"
-        android:textAlignment="viewStart"
-        app:layout_gravity="fill_horizontal" />
+        <include layout="@layout/list_menu_button"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:layout_alignTop="@id/thumbnail"
+            android:layout_alignParentEnd="true"
+            android:paddingTop="12dp" />
 
-    <TextView
-        android:id="@+id/timestamp"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toEndOf="@id/thumbnail"
-        android:layout_alignBottom="@id/thumbnail"
-        android:layout_marginStart="16dp"
-        android:maxLines="1"
-        android:ellipsize="end"
-        android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
-        android:textAlignment="viewStart" />
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toEndOf="@id/thumbnail"
+            android:layout_toStartOf="@+id/more"
+            android:layout_marginStart="16dp"
+            android:layout_alignTop="@id/thumbnail"
+            android:minHeight="40dp"
+            android:maxLines="2"
+            android:ellipsize="end"
+            android:textAppearance="@style/TextAppearance.TextLarge.Primary"
+            android:textAlignment="viewStart"
+            app:layout_gravity="fill_horizontal" />
 
-    <org.chromium.ui.widget.ChromeImageView
-        android:id="@+id/media_button"
-        style="@style/InlineOfflineIconStyle"
-        android:layout_alignBottom="@id/timestamp"
-        android:layout_toEndOf="@id/timestamp"
-        tools:ignore="ContentDescription" />
+        <TextView
+            android:id="@+id/timestamp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toEndOf="@id/thumbnail"
+            android:layout_alignBottom="@id/thumbnail"
+            android:layout_marginStart="16dp"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
+            android:textAlignment="viewStart" />
 
-    <TextView
-        android:id="@+id/caption"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toEndOf="@id/thumbnail"
-        android:layout_above="@id/timestamp"
-        android:layout_marginStart="16dp"
-        android:maxLines="1"
-        android:ellipsize="end"
-        android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
-        android:textAlignment="viewStart" />
+        <org.chromium.ui.widget.ChromeImageView
+            android:id="@+id/media_button"
+            style="@style/InlineOfflineIconStyle"
+            android:layout_alignBottom="@id/timestamp"
+            android:layout_toEndOf="@id/timestamp"
+            tools:ignore="ContentDescription" />
 
-    <!-- Wrap this in a FrameLayout so that if the thumbnail is hidden this view
-         does not negatively affect layout.  The FrameLayout spans the whole
-         parent so it will not impact the rest of the views. -->
-    <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_gravity="fill">
-        <org.chromium.chrome.browser.download.home.view.SelectionView
-            android:id="@+id/selection"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:layout_marginTop="24dp"
-            android:layout_marginStart="24dp"/>
-    </FrameLayout>
-</RelativeLayout>
+        <TextView
+            android:id="@+id/caption"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toEndOf="@id/thumbnail"
+            android:layout_above="@id/timestamp"
+            android:layout_marginStart="16dp"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
+            android:textAlignment="viewStart" />
+
+        <!-- Wrap this in a FrameLayout so that if the thumbnail is hidden this view
+             does not negatively affect layout.  The FrameLayout spans the whole
+             parent so it will not impact the rest of the views. -->
+        <FrameLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_gravity="fill">
+            <org.chromium.chrome.browser.download.home.view.SelectionView
+                android:id="@+id/selection"
+                android:layout_width="24dp"
+                android:layout_height="24dp"
+                android:layout_marginTop="24dp"
+                android:layout_marginStart="24dp"/>
+        </FrameLayout>
+
+    </RelativeLayout>
+
+</org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow>
diff --git a/chrome/browser/download/internal/android/java/res/layout/download_manager_in_progress_video_item.xml b/chrome/browser/download/internal/android/java/res/layout/download_manager_in_progress_video_item.xml
index 4be3f045..e2e8eb0 100644
--- a/chrome/browser/download/internal/android/java/res/layout/download_manager_in_progress_video_item.xml
+++ b/chrome/browser/download/internal/android/java/res/layout/download_manager_in_progress_video_item.xml
@@ -4,82 +4,88 @@
      found in the LICENSE file.
 -->
 
-<androidx.gridlayout.widget.GridLayout
+<org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:clickable="true"
-    android:focusable="true"
-    android:background="@drawable/hairline_border_card_background"
-    app:columnCount="1"
-    app:rowCount="2">
+    style="@style/MaterialCardStyle">
 
-    <!-- Set the src attribute in Java to wrap the drawable properly. -->
-    <org.chromium.components.browser_ui.widget.async_image.ForegroundRoundedCornerImageView
-        android:id="@+id/thumbnail"
-        android:layout_width="match_parent"
-        android:layout_height="200dp"
-        android:layout_marginTop="1dp"
-        android:layout_marginStart="1dp"
-        android:layout_marginEnd="1dp"
-        android:scaleType="centerInside"
-        android:adjustViewBounds="true"
-        app:layout_column="0"
-        app:layout_row="0"
-        app:layout_gravity="center"
-        app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
-        app:cornerRadiusTopEnd="@dimen/download_manager_thumbnail_corner_radius"
-        app:roundedfillColor="@color/modern_grey_300"
-        app:foregroundCompat="@drawable/async_image_view_waiting" />
-
-    <org.chromium.chrome.browser.download.home.list.view.CircularProgressView
-        android:id="@+id/action_button"
-        app:layout_column="0"
-        app:layout_row="0"
-        app:layout_gravity="center"
-        style="@style/LargeCircularProgress" />
-
-    <LinearLayout
+    <androidx.gridlayout.widget.GridLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:baselineAligned="false"
-        app:layout_column="0"
-        app:layout_row="1">
+        android:clickable="true"
+        android:focusable="true"
+        app:columnCount="1"
+        app:rowCount="2">
+
+        <!-- Set the src attribute in Java to wrap the drawable properly. -->
+        <org.chromium.components.browser_ui.widget.async_image.ForegroundRoundedCornerImageView
+            android:id="@+id/thumbnail"
+            android:layout_width="match_parent"
+            android:layout_height="200dp"
+            android:layout_marginTop="1dp"
+            android:layout_marginStart="1dp"
+            android:layout_marginEnd="1dp"
+            android:scaleType="centerInside"
+            android:adjustViewBounds="true"
+            app:layout_column="0"
+            app:layout_row="0"
+            app:layout_gravity="center"
+            app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
+            app:cornerRadiusTopEnd="@dimen/download_manager_thumbnail_corner_radius"
+            app:roundedfillColor="@color/modern_grey_300"
+            app:foregroundCompat="@drawable/async_image_view_waiting" />
+
+        <org.chromium.chrome.browser.download.home.list.view.CircularProgressView
+            android:id="@+id/action_button"
+            app:layout_column="0"
+            app:layout_row="0"
+            app:layout_gravity="center"
+            style="@style/LargeCircularProgress" />
 
         <LinearLayout
-            android:layout_width="0dp"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:layout_marginStart="16dp"
-            android:layout_weight="1">
-            <TextView
-                android:id="@+id/title"
-                style="@style/DownloadItemText"
-                android:layout_width="match_parent"
-                android:layout_marginTop="11dp"
-                android:textAppearance="@style/TextAppearance.TextLarge.Primary" />
+            android:orientation="horizontal"
+            android:baselineAligned="false"
+            app:layout_column="0"
+            app:layout_row="1">
 
-            <TextView
-                android:id="@+id/caption"
-                style="@style/DownloadItemText"
-                android:layout_width="match_parent"
-                android:layout_marginBottom="11dp"
-                android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:layout_marginStart="16dp"
+                android:layout_weight="1">
+                <TextView
+                    android:id="@+id/title"
+                    style="@style/DownloadItemText"
+                    android:layout_width="match_parent"
+                    android:layout_marginTop="11dp"
+                    android:textAppearance="@style/TextAppearance.TextLarge.Primary" />
+
+                <TextView
+                    android:id="@+id/caption"
+                    style="@style/DownloadItemText"
+                    android:layout_width="match_parent"
+                    android:layout_marginBottom="11dp"
+                    android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
+
+            </LinearLayout>
+
+            <org.chromium.ui.widget.ChromeImageButton
+                android:id="@+id/cancel_button"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:layout_weight="0"
+                android:background="?attr/selectableItemBackground"
+                android:contentDescription="@string/download_notification_cancel_button"
+                android:src="@drawable/btn_close"
+                app:tint="@color/default_icon_color" />
 
         </LinearLayout>
 
-        <org.chromium.ui.widget.ChromeImageButton
-            android:id="@+id/cancel_button"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:layout_weight="0"
-            android:background="?attr/selectableItemBackground"
-            android:contentDescription="@string/download_notification_cancel_button"
-            android:src="@drawable/btn_close"
-            app:tint="@color/default_icon_color" />
+    </androidx.gridlayout.widget.GridLayout>
 
-    </LinearLayout>
-
-</androidx.gridlayout.widget.GridLayout>
+</org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow>
diff --git a/chrome/browser/download/internal/android/java/res/layout/download_manager_prefetch_article.xml b/chrome/browser/download/internal/android/java/res/layout/download_manager_prefetch_article.xml
index 586e3d0..4aa8d4c 100644
--- a/chrome/browser/download/internal/android/java/res/layout/download_manager_prefetch_article.xml
+++ b/chrome/browser/download/internal/android/java/res/layout/download_manager_prefetch_article.xml
@@ -4,125 +4,130 @@
      found in the LICENSE file.
 -->
 
-<androidx.gridlayout.widget.GridLayout
+<org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="114dp"
-    android:background="@drawable/hairline_border_card_background"
-    android:clickable="true"
-    android:focusable="true"
-    app:columnCount="4"
-    app:rowCount="4">
+    style="@style/MaterialCardStyle">
 
-    <org.chromium.components.browser_ui.widget.async_image.AsyncImageView
-        android:id="@+id/thumbnail"
-        android:layout_width="113dp"
-        android:layout_height="112dp"
-        android:layout_marginEnd="9dp"
-        android:layout_marginTop="1dp"
-        android:layout_marginBottom="1dp"
-        android:layout_marginStart="1dp"
-        android:scaleType="centerCrop"
-        app:layout_column="0"
-        app:layout_row="0"
-        app:layout_rowSpan="4"
-        app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
-        app:cornerRadiusBottomStart="@dimen/download_manager_thumbnail_corner_radius"
-        style="@style/AsyncImageView"
-        tools:ignore="ContentDescription" />
+    <androidx.gridlayout.widget.GridLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clickable="true"
+        android:focusable="true"
+        app:columnCount="4"
+        app:rowCount="4">
 
-    <!-- Add a spacer so that even if the thumbnail is hidden the other elements
-         are still spaced correctly.  This view matches the padding of the
-         thumbnail. -->
-    <Space
-        android:layout_width="10dp"
-        android:layout_height="114dp"
-        app:layout_column="0"
-        app:layout_row="0"
-        app:layout_rowSpan="4" />
+        <org.chromium.components.browser_ui.widget.async_image.AsyncImageView
+            android:id="@+id/thumbnail"
+            android:layout_width="113dp"
+            android:layout_height="112dp"
+            android:layout_marginEnd="9dp"
+            android:layout_marginTop="1dp"
+            android:layout_marginBottom="1dp"
+            android:layout_marginStart="1dp"
+            android:scaleType="centerCrop"
+            app:layout_column="0"
+            app:layout_row="0"
+            app:layout_rowSpan="4"
+            app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
+            app:cornerRadiusBottomStart="@dimen/download_manager_thumbnail_corner_radius"
+            style="@style/AsyncImageView"
+            tools:ignore="ContentDescription" />
 
-    <Space
-        android:layout_width="wrap_content"
-        android:layout_height="0dp"
-        app:layout_gravity="fill"
-        app:layout_column="0"
-        app:layout_row="3"
-        app:layout_columnSpan="4" />
+        <!-- Add a spacer so that even if the thumbnail is hidden the other elements
+             are still spaced correctly.  This view matches the padding of the
+             thumbnail. -->
+        <Space
+            android:layout_width="10dp"
+            android:layout_height="114dp"
+            app:layout_column="0"
+            app:layout_row="0"
+            app:layout_rowSpan="4" />
 
-    <org.chromium.ui.widget.TextViewWithLeading
-        android:id="@+id/title"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="12dp"
-        android:minHeight="40dp"
-        android:maxLines="2"
-        android:ellipsize="end"
-        android:textAppearance="@style/TextAppearance.TextLarge.Primary"
-        android:textAlignment="viewStart"
-        app:leading="@dimen/text_size_large_leading"
-        app:layout_column="1"
-        app:layout_row="0"
-        app:layout_columnSpan="2"
-        app:layout_gravity="fill_horizontal"/>
+        <Space
+            android:layout_width="wrap_content"
+            android:layout_height="0dp"
+            app:layout_gravity="fill"
+            app:layout_column="0"
+            app:layout_row="3"
+            app:layout_columnSpan="4" />
 
-    <TextView
-        android:id="@+id/caption"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="8dp"
-        android:layout_marginBottom="8dp"
-        android:maxLines="1"
-        android:ellipsize="end"
-        android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
-        android:textAlignment="viewStart"
-        app:layout_column="1"
-        app:layout_row="1"
-        app:layout_columnSpan="3"
-        app:layout_gravity="fill_horizontal" />
+        <org.chromium.ui.widget.TextViewWithLeading
+            android:id="@+id/title"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            android:minHeight="40dp"
+            android:maxLines="2"
+            android:ellipsize="end"
+            android:textAppearance="@style/TextAppearance.TextLarge.Primary"
+            android:textAlignment="viewStart"
+            app:leading="@dimen/text_size_large_leading"
+            app:layout_column="1"
+            app:layout_row="0"
+            app:layout_columnSpan="2"
+            app:layout_gravity="fill_horizontal"/>
 
-    <TextView
-        android:id="@+id/timestamp"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:maxLines="1"
-        android:ellipsize="end"
-        android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
-        android:textAlignment="viewStart"
-        app:layout_column="1"
-        app:layout_row="2"
-        app:layout_gravity="center_vertical" />
+        <TextView
+            android:id="@+id/caption"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:layout_marginBottom="8dp"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
+            android:textAlignment="viewStart"
+            app:layout_column="1"
+            app:layout_row="1"
+            app:layout_columnSpan="3"
+            app:layout_gravity="fill_horizontal" />
 
-    <ImageView
-        style="@style/InlineOfflineIconStyle"
-        app:srcCompat="@drawable/ic_offline_pin_24dp"
-        app:layout_column="2"
-        app:layout_row="2"
-        app:layout_columnSpan="2"
-        app:layout_gravity="start|center_vertical"
-        tools:ignore="ContentDescription" />
+        <TextView
+            android:id="@+id/timestamp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:maxLines="1"
+            android:ellipsize="end"
+            android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
+            android:textAlignment="viewStart"
+            app:layout_column="1"
+            app:layout_row="2"
+            app:layout_gravity="center_vertical" />
 
-    <include layout="@layout/list_menu_button"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:paddingTop="12dp"
-        app:layout_column="3"
-        app:layout_row="0" />
+        <ImageView
+            style="@style/InlineOfflineIconStyle"
+            app:srcCompat="@drawable/ic_offline_pin_24dp"
+            app:layout_column="2"
+            app:layout_row="2"
+            app:layout_columnSpan="2"
+            app:layout_gravity="start|center_vertical"
+            tools:ignore="ContentDescription" />
 
-    <!-- Wrap this in a FrameLayout so that if the thumbnail is hidden this view
-         does not negatively affect layout.  The FrameLayout spans the whole
-         parent so it will not impact the rest of the views. -->
-    <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="0dp"
-        app:layout_gravity="fill"
-        app:layout_column="0"
-        app:layout_row="0"
-        app:layout_columnSpan="4"
-        app:layout_rowSpan="4">
-        <org.chromium.chrome.browser.download.home.view.SelectionView
-            android:id="@+id/selection"
-            style="@style/DownloadItemSelectionView"/>
-    </FrameLayout>
-</androidx.gridlayout.widget.GridLayout>
+        <include layout="@layout/list_menu_button"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:paddingTop="12dp"
+            app:layout_column="3"
+            app:layout_row="0" />
+
+        <!-- Wrap this in a FrameLayout so that if the thumbnail is hidden this view
+             does not negatively affect layout.  The FrameLayout spans the whole
+             parent so it will not impact the rest of the views. -->
+        <FrameLayout
+            android:layout_width="wrap_content"
+            android:layout_height="0dp"
+            app:layout_gravity="fill"
+            app:layout_column="0"
+            app:layout_row="0"
+            app:layout_columnSpan="4"
+            app:layout_rowSpan="4">
+            <org.chromium.chrome.browser.download.home.view.SelectionView
+                android:id="@+id/selection"
+                style="@style/DownloadItemSelectionView"/>
+        </FrameLayout>
+    </androidx.gridlayout.widget.GridLayout>
+</org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow>
diff --git a/chrome/browser/download/internal/android/java/res/layout/download_manager_video_item.xml b/chrome/browser/download/internal/android/java/res/layout/download_manager_video_item.xml
index cefe0e9..9bd7fbb 100644
--- a/chrome/browser/download/internal/android/java/res/layout/download_manager_video_item.xml
+++ b/chrome/browser/download/internal/android/java/res/layout/download_manager_video_item.xml
@@ -4,83 +4,89 @@
      found in the LICENSE file.
 -->
 
- <androidx.gridlayout.widget.GridLayout
+<org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:clickable="true"
-    android:focusable="true"
-    android:background="@drawable/hairline_border_card_background"
-    app:columnCount="1"
-    app:rowCount="2">
+    style="@style/MaterialCardStyle">
 
-    <org.chromium.components.browser_ui.widget.async_image.AsyncImageView
-        android:id="@+id/thumbnail"
-        android:layout_width="match_parent"
-        android:layout_height="200dp"
-        android:layout_marginTop="1dp"
-        android:layout_marginStart="1dp"
-        android:layout_marginEnd="1dp"
-        android:scaleType="centerCrop"
-        android:adjustViewBounds="true"
-        app:layout_column="0"
-        app:layout_row="0"
-        app:layout_gravity="center"
-        app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
-        app:cornerRadiusTopEnd="@dimen/download_manager_thumbnail_corner_radius"
-        app:roundedfillColor="@color/modern_grey_300"/>
-
-    <org.chromium.ui.widget.ChromeImageButton
-        android:id="@+id/action_button"
-        app:layout_column="0"
-        app:layout_row="0"
-        app:layout_gravity="center"
-        android:elevation="2dp"
-        android:clickable="false"
-        style="@style/LargeMediaPlayButton"/>
-
-   <org.chromium.chrome.browser.download.home.view.SelectionView
-       android:id="@+id/selection"
-       style="@style/DownloadItemSelectionView"
-       app:layout_column="0"
-       app:layout_row="0" />
-
-    <LinearLayout
+    <androidx.gridlayout.widget.GridLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:baselineAligned="false"
-        app:layout_column="0"
-        app:layout_row="1">
+        android:clickable="true"
+        android:focusable="true"
+        app:columnCount="1"
+        app:rowCount="2">
+
+        <org.chromium.components.browser_ui.widget.async_image.AsyncImageView
+            android:id="@+id/thumbnail"
+            android:layout_width="match_parent"
+            android:layout_height="200dp"
+            android:layout_marginTop="1dp"
+            android:layout_marginStart="1dp"
+            android:layout_marginEnd="1dp"
+            android:scaleType="centerCrop"
+            android:adjustViewBounds="true"
+            app:layout_column="0"
+            app:layout_row="0"
+            app:layout_gravity="center"
+            app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
+            app:cornerRadiusTopEnd="@dimen/download_manager_thumbnail_corner_radius"
+            app:roundedfillColor="@color/modern_grey_300"/>
+
+        <org.chromium.ui.widget.ChromeImageButton
+            android:id="@+id/action_button"
+            app:layout_column="0"
+            app:layout_row="0"
+            app:layout_gravity="center"
+            android:elevation="2dp"
+            android:clickable="false"
+            style="@style/LargeMediaPlayButton"/>
+
+       <org.chromium.chrome.browser.download.home.view.SelectionView
+           android:id="@+id/selection"
+           style="@style/DownloadItemSelectionView"
+           app:layout_column="0"
+           app:layout_row="0" />
 
         <LinearLayout
-            android:layout_width="0dp"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:layout_marginStart="16dp"
-            android:layout_weight="1">
-            <TextView
-                android:id="@+id/title"
-                style="@style/DownloadItemText"
-                android:layout_width="match_parent"
-                android:layout_marginTop="11dp"
-                android:textAppearance="@style/TextAppearance.TextLarge.Primary" />
+            android:orientation="horizontal"
+            android:baselineAligned="false"
+            app:layout_column="0"
+            app:layout_row="1">
 
-            <TextView
-                android:id="@+id/caption"
-                style="@style/DownloadItemText"
-                android:layout_width="match_parent"
-                android:layout_marginBottom="11dp"
-                android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:layout_marginStart="16dp"
+                android:layout_weight="1">
+                <TextView
+                    android:id="@+id/title"
+                    style="@style/DownloadItemText"
+                    android:layout_width="match_parent"
+                    android:layout_marginTop="11dp"
+                    android:textAppearance="@style/TextAppearance.TextLarge.Primary" />
+
+                <TextView
+                    android:id="@+id/caption"
+                    style="@style/DownloadItemText"
+                    android:layout_width="match_parent"
+                    android:layout_marginBottom="11dp"
+                    android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
+            </LinearLayout>
+
+            <include layout="@layout/list_menu_button"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:layout_weight="0" />
+
         </LinearLayout>
 
-        <include layout="@layout/list_menu_button"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:layout_weight="0" />
+    </androidx.gridlayout.widget.GridLayout>
 
-    </LinearLayout>
-
-</androidx.gridlayout.widget.GridLayout>
+</org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow>
diff --git a/chrome/browser/download/internal/android/java/res/layout/downloads_empty_view.xml b/chrome/browser/download/internal/android/java/res/layout/downloads_empty_view.xml
index a4127bd..f163316 100644
--- a/chrome/browser/download/internal/android/java/res/layout/downloads_empty_view.xml
+++ b/chrome/browser/download/internal/android/java/res/layout/downloads_empty_view.xml
@@ -8,15 +8,15 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent" >
 
-    <FrameLayout
-        style="@style/Card"
+    <org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow
         android:id="@+id/empty_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/default_list_row_padding"
         android:layout_marginStart="@dimen/default_list_row_padding"
         android:gravity="center"
-        android:padding="@dimen/card_padding" >
+        android:padding="@dimen/card_padding"
+        style="@style/MaterialCardStyle">
 
         <org.chromium.ui.widget.TextViewWithLeading
             android:id="@+id/empty"
@@ -26,7 +26,7 @@
             android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
             app:leading="@dimen/text_size_medium_leading"/>
 
-    </FrameLayout>
+    </org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow>
 
     <org.chromium.ui.widget.LoadingView
         android:id="@+id/loading"
diff --git a/chrome/browser/engagement/important_sites_util.cc b/chrome/browser/engagement/important_sites_util.cc
index e89f28ad..b400b551 100644
--- a/chrome/browser/engagement/important_sites_util.cc
+++ b/chrome/browser/engagement/important_sites_util.cc
@@ -372,9 +372,9 @@
       service->GetAllDetailsEngagedInTimePeriod(time_period);
   std::set<GURL> content_origins;
 
-  // Check with AppRegistrar to make sure the apps have not yet been
+  // Check with WebAppRegistrar to make sure the apps have not yet been
   // uninstalled.
-  const web_app::AppRegistrar& registrar =
+  const web_app::WebAppRegistrar& registrar =
       web_app::WebAppProvider::Get(profile)->registrar();
   auto app_ids = registrar.GetAppIds();
   std::map<std::string, std::string> installed_origins_map;
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
index 8f48416..41fe37b 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -505,7 +505,7 @@
   base::FilePath expected_file_path =
       data_dir().AppendASCII("simple_with_popup.pem");
   api::EntryPicker::SkipPickerAndAlwaysSelectPathForTest(&expected_file_path);
-  choose_args.Clear();
+  choose_args.ClearList();
   choose_args.AppendString("FILE");
   choose_args.AppendString("PEM");
   function = new api::DeveloperPrivateChoosePathFunction();
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
index 0a7f561..b3d9886 100644
--- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
+++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
@@ -250,7 +250,7 @@
       std::move(spellcheck_languages));
 
   // Build the language list.
-  language_list_->Clear();
+  language_list_->ClearList();
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   const base::flat_set<std::string> allowed_ui_locales(GetAllowedLanguages(
       Profile::FromBrowserContext(browser_context())->GetPrefs()));
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
index 926c10a..c4b2b9ce 100644
--- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
+++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -32,14 +32,14 @@
 #include "chrome/browser/ui/tab_helpers.h"
 #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/extension_metrics.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "components/favicon/core/favicon_service.h"
@@ -247,7 +247,7 @@
           image_result.image.AsBitmap();
     }
 
-    auto* provider = web_app::WebAppProviderBase::GetProviderBase(
+    auto* provider = web_app::WebAppProvider::GetForWebApps(
         Profile::FromBrowserContext(context));
     DCHECK(provider);
 
@@ -261,10 +261,10 @@
   extensions::api::management::ExtensionInfo CreateExtensionInfoFromWebApp(
       const std::string& app_id,
       content::BrowserContext* context) override {
-    auto* provider = web_app::WebAppProviderBase::GetProviderBase(
+    auto* provider = web_app::WebAppProvider::GetForWebApps(
         Profile::FromBrowserContext(context));
     DCHECK(provider);
-    const web_app::AppRegistrar& registrar = provider->registrar();
+    const web_app::WebAppRegistrar& registrar = provider->registrar();
 
     extensions::api::management::ExtensionInfo info;
     info.id = app_id;
@@ -327,7 +327,7 @@
   // preference, the default launch value will be returned.
   // TODO(crbug.com/1003602): Make AppLaunchParams launch container Optional or
   // add a "default" launch container enum value.
-  auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
   DCHECK(provider);
   blink::mojom::DisplayMode display_mode =
       provider->registrar().GetAppUserDisplayMode(app_id);
@@ -530,7 +530,7 @@
     const GURL& web_app_url,
     InstallOrLaunchWebAppCallback callback) const {
   Profile* profile = Profile::FromBrowserContext(context);
-  auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
   DCHECK(provider);
 
   // Launch the app if web_app_url happens to match start_url. If not, the app
diff --git a/chrome/browser/extensions/api/management/management_apitest.cc b/chrome/browser/extensions/api/management/management_apitest.cc
index 5b4eb521..7a7c804 100644
--- a/chrome/browser/extensions/api/management/management_apitest.cc
+++ b/chrome/browser/extensions/api/management/management_apitest.cc
@@ -16,11 +16,11 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/test/test_web_app_ui_manager.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "content/public/test/browser_test.h"
@@ -210,7 +210,7 @@
     web_app::AppId web_app_id =
         web_app::GenerateAppId(/*manifest_id=*/absl::nullopt, start_url);
     auto* provider =
-        web_app::WebAppProviderBase::GetProviderBase(browser()->profile());
+        web_app::WebAppProvider::GetForWebApps(browser()->profile());
     EXPECT_FALSE(provider->registrar().IsLocallyInstalled(start_url));
     EXPECT_EQ(0, static_cast<int>(
                      provider->ui_manager().GetNumWindowsForApp(web_app_id)));
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
index a8ad698f..cf39662 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
@@ -12,10 +12,10 @@
 #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_util.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/common/extensions/api/safe_browsing_private.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_function.h"
 
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_util.h b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_util.h
index 8f0763f..edd31e4 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_util.h
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_util.h
@@ -5,8 +5,8 @@
 #ifndef CHROME_BROWSER_EXTENSIONS_API_SAFE_BROWSING_PRIVATE_SAFE_BROWSING_UTIL_H_
 #define CHROME_BROWSER_EXTENSIONS_API_SAFE_BROWSING_PRIVATE_SAFE_BROWSING_UTIL_H_
 
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/common/extensions/api/safe_browsing_private.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 
 namespace extensions {
 
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
index 0f20ccb..d522b493 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
@@ -149,7 +149,7 @@
     base::ListValue* list_of_capture_info) const {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(list_of_capture_info);
-  list_of_capture_info->Clear();
+  list_of_capture_info->ClearList();
   for (const std::unique_ptr<LiveRequest>& request : requests_) {
     if (request->is_anonymous() || !request->is_verified() ||
         request->extension_id() != extension_id)
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
index fd2f9dd..25cd387e 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -77,7 +77,7 @@
                                  const Extension* extension,
                                  Event* event,
                                  const base::DictionaryValue* listener_filter) {
-  event->event_args->Clear();
+  event->event_args->ClearList();
   ExtensionTabUtil::ScrubTabBehavior scrub_tab_behavior =
       ExtensionTabUtil::GetScrubTabBehavior(extension, target_context,
                                             contents);
diff --git a/chrome/browser/extensions/api/tabs/windows_event_router.cc b/chrome/browser/extensions/api/tabs/windows_event_router.cc
index 53e7bfe..7187053 100644
--- a/chrome/browser/extensions/api/tabs/windows_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/windows_event_router.cc
@@ -133,10 +133,10 @@
       window_controller, extension, listener_filter);
 
   if (cant_cross_incognito || !visible_to_listener) {
-    event->event_args->Clear();
+    event->event_args->ClearList();
     event->event_args->AppendInteger(extension_misc::kUnknownWindowId);
   } else {
-    event->event_args->Clear();
+    event->event_args->ClearList();
     event->event_args->AppendInteger(window_id);
   }
   return true;
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 e5ae528d2..db87355 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -33,7 +33,6 @@
 #include "chrome/browser/extensions/scoped_active_install.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
@@ -46,6 +45,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "content/public/browser/gpu_feature_checker.h"
 #include "content/public/browser/storage_partition.h"
diff --git a/chrome/browser/extensions/chrome_app_sorting.cc b/chrome/browser/extensions/chrome_app_sorting.cc
index 12bba92..416ca38 100644
--- a/chrome/browser/extensions/chrome_app_sorting.cc
+++ b/chrome/browser/extensions/chrome_app_sorting.cc
@@ -18,8 +18,8 @@
 #include "chrome/browser/extensions/extension_sync_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -198,8 +198,7 @@
 void ChromeAppSorting::InitializePageOrdinalMapFromWebApps() {
   auto* profile = Profile::FromBrowserContext(browser_context_);
   DCHECK(profile);
-  auto* web_app_provider =
-      web_app::WebAppProviderBase::GetProviderBase(profile);
+  auto* web_app_provider = web_app::WebAppProvider::GetForWebApps(profile);
   DCHECK(web_app_provider);
   web_app_registrar_ = web_app_provider->registrar().AsWebAppRegistrar();
   web_app_sync_bridge_ =
diff --git a/chrome/browser/extensions/chrome_app_sorting.h b/chrome/browser/extensions/chrome_app_sorting.h
index fb574569..d32811e 100644
--- a/chrome/browser/extensions/chrome_app_sorting.h
+++ b/chrome/browser/extensions/chrome_app_sorting.h
@@ -15,10 +15,10 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/sync/model/string_ordinal.h"
 #include "extensions/browser/app_sorting.h"
 #include "extensions/browser/extension_prefs.h"
@@ -176,7 +176,8 @@
   content::BrowserContext* const browser_context_ = nullptr;
   const web_app::WebAppRegistrar* web_app_registrar_ = nullptr;
   web_app::WebAppSyncBridge* web_app_sync_bridge_ = nullptr;
-  base::ScopedObservation<web_app::AppRegistrar, web_app::AppRegistrarObserver>
+  base::ScopedObservation<web_app::WebAppRegistrar,
+                          web_app::AppRegistrarObserver>
       app_registrar_observation_{this};
 
   // A map of all the StringOrdinal page ordinals mapping to the collections of
diff --git a/chrome/browser/extensions/extension_management_unittest.cc b/chrome/browser/extensions/extension_management_unittest.cc
index 92419d7..b0c0e6f 100644
--- a/chrome/browser/extensions/extension_management_unittest.cc
+++ b/chrome/browser/extensions/extension_management_unittest.cc
@@ -1094,7 +1094,7 @@
   blocklist.AppendString("*");
   EXPECT_TRUE(BlocklistedByDefault(&blocklist));
 
-  blocklist.Clear();
+  blocklist.ClearList();
   blocklist.AppendString("*");
   EXPECT_TRUE(BlocklistedByDefault(&blocklist));
 }
@@ -1171,7 +1171,7 @@
   blocklist.AppendString(extension_->id());
   EXPECT_FALSE(UserMayLoad(&blocklist, nullptr, nullptr, nullptr,
                            extension_.get(), nullptr));
-  blocklist.Clear();
+  blocklist.ClearList();
   blocklist.AppendString(extension_->id());
   EXPECT_FALSE(UserMayLoad(&blocklist, nullptr, nullptr, nullptr,
                            extension_.get(), nullptr));
diff --git a/chrome/browser/extensions/extension_web_ui.cc b/chrome/browser/extensions/extension_web_ui.cc
index 0260a49..cb2e6b4b 100644
--- a/chrome/browser/extensions/extension_web_ui.cc
+++ b/chrome/browser/extensions/extension_web_ui.cc
@@ -102,7 +102,7 @@
 
 // Adds |override| to |list|, or, if there's already an entry for the override,
 // marks it as active.
-void AddOverridesToList(base::ListValue* list, const GURL& override_url) {
+void AddOverridesToList(base::Value* list, const GURL& override_url) {
   const std::string& spec = override_url.spec();
   for (auto& val : list->GetList()) {
     std::string* entry = nullptr;
@@ -129,11 +129,11 @@
     }
   }
 
-  auto dict = std::make_unique<base::DictionaryValue>();
-  dict->SetString(kEntry, spec);
-  dict->SetBoolean(kActive, true);
+  base::Value dict(base::Value::Type::DICTIONARY);
+  dict.SetStringPath(kEntry, spec);
+  dict.SetBoolPath(kActive, true);
   // Add the entry to the front of the list.
-  list->Insert(0, std::move(dict));
+  list->Insert(list->GetList().begin(), std::move(dict));
 }
 
 // Validates that each entry in |list| contains a valid url and points to an
@@ -539,14 +539,13 @@
     return;
   PrefService* prefs = profile->GetPrefs();
   DictionaryPrefUpdate update(prefs, kExtensionURLOverrides);
-  base::DictionaryValue* all_overrides = update.Get();
+  base::Value* all_overrides = update.Get();
   for (const auto& page_override_pair : overrides) {
-    base::ListValue* page_overrides_weak = nullptr;
-    if (!all_overrides->GetList(page_override_pair.first,
-                                &page_overrides_weak)) {
-      auto page_overrides = std::make_unique<base::ListValue>();
-      page_overrides_weak = page_overrides.get();
-      all_overrides->Set(page_override_pair.first, std::move(page_overrides));
+    base::Value* page_overrides_weak =
+        all_overrides->FindListPath(page_override_pair.first);
+    if (page_overrides_weak == nullptr) {
+      page_overrides_weak = all_overrides->SetPath(
+          page_override_pair.first, base::Value(base::Value::Type::LIST));
     }
     AddOverridesToList(page_overrides_weak, page_override_pair.second);
   }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index aa2546f..e36d5d3 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -3011,7 +3011,12 @@
   },
   {
     "name": "files-archivemount",
-    "owners": [ "fdegros", "nigeltao"],
+    "owners": [ "fdegros", "nigeltao" ],
+    "expiry_milestone": 100
+  },
+  {
+    "name": "files-banner-framework",
+    "owners": [ "benreich", "lucmult" ],
     "expiry_milestone": 100
   },
   {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index e0f6fa2..63e35fd 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -4661,6 +4661,11 @@
 const char kFilesArchivemountDescription[] =
     "Enable mounting various archive formats in File Manager.";
 
+const char kFilesBannerFrameworkName[] =
+    "Updated Banner framework in Files app";
+const char kFilesBannerFrameworkDescription[] =
+    "Enable the updated branner framework in Files app";
+
 const char kFilesSinglePartitionFormatName[] =
     "Enable Partitioning of Removable Disks.";
 const char kFilesSinglePartitionFormatDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 7dfa6ec..581b8862 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2677,6 +2677,9 @@
 extern const char kFilesArchivemountName[];
 extern const char kFilesArchivemountDescription[];
 
+extern const char kFilesBannerFrameworkName[];
+extern const char kFilesBannerFrameworkDescription[];
+
 extern const char kFilesSinglePartitionFormatName[];
 extern const char kFilesSinglePartitionFormatDescription[];
 
diff --git a/chrome/browser/installable/installable_utils.cc b/chrome/browser/installable/installable_utils.cc
index cba8d8d..0ab3e79d 100644
--- a/chrome/browser/installable/installable_utils.cc
+++ b/chrome/browser/installable/installable_utils.cc
@@ -11,9 +11,9 @@
 #include "chrome/browser/android/shortcut_helper.h"
 #else
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_provider_factory.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "url/gurl.h"
 #include "url/url_constants.h"
 #endif
@@ -46,7 +46,7 @@
   // that WebAppProvider is started.
   if (!provider || !provider->on_registry_ready().is_signaled())
     return std::set<GURL>();
-  const web_app::AppRegistrar& registrar = provider->registrar();
+  const web_app::WebAppRegistrar& registrar = provider->registrar();
   auto app_ids = registrar.GetAppIds();
   std::set<GURL> installed_origins;
   for (auto& app_id : app_ids) {
diff --git a/chrome/browser/metrics/variations/variations_safe_mode_browsertest.cc b/chrome/browser/metrics/variations/variations_safe_mode_browsertest.cc
index 752b489..bf42b9f9 100644
--- a/chrome/browser/metrics/variations/variations_safe_mode_browsertest.cc
+++ b/chrome/browser/metrics/variations/variations_safe_mode_browsertest.cc
@@ -4,9 +4,8 @@
 
 #include <string>
 
-#include "base/base64.h"
+#include "base/metrics/field_trial.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/metrics/clean_exit_beacon.h"
@@ -17,37 +16,23 @@
 #include "components/variations/variations_test_utils.h"
 #include "content/public/test/browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/zlib/google/compression_utils.h"
 
+namespace variations {
 namespace {
 
-// Returns a base64-encoded compressed serialized form of a VariationsSeed.
-std::string GetTestSeedForPrefs() {
-  std::string serialized_seed;
-  base::Base64Decode(variations::kUncompressedBase64TestSeedData,
-                     &serialized_seed);
-
-  std::string compressed_seed_data;
-  compression::GzipCompress(serialized_seed, &compressed_seed_data);
-
-  std::string base64_seed_data;
-  base::Base64Encode(compressed_seed_data, &base64_seed_data);
-  return base64_seed_data;
-}
-
 // Sets |local_state|'s seed and seed signature prefs to a valid seed-signature
 // pair. If |use_safe_seed_prefs| is true, then uses the safe seed prefs.
 void StoreTestSeedAndSignature(PrefService* local_state,
                                bool use_safe_seed_prefs) {
-  const std::string seed_pref =
-      use_safe_seed_prefs ? variations::prefs::kVariationsSafeCompressedSeed
-                          : variations::prefs::kVariationsCompressedSeed;
+  const std::string seed_pref = use_safe_seed_prefs
+                                    ? prefs::kVariationsSafeCompressedSeed
+                                    : prefs::kVariationsCompressedSeed;
   local_state->SetString(seed_pref, GetTestSeedForPrefs());
 
-  const std::string signature_pref =
-      use_safe_seed_prefs ? variations::prefs::kVariationsSafeSeedSignature
-                          : variations::prefs::kVariationsSeedSignature;
-  local_state->SetString(signature_pref, variations::kBase64TestSeedSignature);
+  const std::string signature_pref = use_safe_seed_prefs
+                                         ? prefs::kVariationsSafeSeedSignature
+                                         : prefs::kVariationsSeedSignature;
+  local_state->SetString(signature_pref, kBase64TestSeedSignature);
 }
 
 // Simulates a crash by forcing Chrome to fail to exit cleanly.
@@ -60,7 +45,7 @@
 
 class VariationsSafeModeBrowserTest : public InProcessBrowserTest {
  public:
-  VariationsSafeModeBrowserTest() { variations::DisableTestingConfig(); }
+  VariationsSafeModeBrowserTest() { DisableTestingConfig(); }
   ~VariationsSafeModeBrowserTest() override = default;
 
  protected:
@@ -91,7 +76,7 @@
 IN_PROC_BROWSER_TEST_F(VariationsSafeModeBrowserTest,
                        ThreeCrashesTriggerSafeMode) {
   EXPECT_EQ(g_browser_process->local_state()->GetInteger(
-                variations::prefs::kVariationsCrashStreak),
+                prefs::kVariationsCrashStreak),
             3);
   histogram_tester_.ExpectUniqueSample("Variations.SafeMode.Streak.Crashes", 3,
                                        1);
@@ -99,10 +84,13 @@
   // Verify that Chrome fell back to a safe seed, which happens during browser
   // test setup.
   histogram_tester_.ExpectUniqueSample(
-      "Variations.SafeMode.LoadSafeSeed.Result",
-      variations::LoadSeedResult::kSuccess, 1);
+      "Variations.SafeMode.LoadSafeSeed.Result", LoadSeedResult::kSuccess, 1);
   histogram_tester_.ExpectUniqueSample(
       "Variations.SafeMode.FellBackToSafeMode2", true, 1);
+
+  // Verify that there is a field trial associated with the sole test seed
+  // study, |kTestSeedStudyName|.
+  EXPECT_TRUE(base::FieldTrialList::TrialExists(kTestSeedStudyName));
 }
 
 IN_PROC_BROWSER_TEST_F(VariationsSafeModeBrowserTest,
@@ -112,8 +100,7 @@
   // pref to be set early enough to be read by the variations code, which runs
   // very early during startup.
   PrefService* local_state = g_browser_process->local_state();
-  local_state->SetInteger(variations::prefs::kVariationsFailedToFetchSeedStreak,
-                          25);
+  local_state->SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 25);
   StoreTestSeedAndSignature(local_state, /*use_safe_seed_prefs=*/true);
 }
 
@@ -125,10 +112,13 @@
   // Verify that Chrome fell back to a safe seed, which happens during browser
   // test setup.
   histogram_tester_.ExpectUniqueSample(
-      "Variations.SafeMode.LoadSafeSeed.Result",
-      variations::LoadSeedResult::kSuccess, 1);
+      "Variations.SafeMode.LoadSafeSeed.Result", LoadSeedResult::kSuccess, 1);
   histogram_tester_.ExpectUniqueSample(
       "Variations.SafeMode.FellBackToSafeMode2", true, 1);
+
+  // Verify that there is a field trial associated with the sole test seed
+  // study, |kTestSeedStudyName|.
+  EXPECT_TRUE(base::FieldTrialList::TrialExists(kTestSeedStudyName));
 }
 
 IN_PROC_BROWSER_TEST_F(VariationsSafeModeBrowserTest,
@@ -138,9 +128,8 @@
   // pref to be set early enough to be read by the variations code, which runs
   // very early during startup.
   PrefService* local_state = g_browser_process->local_state();
-  local_state->SetInteger(variations::prefs::kVariationsCrashStreak, 2);
-  local_state->SetInteger(variations::prefs::kVariationsFailedToFetchSeedStreak,
-                          24);
+  local_state->SetInteger(prefs::kVariationsCrashStreak, 2);
+  local_state->SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 24);
   StoreTestSeedAndSignature(local_state, /*use_safe_seed_prefs=*/false);
 }
 
@@ -152,9 +141,11 @@
 
   // Verify that Chrome applied the latest seed.
   histogram_tester_.ExpectUniqueSample("Variations.SeedLoadResult",
-                                       variations::LoadSeedResult::kSuccess, 1);
+                                       LoadSeedResult::kSuccess, 1);
 
   // Verify that Chrome did not fall back to a safe seed.
   histogram_tester_.ExpectUniqueSample(
       "Variations.SafeMode.FellBackToSafeMode2", false, 1);
 }
+
+}  // namespace variations
diff --git a/chrome/browser/page_load_metrics/observers/prerender_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/prerender_page_load_metrics_observer_browsertest.cc
new file mode 100644
index 0000000..ecc650f
--- /dev/null
+++ b/chrome/browser/page_load_metrics/observers/prerender_page_load_metrics_observer_browsertest.cc
@@ -0,0 +1,168 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.h"
+#include "components/page_load_metrics/browser/page_load_metrics_test_waiter.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/prerender_test_util.h"
+#include "third_party/blink/public/common/features.h"
+
+class PrerenderPageLoadMetricsObserverBrowserTest
+    : public MetricIntegrationTest {
+ public:
+  PrerenderPageLoadMetricsObserverBrowserTest()
+      : prerender_helper_(base::BindRepeating(
+            &PrerenderPageLoadMetricsObserverBrowserTest::web_contents,
+            base::Unretained(this))) {
+    feature_list_.InitAndEnableFeature(blink::features::kPrerender2);
+  }
+  ~PrerenderPageLoadMetricsObserverBrowserTest() override = default;
+
+  void SetUpOnMainThread() override {
+    prerender_helper_.SetUpOnMainThread(embedded_test_server());
+    MetricIntegrationTest::SetUpOnMainThread();
+  }
+
+ protected:
+  content::test::PrerenderTestHelper prerender_helper_;
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(PrerenderPageLoadMetricsObserverBrowserTest,
+                       ActivateInForeground) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Navigate to an initial page.
+  auto initial_url = embedded_test_server()->GetURL("/empty.html");
+  ui_test_utils::NavigateToURL(browser(), initial_url);
+
+  // Start a prerender.
+  GURL prerender_url = embedded_test_server()->GetURL("/title2.html");
+  prerender_helper_.AddPrerender(prerender_url);
+
+  // Activate and wait for FCP.
+  auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
+      web_contents());
+  waiter->AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
+                                 TimingField::kFirstContentfulPaint);
+  prerender_helper_.NavigatePrimaryPage(prerender_url);
+  waiter->Wait();
+
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderNavigationToActivation, 1);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderActivationToFirstPaint, 1);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderActivationToFirstContentfulPaint, 1);
+
+  // Simulate mouse click and wait for FirstInputDelay.
+  content::SimulateMouseClick(web_contents(), 0,
+                              blink::WebPointerProperties::Button::kLeft);
+  waiter->AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
+                                 TimingField::kFirstInputDelay);
+  waiter->Wait();
+
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderFirstInputDelay4, 1);
+
+  // Force navigation to another page, which should force logging of histograms
+  // persisted at the end of the page load lifetime.
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderActivationToLargestContentfulPaint2, 1);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderCumulativeShiftScore, 1);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderCumulativeShiftScoreMainFrame, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(PrerenderPageLoadMetricsObserverBrowserTest,
+                       ActivateInBackground) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Navigate to an initial page.
+  auto initial_url = embedded_test_server()->GetURL("/empty.html");
+  ui_test_utils::NavigateToURL(browser(), initial_url);
+
+  // Start a prerender.
+  GURL prerender_url = embedded_test_server()->GetURL("/title2.html");
+  prerender_helper_.AddPrerender(prerender_url);
+
+  // Make the tab backgrounded before the prerendered page is activated.
+  web_contents()->WasHidden();
+
+  // Activate the page, foreground the tab and wait for FCP.
+  auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
+      web_contents());
+  waiter->AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
+                                 TimingField::kFirstContentfulPaint);
+  prerender_helper_.NavigatePrimaryPage(prerender_url);
+  EXPECT_TRUE(WaitForLoadStop(web_contents()));
+  web_contents()->WasShown();
+  waiter->Wait();
+
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderNavigationToActivation, 1);
+
+  // Simulate mouse click and wait for FirstInputDelay.
+  content::SimulateMouseClick(web_contents(), 0,
+                              blink::WebPointerProperties::Button::kLeft);
+  waiter->AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
+                                 TimingField::kFirstInputDelay);
+  waiter->Wait();
+
+  // Force navigation to another page, which should force logging of histograms
+  // persisted at the end of the page load lifetime.
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+
+  // As the tab was in the background when activated, no CWV metrics are
+  // recorded.
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderActivationToFirstPaint, 0);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderActivationToFirstContentfulPaint, 0);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderActivationToLargestContentfulPaint2, 0);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderFirstInputDelay4, 0);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderCumulativeShiftScore, 0);
+  histogram_tester().ExpectTotalCount(
+      internal::kHistogramPrerenderCumulativeShiftScoreMainFrame, 0);
+}
+
+IN_PROC_BROWSER_TEST_F(PrerenderPageLoadMetricsObserverBrowserTest,
+                       CancelledPrerender) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Navigate to an initial page.
+  auto initial_url = embedded_test_server()->GetURL("/empty.html");
+  ui_test_utils::NavigateToURL(browser(), initial_url);
+
+  // Start a prerender.
+  GURL prerender_url = embedded_test_server()->GetURL("/title2.html");
+  const int host_id = prerender_helper_.AddPrerender(prerender_url);
+
+  // Start a navigation in the prerender frame tree that will cancel the
+  // initiator's prerendering.
+  content::test::PrerenderHostObserver observer(*web_contents(), host_id);
+
+  GURL hung_url = embedded_test_server()->GetURL("/hung");
+  prerender_helper_.NavigatePrerenderedPage(host_id, hung_url);
+
+  observer.WaitForDestroyed();
+
+  // Force navigation to another page, which should force logging of histograms
+  // persisted at the end of the page load lifetime.
+  ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
+
+  // As the prerender was cancelled, no prerendering metrics are recorded.
+  EXPECT_EQ(0u, histogram_tester()
+                    .GetTotalCountsForPrefix("PageLoad.Clients.Prerender.")
+                    .size());
+}
diff --git a/chrome/browser/password_manager/password_store_utils.cc b/chrome/browser/password_manager/password_store_utils.cc
index a97bf4c3..eab00137 100644
--- a/chrome/browser/password_manager/password_store_utils.cc
+++ b/chrome/browser/password_manager/password_store_utils.cc
@@ -8,59 +8,9 @@
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/password_manager/core/browser/password_form.h"
-#include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_store.h"
 #include "components/password_manager/core/browser/password_store_interface.h"
 
-namespace {
-using password_manager::metrics_util::IsPasswordChanged;
-using password_manager::metrics_util::IsUsernameChanged;
-}  // namespace
-
-// TODO(crbug.com/1136815): Drop this, once Android no longer use it.
-void EditSavedPasswords(
-    Profile* profile,
-    const base::span<const std::unique_ptr<password_manager::PasswordForm>>
-        forms_to_change,
-    const std::u16string& new_username,
-    const absl::optional<std::u16string>& new_password) {
-  DCHECK(!forms_to_change.empty());
-
-  const std::string signon_realm = forms_to_change[0]->signon_realm;
-
-  IsUsernameChanged username_changed(new_username !=
-                                     forms_to_change[0]->username_value);
-  IsPasswordChanged password_changed(new_password !=
-                                     forms_to_change[0]->password_value);
-
-  // An updated username implies a change in the primary key, thus we need to
-  // make sure to call the right API. Update every entry in the equivalence
-  // class.
-  for (const auto& old_form : forms_to_change) {
-    scoped_refptr<password_manager::PasswordStoreInterface> store =
-        GetPasswordStore(profile, old_form->IsUsingAccountStore());
-
-    if (!store) {
-      continue;
-    }
-    password_manager::PasswordForm new_form = *old_form;
-    new_form.username_value = new_username;
-
-    // The desktop logic allows to edit usernames even in cases when the
-    // password cannot be displayed. In those cases, new_password won't have
-    // a value.
-    if (new_password.has_value())
-      new_form.password_value = new_password.value();
-    if (username_changed) {
-      store->UpdateLoginWithPrimaryKey(new_form, *old_form);
-    } else {
-      store->UpdateLogin(new_form);
-    }
-  }
-  password_manager::metrics_util::LogPasswordEditResult(username_changed,
-                                                        password_changed);
-}
-
 password_manager::PasswordStoreInterface* GetPasswordStore(
     Profile* profile,
     bool use_account_store) {
diff --git a/chrome/browser/password_manager/password_store_utils.h b/chrome/browser/password_manager/password_store_utils.h
index a89e6df..4304dc79 100644
--- a/chrome/browser/password_manager/password_store_utils.h
+++ b/chrome/browser/password_manager/password_store_utils.h
@@ -7,31 +7,14 @@
 #ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_UTILS_H_
 #define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_UTILS_H_
 
-#include <string>
-
-#include "base/containers/span.h"
 #include "base/memory/scoped_refptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace password_manager {
 class PasswordStoreInterface;
-struct PasswordForm;
 }
 
 class Profile;
 
-// Changes a credential record in password store. If new_password is null it
-// isn't changed, but if it is non-null it can't be empty.
-// |forms_to_change| are the forms in which the usernames and passwords are
-// changed. This function assumes that all conflicts checks have already
-// been performed, prior to calling it.
-void EditSavedPasswords(
-    Profile* profile,
-    base::span<const std::unique_ptr<password_manager::PasswordForm>>
-        forms_to_change,
-    const std::u16string& new_username,
-    const absl::optional<std::u16string>& new_password);
-
 // Returns the password store associated with the currently active profile.
 password_manager::PasswordStoreInterface* GetPasswordStore(
     Profile* profile,
diff --git a/chrome/browser/policy/extension_policy_browsertest.cc b/chrome/browser/policy/extension_policy_browsertest.cc
index 51e4f12..1ee3debe 100644
--- a/chrome/browser/policy/extension_policy_browsertest.cc
+++ b/chrome/browser/policy/extension_policy_browsertest.cc
@@ -35,13 +35,13 @@
 #include "chrome/browser/policy/profile_policy_connector_builder.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
 #include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/extension_test_util.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -235,8 +235,8 @@
     return extensions::ExtensionRegistry::Get(browser()->profile());
   }
 
-  web_app::WebAppProviderBase* web_app_provider_base() {
-    return web_app::WebAppProviderBase::GetProviderBase(browser()->profile());
+  web_app::WebAppProvider* web_app_provider() {
+    return web_app::WebAppProvider::GetForWebApps(browser()->profile());
   }
 
   const extensions::Extension* InstallExtension(
@@ -285,7 +285,7 @@
     web_application->start_url = GURL("http://www.google.com");
     base::RunLoop loop;
     web_app::AppId return_app_id;
-    web_app_provider_base()->install_manager().InstallWebAppFromInfo(
+    web_app_provider()->install_manager().InstallWebAppFromInfo(
         std::move(web_application), web_app::ForInstallableSite::kYes,
         webapps::WebappInstallSource::SYNC,
         base::BindLambdaForTesting(
@@ -506,7 +506,7 @@
   web_app::AppId web_app_id = InstallWebApp();
   EXPECT_TRUE(InstallExtension(kGoodCrxName));
 
-  web_app::WebAppProviderBase* provider = web_app_provider_base();
+  web_app::WebAppProvider* provider = web_app_provider();
   EXPECT_TRUE(provider->registrar().IsInstalled(web_app_id));
   extensions::ExtensionService* service = extension_service();
   EXPECT_TRUE(service->IsExtensionEnabled(kGoodCrxId));
@@ -606,7 +606,7 @@
   web_app::AppId web_app_id = InstallWebApp();
   EXPECT_TRUE(InstallExtension(kGoodCrxName));
 
-  web_app::WebAppProviderBase* provider = web_app_provider_base();
+  web_app::WebAppProvider* provider = web_app_provider();
   EXPECT_TRUE(provider->registrar().IsInstalled(web_app_id));
   extensions::ExtensionService* service = extension_service();
   EXPECT_TRUE(service->IsExtensionEnabled(kGoodCrxId));
@@ -683,7 +683,7 @@
   web_app::AppId web_app_id = InstallWebApp();
   EXPECT_TRUE(InstallExtension(kGoodCrxName));
 
-  web_app::WebAppProviderBase* provider = web_app_provider_base();
+  web_app::WebAppProvider* provider = web_app_provider();
   EXPECT_TRUE(provider->registrar().IsInstalled(web_app_id));
   extensions::ExtensionService* service = extension_service();
   EXPECT_TRUE(service->IsExtensionEnabled(kGoodCrxId));
@@ -2523,9 +2523,8 @@
 };
 
 IN_PROC_BROWSER_TEST_F(WebAppInstallForceListPolicyTest, StartUpInstallation) {
-  const web_app::AppRegistrar& registrar =
-      web_app::WebAppProviderBase::GetProviderBase(browser()->profile())
-          ->registrar();
+  const web_app::WebAppRegistrar& registrar =
+      web_app::WebAppProvider::GetForWebApps(browser()->profile())->registrar();
   web_app::WebAppInstallObserver install_observer(browser()->profile());
   absl::optional<web_app::AppId> app_id =
       registrar.FindAppWithUrlInScope(policy_app_url_);
@@ -2555,9 +2554,8 @@
 IN_PROC_BROWSER_TEST_F(
     WebAppInstallForceListPolicyWithAppFallbackNameManifestTest,
     StartUpInstallationPWAFallbackName) {
-  const web_app::AppRegistrar& registrar =
-      web_app::WebAppProviderBase::GetProviderBase(browser()->profile())
-          ->registrar();
+  const web_app::WebAppRegistrar& registrar =
+      web_app::WebAppProvider::GetForWebApps(browser()->profile())->registrar();
   web_app::WebAppInstallObserver install_observer(browser()->profile());
   absl::optional<web_app::AppId> app_id =
       registrar.FindAppWithUrlInScope(policy_app_url_);
@@ -2587,9 +2585,8 @@
 
 IN_PROC_BROWSER_TEST_F(WebAppInstallForceListPolicySAATest,
                        StartUpInstallationSAA) {
-  const web_app::AppRegistrar& registrar =
-      web_app::WebAppProviderBase::GetProviderBase(browser()->profile())
-          ->registrar();
+  const web_app::WebAppRegistrar& registrar =
+      web_app::WebAppProvider::GetForWebApps(browser()->profile())->registrar();
   web_app::WebAppInstallObserver install_observer(browser()->profile());
   absl::optional<web_app::AppId> app_id =
       registrar.FindAppWithUrlInScope(policy_app_url_);
@@ -2616,9 +2613,8 @@
 
 IN_PROC_BROWSER_TEST_F(WebAppInstallForceListPolicyWithAppFallbackNameSAATest,
                        StartUpInstallationSAAFallbackName) {
-  const web_app::AppRegistrar& registrar =
-      web_app::WebAppProviderBase::GetProviderBase(browser()->profile())
-          ->registrar();
+  const web_app::WebAppRegistrar& registrar =
+      web_app::WebAppProvider::GetForWebApps(browser()->profile())->registrar();
   web_app::WebAppInstallObserver install_observer(browser()->profile());
   absl::optional<web_app::AppId> app_id =
       registrar.FindAppWithUrlInScope(policy_app_url_);
@@ -2649,9 +2645,8 @@
 IN_PROC_BROWSER_TEST_F(
     WebAppInstallForceListPolicyPlaceholderWithAppFallbackNameTest,
     StartUpInstallationPlaceholderFallbackName) {
-  const web_app::AppRegistrar& registrar =
-      web_app::WebAppProviderBase::GetProviderBase(browser()->profile())
-          ->registrar();
+  const web_app::WebAppRegistrar& registrar =
+      web_app::WebAppProvider::GetForWebApps(browser()->profile())->registrar();
   web_app::WebAppInstallObserver install_observer(browser()->profile());
   absl::optional<web_app::AppId> app_id =
       registrar.FindAppWithUrlInScope(policy_app_url_);
diff --git a/chrome/browser/policy/test/safe_browsing_policy_browsertest.cc b/chrome/browser/policy/test/safe_browsing_policy_browsertest.cc
index 11ad858..2664c55 100644
--- a/chrome/browser/policy/test/safe_browsing_policy_browsertest.cc
+++ b/chrome/browser/policy/test/safe_browsing_policy_browsertest.cc
@@ -152,7 +152,7 @@
   EXPECT_EQ("mydomain.net", canonicalized_domains[1]);
 
   // Invalid domains will be skipped.
-  whitelist_domains.Clear();
+  whitelist_domains.ClearList();
   whitelist_domains.AppendString(std::string("%EF%BF%BDzyx.com"));
   policies.Set(key::kSafeBrowsingWhitelistDomains, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
@@ -195,7 +195,7 @@
   EXPECT_EQ(GURL("https://mydomian.com/login.html"), login_urls[1]);
 
   // Verify non-http/https schemes, or invalid URLs will be skipped.
-  login_url_values.Clear();
+  login_url_values.ClearList();
   login_url_values.AppendString(std::string("invalid"));
   login_url_values.AppendString(std::string("ftp://login.mydomain.com"));
   policies.Set(key::kPasswordProtectionLoginURLs, POLICY_LEVEL_MANDATORY,
diff --git a/chrome/browser/portal/portal_browsertest.cc b/chrome/browser/portal/portal_browsertest.cc
index e49852a..2ed97ce 100644
--- a/chrome/browser/portal/portal_browsertest.cc
+++ b/chrome/browser/portal/portal_browsertest.cc
@@ -457,8 +457,16 @@
 // Tests that if a page embeds a portal whose contents are considered dangerous
 // by Safe Browsing, the embedder is also treated as dangerous in terms of how
 // we display the Safe Browsing interstitial.
+// Flaky on ChromeOS & under Ozone (crbug.com/1220319)
+#if defined(OS_CHROMEOS) || defined(USE_OZONE)
+#define MAYBE_EmbedderOfDangerousPortalConsideredDangerous \
+  DISABLED_EmbedderOfDangerousPortalConsideredDangerous
+#else
+#define MAYBE_EmbedderOfDangerousPortalConsideredDangerous \
+  EmbedderOfDangerousPortalConsideredDangerous
+#endif
 IN_PROC_BROWSER_TEST_F(PortalSafeBrowsingBrowserTest,
-                       EmbedderOfDangerousPortalConsideredDangerous) {
+                       MAYBE_EmbedderOfDangerousPortalConsideredDangerous) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
   GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 5795ded..a229a85a 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -146,6 +146,7 @@
 #include "components/site_engagement/content/site_engagement_service.h"
 #include "components/subresource_filter/content/browser/ruleset_service.h"
 #include "components/sync/base/sync_prefs.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync_device_info/device_info_prefs.h"
 #include "components/sync_preferences/pref_service_syncable.h"
 #include "components/sync_sessions/session_sync_prefs.h"
@@ -1105,6 +1106,7 @@
   sync_sessions::SessionSyncPrefs::RegisterProfilePrefs(registry);
   syncer::DeviceInfoPrefs::RegisterProfilePrefs(registry);
   syncer::SyncPrefs::RegisterProfilePrefs(registry);
+  syncer::SyncTransportDataPrefs::RegisterProfilePrefs(registry);
   TemplateURLPrepopulateData::RegisterProfilePrefs(registry);
   translate::TranslatePrefs::RegisterProfilePrefs(registry);
   omnibox::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/prefs/session_startup_pref.cc b/chrome/browser/prefs/session_startup_pref.cc
index 8f33f17..f5fe185 100644
--- a/chrome/browser/prefs/session_startup_pref.cc
+++ b/chrome/browser/prefs/session_startup_pref.cc
@@ -88,7 +88,7 @@
     ListPrefUpdate update(prefs, prefs::kURLsToRestoreOnStartup);
     base::ListValue* url_pref_list = update.Get();
     DCHECK(url_pref_list);
-    url_pref_list->Clear();
+    url_pref_list->ClearList();
     for (size_t i = 0; i < pref.urls.size(); ++i) {
       url_pref_list->Set(static_cast<int>(i),
                          std::make_unique<base::Value>(pref.urls[i].spec()));
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index f2ba13c..f14d4dac 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -18,7 +18,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job.h"
@@ -30,6 +29,7 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "printing/backend/print_backend.h"
+#include "printing/mojom/print.mojom.h"
 #include "printing/print_job_constants.h"
 #include "printing/printed_document.h"
 #include "printing/printing_utils.h"
@@ -47,10 +47,6 @@
 #include "printing/printing_features.h"
 #endif
 
-#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && defined(USE_CUPS)
-#include "printing/mojom/print.mojom.h"
-#endif
-
 using content::BrowserThread;
 
 namespace printing {
@@ -196,7 +192,7 @@
                                 std::move(callback)));
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 void PrintJobWorker::SetSettingsFromPOD(
     std::unique_ptr<PrintSettings> new_settings,
     SettingsCallback callback) {
@@ -254,7 +250,7 @@
   GetSettingsDone(std::move(callback), result);
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 void PrintJobWorker::UpdatePrintSettingsFromPOD(
     std::unique_ptr<PrintSettings> new_settings,
     SettingsCallback callback) {
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h
index b74ce4f..2494da2 100644
--- a/chrome/browser/printing/print_job_worker.h
+++ b/chrome/browser/printing/print_job_worker.h
@@ -13,7 +13,6 @@
 #include "base/threading/thread.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "content/public/browser/browser_thread.h"
 #include "printing/mojom/print.mojom.h"
 #include "printing/page_number.h"
@@ -62,7 +61,7 @@
   // Set the new print settings from a dictionary value.
   void SetSettings(base::Value new_settings, SettingsCallback callback);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
   // Set the new print settings from a POD type.
   void SetSettingsFromPOD(std::unique_ptr<printing::PrintSettings> new_settings,
                           SettingsCallback callback);
@@ -151,7 +150,7 @@
   // Called on the UI thread to update the print settings.
   void UpdatePrintSettings(base::Value new_settings, SettingsCallback callback);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
   // Called on the UI thread to update the print settings.
   void UpdatePrintSettingsFromPOD(
       std::unique_ptr<printing::PrintSettings> new_settings,
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc
index b34730f..a65e9fd 100644
--- a/chrome/browser/printing/printer_query.cc
+++ b/chrome/browser/printing/printer_query.cc
@@ -13,7 +13,6 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
-#include "build/chromeos_buildflags.h"
 #include "chrome/browser/printing/print_job_worker.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -127,7 +126,7 @@
                          base::Unretained(this), std::move(callback))));
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 void PrinterQuery::SetSettingsFromPOD(
     std::unique_ptr<printing::PrintSettings> new_settings,
     base::OnceClosure callback) {
diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h
index 5f241f3..a9e24a7 100644
--- a/chrome/browser/printing/printer_query.h
+++ b/chrome/browser/printing/printer_query.h
@@ -10,7 +10,6 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/values.h"
-#include "build/chromeos_buildflags.h"
 #include "printing/mojom/print.mojom.h"
 #include "printing/print_settings.h"
 #include "printing/printing_context.h"
@@ -64,7 +63,7 @@
   virtual void SetSettings(base::Value new_settings,
                            base::OnceClosure callback);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
   // Updates the current settings with |new_settings|.
   // Caller has to ensure that |this| is alive until |callback| is run.
   void SetSettingsFromPOD(std::unique_ptr<PrintSettings> new_settings,
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 1c51cce..6231d7f 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -2172,7 +2172,7 @@
   ListPrefUpdate update(local_state, prefs::kProfilesLastActive);
   base::ListValue* profile_list = update.Get();
 
-  profile_list->Clear();
+  profile_list->ClearList();
 
   // crbug.com/120112 -> several non-off-the-record profiles might have the same
   // GetBaseName(). In that case, we cannot restore both
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index c6712d47..1bb31fac 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -86,11 +86,10 @@
 #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
 #include "chrome/browser/ui/webui/history/foreign_session_handler.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_render_frame.mojom.h"
@@ -1462,7 +1461,7 @@
     open_in_app_string_id = IDS_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP;
   }
 
-  auto* const provider = web_app::WebAppProviderBase::GetProviderBase(profile);
+  auto* const provider = web_app::WebAppProvider::GetForWebApps(profile);
   menu_model_.AddItem(
       IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP,
       l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
index 3029252..0aca7cc9 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -41,9 +41,9 @@
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_render_frame.mojom.h"
 #include "chrome/common/pref_names.h"
@@ -116,7 +116,7 @@
 using extensions::MimeHandlerViewGuest;
 using extensions::TestMimeHandlerViewGuest;
 using web_app::AppId;
-using web_app::WebAppProviderBase;
+using web_app::WebAppProvider;
 
 namespace {
 
@@ -566,8 +566,8 @@
   const AppId app_id = InstallTestWebApp(GURL(kAppUrl1));
 
   {
-    WebAppProviderBase* const provider =
-        WebAppProviderBase::GetProviderBase(browser()->profile());
+    WebAppProvider* const provider =
+        WebAppProvider::GetForWebApps(browser()->profile());
     base::RunLoop run_loop;
 
     ASSERT_TRUE(provider->install_finalizer().CanUserUninstallWebApp(app_id));
diff --git a/chrome/browser/resources/bookmarks/api_listener.ts b/chrome/browser/resources/bookmarks/api_listener.ts
index 8581e3b..67b7187e 100644
--- a/chrome/browser/resources/bookmarks/api_listener.ts
+++ b/chrome/browser/resources/bookmarks/api_listener.ts
@@ -118,6 +118,7 @@
  */
 function onImportBegan() {
   chrome.bookmarks.onCreated.removeListener(onBookmarkCreated);
+  document.dispatchEvent(new CustomEvent('import-began'));
 }
 
 function onImportEnded() {
@@ -125,6 +126,7 @@
     dispatch(refreshNodes(normalizeNodes(results[0]!)));
   });
   chrome.bookmarks.onCreated.addListener(onBookmarkCreated);
+  document.dispatchEvent(new CustomEvent('import-ended'));
 }
 
 function onIncognitoAvailabilityChanged(availability: IncognitoAvailability) {
diff --git a/chrome/browser/resources/bookmarks/list.ts b/chrome/browser/resources/bookmarks/list.ts
index 576cebf5..32f808ff 100644
--- a/chrome/browser/resources/bookmarks/list.ts
+++ b/chrome/browser/resources/bookmarks/list.ts
@@ -8,15 +8,15 @@
 import './strings.m.js';
 import './item.js';
 
+import {CrA11yAnnouncerElement} from 'chrome://resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
-import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
 import {isMac} from 'chrome://resources/js/cr.m.js';
 import {StoreObserver} from 'chrome://resources/js/cr/ui/store.m.js';
+import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
 import {ListPropertyUpdateBehavior} from 'chrome://resources/js/list_property_update_behavior.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
 import {getDeepActiveElement} from 'chrome://resources/js/util.m.js';
-import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js';
 import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
 import {afterNextRender, html, microTask, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
@@ -30,10 +30,10 @@
 
 const BookmarksListElementBase =
     mixinBehaviors([StoreClient, ListPropertyUpdateBehavior], PolymerElement) as
-{
-  new (): PolymerElement &BookmarksStoreClientInterface &
-      StoreObserver<BookmarksPageState> & ListPropertyUpdateBehavior
-}
+    {
+      new (): PolymerElement & BookmarksStoreClientInterface &
+      StoreObserver<BookmarksPageState>& ListPropertyUpdateBehavior
+    };
 
 export interface BookmarksListElement {
   $: {
@@ -129,10 +129,10 @@
     this.eventTracker_.add(
         document, 'highlight-items',
         e => this.onHighlightItems_(e as CustomEvent<string[]>));
-
-    afterNextRender(this, function() {
-      IronA11yAnnouncer.requestAvailability();
-    });
+    this.eventTracker_.add(
+        document, 'import-began', () => this.onImportBegan_());
+    this.eventTracker_.add(
+        document, 'import-ended', () => this.onImportEnded_());
   }
 
   disconnectedCallback() {
@@ -175,9 +175,7 @@
         new CustomEvent('iron-resize', {bubbles: true, composed: true}));
     const label = await PluralStringProxyImpl.getInstance().getPluralString(
         'listChanged', this.displayedList_.length);
-    this.dispatchEvent(new CustomEvent(
-        'iron-announce',
-        {bubbles: true, composed: true, detail: {text: label}}));
+    CrA11yAnnouncerElement.getInstance().announce(label);
 
     if (!skipFocus && selectIndex > -1) {
       setTimeout(() => {
@@ -265,6 +263,16 @@
     });
   }
 
+  private onImportBegan_() {
+    CrA11yAnnouncerElement.getInstance().announce(
+        loadTimeData.getString('importBegan'));
+  }
+
+  private onImportEnded_() {
+    CrA11yAnnouncerElement.getInstance().announce(
+        loadTimeData.getString('importEnded'));
+  }
+
   private onItemKeydown_(e: KeyboardEvent) {
     let handled = true;
     const list = this.$.list;
@@ -297,8 +305,8 @@
     }
 
     if (focusMoved) {
-      focusedIndex = Math.min(list.items!.length - 1,
-                              Math.max(0, focusedIndex));
+      focusedIndex =
+          Math.min(list.items!.length - 1, Math.max(0, focusedIndex));
       list.focusItem(focusedIndex);
 
       if (cursorModifier && !e.shiftKey) {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/key_util.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/key_util.js
index dab29f2..73d2167 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/key_util.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/key_util.js
@@ -398,29 +398,32 @@
             const keyCode = keySequence.keys[keyPressed][index];
             // We make sure the keyCode isn't for a modifier key. If it is, then
             // we've already added that into the string above.
-            if (!keySequence.isModifierKey(keyCode) && !opt_modifiers) {
-              if (opt_readableKeyCode) {
-                // First, try using Chrome OS's localized DOM key string
-                // conversion.
-                let domKeyString = await new Promise(
-                    resolve => chrome.accessibilityPrivate
-                                   .getLocalizedDomKeyStringForKeyCode(
-                                       keyCode, resolve));
-                if (domKeyString) {
-                  // Upper case single-lettered key strings for better tts.
-                  if (domKeyString.length === 1) {
-                    domKeyString = domKeyString.toUpperCase();
-                  }
-
-
-                  tempStr += domKeyString;
-                } else {
-                  tempStr += KeyUtil.getReadableNameForKeyCode(keyCode);
-                }
-              } else {
-                tempStr += KeyUtil.keyCodeToString(keyCode);
-              }
+            if (keySequence.isModifierKey(keyCode) || opt_modifiers) {
+              break;
             }
+
+            if (!opt_readableKeyCode) {
+              tempStr += KeyUtil.keyCodeToString(keyCode);
+              break;
+            }
+
+            // First, try using Chrome OS's localized DOM key string conversion.
+            let domKeyString = await new Promise(
+                resolve =>
+                    chrome.accessibilityPrivate
+                        .getLocalizedDomKeyStringForKeyCode(keyCode, resolve));
+            if (!domKeyString) {
+              tempStr += KeyUtil.getReadableNameForKeyCode(keyCode);
+              break;
+            }
+
+            // Upper case single-lettered key strings for better tts.
+            if (domKeyString.length === 1) {
+              domKeyString = domKeyString.toUpperCase();
+            }
+
+            tempStr += domKeyString;
+            break;
         }
         if (str.indexOf(modifier) === -1) {
           tempStr += modifier + '+';
diff --git a/chrome/browser/resources/chromeos/login/fingerprint_setup.html b/chrome/browser/resources/chromeos/login/fingerprint_setup.html
index 757e2ec..ad67f77 100644
--- a/chrome/browser/resources/chromeos/login/fingerprint_setup.html
+++ b/chrome/browser/resources/chromeos/login/fingerprint_setup.html
@@ -39,12 +39,18 @@
     <oobe-adaptive-dialog id="setupFingerprint" role="dialog" for-step="start"
         footer-shrinkable
         aria-label$="[[i18nDynamic(locale, 'setupFingerprintScreenAriaLabel')]]">
-      <h1 slot="title">
+      <h1 slot="title" hidden="[[isChildAccount_]]">
         [[i18nDynamic(locale, 'setupFingerprintScreenTitle')]]
       </h1>
-      <p slot="subtitle">
+      <h1 slot="title" hidden="[[!isChildAccount_]]">
+        [[i18nDynamic(locale, 'setupFingerprintScreenTitleForChild')]]
+      </h1>
+      <p slot="subtitle" hidden="[[isChildAccount_]]">
         [[i18nDynamic(locale, 'setupFingerprintScreenDescription')]]
       </p>
+      <p slot="subtitle" hidden="[[!isChildAccount_]]">
+        [[i18nDynamic(locale, 'setupFingerprintScreenDescriptionForChild')]]
+      </p>
       <iron-icon slot="icon" icon="oobe-32:fingerprint"></iron-icon>
       <div slot="content" class="flex layout vertical center center-justified">
         <div id="sensorLocationContainer" class="oobe-illustration">
@@ -76,10 +82,22 @@
         [[i18nDynamic(locale, 'setupFingerprintEnrollmentSuccessTitle')]]
       </h1>
       <div slot="subtitle" hidden="[[!complete_]]">
-        [[i18nDynamic(locale, 'setupFingerprintEnrollmentSuccessDescription')]]
+        <div hidden="[[isChildAccount_]]">
+          [[i18nDynamic(locale,
+              'setupFingerprintEnrollmentSuccessDescription')]]
+        </div>
+        <div hidden="[[!isChildAccount_]]">
+          [[i18nDynamic(locale,
+              'setupFingerprintEnrollmentSuccessDescriptionForChild')]]
+        </div>
       </div>
       <div slot="subtitle" hidden="[[!isProblemImmobile_(scanResult_)]]">
-        [[i18nDynamic(locale, 'setupFingerprintScanMoveFinger')]]
+        <div hidden="[[isChildAccount_]]">
+          [[i18nDynamic(locale, 'setupFingerprintScanMoveFinger')]]
+        </div>
+        <div hidden="[[!isChildAccount_]]">
+          [[i18nDynamic(locale, 'setupFingerprintScanMoveFingerForChild')]]
+        </div>
       </div>
       <div slot="subtitle" hidden="[[!isProblemOther_(scanResult_)]]">
         [[i18nDynamic(locale, 'setupFingerprintScanTryAgain')]]
diff --git a/chrome/browser/resources/chromeos/login/fingerprint_setup.js b/chrome/browser/resources/chromeos/login/fingerprint_setup.js
index 1e66016b..8a036a9 100644
--- a/chrome/browser/resources/chromeos/login/fingerprint_setup.js
+++ b/chrome/browser/resources/chromeos/login/fingerprint_setup.js
@@ -105,7 +105,16 @@
         return loadTimeData.getBoolean('useLottieAnimationForFingerprint');
       },
       readOnly: true,
-    }
+    },
+
+    /**
+     * Indicates whether user is a child account.
+     * @type {boolean}
+     */
+    isChildAccount_: {
+      type: Boolean,
+      value: false,
+    },
   },
 
   ready() {
@@ -123,7 +132,8 @@
     return UIState.START;
   },
 
-  onBeforeShow() {
+  onBeforeShow(data) {
+    this.isChildAccount_ = data['isChildAccount'];
     this.setAnimationState_(true);
   },
 
diff --git a/chrome/browser/resources/new_tab_page/BUILD.gn b/chrome/browser/resources/new_tab_page/BUILD.gn
index cf2cccf..2acff1b2 100644
--- a/chrome/browser/resources/new_tab_page/BUILD.gn
+++ b/chrome/browser/resources/new_tab_page/BUILD.gn
@@ -117,7 +117,6 @@
     ":new_tab_page_proxy",
     ":utils",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_components/customize_themes",
     "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
     "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
   ]
@@ -455,11 +454,12 @@
     deps = [
       ":preprocess",
       ":preprocess_gen",
-      "../../../../ui/webui/resources:preprocess",
       "modules:preprocess",
       "modules:preprocess_gen",
       "realbox:preprocess",
       "realbox:preprocess_gen",
+      "//ui/webui/resources:preprocess",
+      "//ui/webui/resources/cr_components/customize_themes:build_ts",
     ]
     js_module_in_files = [
       "new_tab_page.js",
diff --git a/chrome/browser/resources/new_tab_page/customize_dialog.js b/chrome/browser/resources/new_tab_page/customize_dialog.js
index 779e516..92087087 100644
--- a/chrome/browser/resources/new_tab_page/customize_dialog.js
+++ b/chrome/browser/resources/new_tab_page/customize_dialog.js
@@ -21,6 +21,16 @@
 import {NewTabPageProxy} from './new_tab_page_proxy.js';
 import {createScrollBorders} from './utils.js';
 
+
+/**
+ * Workaround until new_tab_page is migrated to TypeScript.
+ * @interface
+ */
+class CustomizeThemesElement {
+  revertThemeChanges() {}
+  confirmThemeChanges() {}
+}
+
 /**
  * Dialog that lets the user customize the NTP such as the background color or
  * image.
@@ -126,7 +136,8 @@
 
   /** @private */
   onCancel_() {
-    this.$.customizeThemes.revertThemeChanges();
+    /** @type {CustomizeThemesElement} */ (this.$.customizeThemes)
+        .revertThemeChanges();
     this.backgroundSelection = {type: BackgroundSelectionType.NO_SELECTION};
   }
 
@@ -148,7 +159,8 @@
    * @private
    */
   onDoneClick_() {
-    this.$.customizeThemes.confirmThemeChanges();
+    /** @type {CustomizeThemesElement} */ (this.$.customizeThemes)
+        .confirmThemeChanges();
     this.shadowRoot.querySelector('ntp-customize-shortcuts').apply();
     if (this.modulesEnabled_) {
       this.shadowRoot.querySelector('ntp-customize-modules').apply();
diff --git a/chrome/browser/resources/new_tab_page/modules/modules.html b/chrome/browser/resources/new_tab_page/modules/modules.html
index 5a9b6fd..21885b8 100644
--- a/chrome/browser/resources/new_tab_page/modules/modules.html
+++ b/chrome/browser/resources/new_tab_page/modules/modules.html
@@ -7,15 +7,20 @@
     width: var(--ntp-module-width);
   }
 
-  ntp-module-wrapper + ntp-module-wrapper {
-    margin-top: 16px;
+  .module-container + .module-container {
+    padding-top: 16px;
   }
 
   #removeModuleToastMessage {
     flex-grow: 1;
   }
 
+  [draggable] {
+    cursor: grab;
+  }
+
   [dragging] {
+    pointer-events: none;
     position: fixed;
     z-index: 2;
   }
diff --git a/chrome/browser/resources/new_tab_page/modules/modules.js b/chrome/browser/resources/new_tab_page/modules/modules.js
index c92c8a88..f9dc5eef 100644
--- a/chrome/browser/resources/new_tab_page/modules/modules.js
+++ b/chrome/browser/resources/new_tab_page/modules/modules.js
@@ -152,7 +152,11 @@
               (event));
         });
         moduleWrapper.hidden = this.moduleDisabled_(module.descriptor.id);
-        this.$.modules.appendChild(moduleWrapper);
+
+        const moduleContainer = this.ownerDocument.createElement('div');
+        moduleContainer.classList.add('module-container');
+        moduleContainer.appendChild(moduleWrapper);
+        this.$.modules.appendChild(moduleContainer);
       });
       this.onModulesLoaded_();
     }
@@ -323,10 +327,8 @@
       y: e.y - dragElementRect.y,
     };
 
-    const moduleWrappers = Array.from(this.$.modules.childNodes);
-
-    const dragIndex = moduleWrappers.indexOf(dragElement);
-    let dropIndex = dragIndex;
+    dragElement.parentElement.style.width = `${dragElementRect.width}px`;
+    dragElement.parentElement.style.height = `${dragElementRect.height}px`;
 
     const dragOver = e => {
       e.preventDefault();
@@ -337,29 +339,40 @@
       dragElement.setAttribute('dragging', '');
       dragElement.style.left = `${e.x - dragOffset.x}px`;
       dragElement.style.top = `${e.y - dragOffset.y}px`;
-
-      const moduleRects = moduleWrappers.map(m => m.getBoundingClientRect());
-      moduleRects.splice(dragIndex, 1);
-      dropIndex = moduleRects.findIndex(
-          r => e.x >= r.left && e.x <= r.right && e.y >= r.top &&
-              e.y <= r.bottom);
-      dropIndex = (dropIndex > -1) ? dropIndex : dragIndex;
     };
 
+    const dragEnter = e => {
+      const moduleContainers = Array.from(this.$.modules.childNodes);
+      const dragIndex = moduleContainers.indexOf(dragElement.parentElement);
+      const dropIndex = moduleContainers.indexOf(e.target.parentElement);
+
+      const positionType = dragIndex > dropIndex ? 'beforebegin' : 'afterend';
+      const dragContainer = moduleContainers[dragIndex];
+      const previousContainer = moduleContainers[dropIndex];
+
+      dragContainer.remove();
+      previousContainer.insertAdjacentElement(positionType, dragContainer);
+    };
+
+    const undraggedModuleWrappers =
+        Array.from(this.shadowRoot.querySelectorAll('ntp-module-wrapper'))
+            .filter(moduleWrapper => moduleWrapper !== dragElement);
+
+    undraggedModuleWrappers.forEach(moduleWrapper => {
+      moduleWrapper.addEventListener('dragenter', dragEnter);
+    });
+
     this.ownerDocument.addEventListener('dragover', dragOver);
     this.ownerDocument.addEventListener('dragend', () => {
       this.ownerDocument.removeEventListener('dragover', dragOver);
 
-      const [draggingModule] = moduleWrappers.splice(dragIndex, 1);
-      draggingModule.removeAttribute('dragging');
-      draggingModule.style.removeProperty('left');
-      draggingModule.style.removeProperty('top');
-      moduleWrappers.splice(dropIndex, 0, draggingModule);
-
-      moduleWrappers.forEach(moduleWrapper => {
-        moduleWrapper.remove();
-        this.$.modules.appendChild(moduleWrapper);
+      undraggedModuleWrappers.forEach(moduleWrapper => {
+        moduleWrapper.removeEventListener('dragenter', dragEnter);
       });
+
+      dragElement.removeAttribute('dragging');
+      dragElement.style.removeProperty('left');
+      dragElement.style.removeProperty('top');
     }, {once: true});
   }
 }
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn
index de135acf..de3bca1 100644
--- a/chrome/browser/resources/settings/BUILD.gn
+++ b/chrome/browser/resources/settings/BUILD.gn
@@ -41,6 +41,10 @@
       "//ui/webui/resources:preprocess",
     ]
 
+    if (!is_chromeos) {
+      deps += [ "//ui/webui/resources/cr_components/customize_themes:build_ts" ]
+    }
+
     if (use_nss_certs) {
       deps +=
           [ "//ui/webui/resources/cr_components/certificate_manager:build_ts" ]
@@ -116,7 +120,7 @@
     "autofill_page/multi_store_exception_entry.js",
     "autofill_page/multi_store_id_handler.js",
     "autofill_page/multi_store_password_ui_entry.js",
-    "autofill_page/password_check_behavior.js",
+    "autofill_page/password_check_mixin.js",
     "autofill_page/password_manager_proxy.js",
     "autofill_page/show_password_mixin.js",
     "base_mixin.js",
@@ -158,7 +162,7 @@
     "search_settings.js",
     "setting_id_param_util.js",
     "settings.js",
-    "settings_page/main_page_behavior.js",
+    "settings_page/main_page_mixin.js",
     "settings_routes.js",
     "site_settings/constants.js",
     "site_settings/cookie_info.js",
diff --git a/chrome/browser/resources/settings/autofill_page/BUILD.gn b/chrome/browser/resources/settings/autofill_page/BUILD.gn
index 0f6b0e3..ff2a146e 100644
--- a/chrome/browser/resources/settings/autofill_page/BUILD.gn
+++ b/chrome/browser/resources/settings/autofill_page/BUILD.gn
@@ -24,10 +24,10 @@
     ":multi_store_id_handler",
     ":multi_store_password_ui_entry",
     ":password_check",
-    ":password_check_behavior",
     ":password_check_edit_dialog",
     ":password_check_edit_disclaimer_dialog",
     ":password_check_list_item",
+    ":password_check_mixin",
     ":password_edit_dialog",
     ":password_list_item",
     ":password_manager_proxy",
@@ -59,7 +59,7 @@
 
 js_library("autofill_page") {
   deps = [
-    ":password_check_behavior",
+    ":password_check_mixin",
     "..:hats_browser_proxy",
     "..:open_window_proxy",
     "..:route",
@@ -126,7 +126,7 @@
 js_library("password_check") {
   deps = [
     ":blocking_request_manager",
-    ":password_check_behavior",
+    ":password_check_mixin",
     ":password_manager_proxy",
     "..:route",
     "../prefs:prefs_behavior",
@@ -136,7 +136,7 @@
   ]
 }
 
-js_library("password_check_behavior") {
+js_library("password_check_mixin") {
   deps = [
     ":password_manager_proxy",
     "//ui/webui/resources/js:plural_string_proxy",
diff --git a/chrome/browser/resources/settings/autofill_page/autofill_page.js b/chrome/browser/resources/settings/autofill_page/autofill_page.js
index fc7b63c86..71e9f55 100644
--- a/chrome/browser/resources/settings/autofill_page/autofill_page.js
+++ b/chrome/browser/resources/settings/autofill_page/autofill_page.js
@@ -21,7 +21,7 @@
 import {routes} from '../route.js';
 import {Router} from '../router.js';
 
-import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_behavior.js';
+import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_mixin.js';
 import {PasswordManagerImpl} from './password_manager_proxy.js';
 
 
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.js b/chrome/browser/resources/settings/autofill_page/password_check.js
index e8bf8618b..ede29af 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check.js
+++ b/chrome/browser/resources/settings/autofill_page/password_check.js
@@ -39,7 +39,7 @@
 // <if expr="chromeos">
 import {BlockingRequestManager} from './blocking_request_manager.js';
 // </if>
-import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_behavior.js';
+import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_mixin.js';
 import {PasswordManagerImpl, PasswordManagerProxy} from './password_manager_proxy.js';
 
 
diff --git a/chrome/browser/resources/settings/autofill_page/password_check_behavior.js b/chrome/browser/resources/settings/autofill_page/password_check_mixin.js
similarity index 100%
rename from chrome/browser/resources/settings/autofill_page/password_check_behavior.js
rename to chrome/browser/resources/settings/autofill_page/password_check_mixin.js
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chrome/browser/resources/settings/autofill_page/passwords_section.js
index f4261af..ad00252 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_section.js
+++ b/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -44,7 +44,7 @@
 import {Router} from '../router.js';
 import '../settings_shared_css.js';
 import '../site_favicon.js';
-import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_behavior.js';
+import {PasswordCheckMixin, PasswordCheckMixinInterface} from './password_check_mixin.js';
 import './password_list_item.js';
 import './passwords_list_handler.js';
 import {PasswordManagerImpl, PasswordManagerProxy} from './password_manager_proxy.js';
diff --git a/chrome/browser/resources/settings/basic_page/BUILD.gn b/chrome/browser/resources/settings/basic_page/BUILD.gn
index 393695d..7a463f9 100644
--- a/chrome/browser/resources/settings/basic_page/BUILD.gn
+++ b/chrome/browser/resources/settings/basic_page/BUILD.gn
@@ -23,7 +23,7 @@
     "../privacy_page:privacy_page",
     "../safety_check_page:safety_check_page",
     "../search_page",
-    "../settings_page:main_page_behavior",
+    "../settings_page:main_page_mixin",
     "//ui/webui/resources/js:load_time_data.m",
   ]
 }
diff --git a/chrome/browser/resources/settings/basic_page/basic_page.js b/chrome/browser/resources/settings/basic_page/basic_page.js
index 30fb080e..497f68b 100644
--- a/chrome/browser/resources/settings/basic_page/basic_page.js
+++ b/chrome/browser/resources/settings/basic_page/basic_page.js
@@ -41,7 +41,7 @@
 import {routes} from '../route.js';
 import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../router.js';
 import {getSearchManager, SearchResult} from '../search_settings.js';
-import {MainPageMixin, MainPageMixinInterface} from '../settings_page/main_page_behavior.js';
+import {MainPageMixin, MainPageMixinInterface} from '../settings_page/main_page_mixin.js';
 
 // <if expr="chromeos or lacros">
 const OS_BANNER_INTERACTION_METRIC_NAME =
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn
index 34b727d..56fbac3f 100644
--- a/chrome/browser/resources/settings/chromeos/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -215,6 +215,8 @@
     "chromeos/date_time_page/timezone_browser_proxy.js",
     "chromeos/google_assistant_page/google_assistant_browser_proxy.js",
     "chromeos/guest_os/guest_os_browser_proxy.js",
+    "chromeos/internet_page/cellular_setup_settings_delegate.js",
+    "chromeos/internet_page/internet_page_browser_proxy.js",
     "chromeos/os_languages_page/input_method_settings.js",
     "chromeos/os_printing_page/cups_printers_entry_list_behavior.js",
     "chromeos/os_printing_page/cups_printer_dialog_util.js",
@@ -306,26 +308,24 @@
     "chromeos/google_assistant_page/google_assistant_page.js",
     "chromeos/guest_os/guest_os_shared_paths.js",
     "chromeos/guest_os/guest_os_shared_usb_devices.js",
-    "chromeos/internet_page/esim_install_error_dialog.m.js",
-    "chromeos/internet_page/esim_remove_profile_dialog.m.js",
-    "chromeos/internet_page/esim_rename_dialog.m.js",
-    "chromeos/internet_page/cellular_networks_list.m.js",
-    "chromeos/internet_page/cellular_roaming_toggle_button.m.js",
-    "chromeos/internet_page/cellular_setup_dialog.m.js",
-    "chromeos/internet_page/cellular_setup_settings_delegate.m.js",
-    "chromeos/internet_page/internet_config.m.js",
-    "chromeos/internet_page/internet_detail_menu.m.js",
-    "chromeos/internet_page/internet_detail_page.m.js",
-    "chromeos/internet_page/internet_known_networks_page.m.js",
-    "chromeos/internet_page/internet_page.m.js",
-    "chromeos/internet_page/internet_page_browser_proxy.m.js",
-    "chromeos/internet_page/internet_shared_css.m.js",
-    "chromeos/internet_page/internet_subpage.m.js",
-    "chromeos/internet_page/network_always_on_vpn.m.js",
-    "chromeos/internet_page/network_proxy_section.m.js",
-    "chromeos/internet_page/network_summary.m.js",
-    "chromeos/internet_page/network_summary_item.m.js",
-    "chromeos/internet_page/tether_connection_dialog.m.js",
+    "chromeos/internet_page/esim_install_error_dialog.js",
+    "chromeos/internet_page/esim_remove_profile_dialog.js",
+    "chromeos/internet_page/esim_rename_dialog.js",
+    "chromeos/internet_page/cellular_networks_list.js",
+    "chromeos/internet_page/cellular_roaming_toggle_button.js",
+    "chromeos/internet_page/cellular_setup_dialog.js",
+    "chromeos/internet_page/internet_config.js",
+    "chromeos/internet_page/internet_detail_menu.js",
+    "chromeos/internet_page/internet_detail_page.js",
+    "chromeos/internet_page/internet_known_networks_page.js",
+    "chromeos/internet_page/internet_page.js",
+    "chromeos/internet_page/internet_shared_css.js",
+    "chromeos/internet_page/internet_subpage.js",
+    "chromeos/internet_page/network_always_on_vpn.js",
+    "chromeos/internet_page/network_proxy_section.js",
+    "chromeos/internet_page/network_summary.js",
+    "chromeos/internet_page/network_summary_item.js",
+    "chromeos/internet_page/tether_connection_dialog.js",
     "chromeos/kerberos_page/kerberos_accounts.m.js",
     "chromeos/kerberos_page/kerberos_accounts_browser_proxy.m.js",
     "chromeos/kerberos_page/kerberos_add_account_dialog.m.js",
@@ -679,7 +679,7 @@
     "device_page:polymer3_elements",
     "google_assistant_page:web_components",
     "guest_os:web_components",
-    "internet_page:polymer3_elements",
+    "internet_page:web_components",
     "kerberos_page:polymer3_elements",
     "keyboard_shortcut_banner:web_components",
     "localized_link:web_components",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
index ad7922e..175642e 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -4,39 +4,37 @@
 
 import("//chrome/browser/resources/settings/chromeos/os_settings.gni")
 import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/polymer/polymer.gni")
-import("//ui/webui/resources/tools/js_modulizer.gni")
+import("//tools/polymer/html_to_js.gni")
 import("../os_settings.gni")
 
 js_type_check("closure_compile_module") {
   closure_flags = os_settings_closure_flags
   is_polymer3 = true
   deps = [
-    ":cellular_networks_list.m",
-    ":cellular_roaming_toggle_button.m",
-    ":cellular_setup_dialog.m",
-    ":cellular_setup_settings_delegate.m",
-    ":esim_install_error_dialog.m",
-    ":esim_remove_profile_dialog.m",
-    ":esim_rename_dialog.m",
-    ":internet_config.m",
-    ":internet_detail_menu.m",
-    ":internet_detail_page.m",
-    ":internet_known_networks_page.m",
-    ":internet_page.m",
-    ":internet_page_browser_proxy.m",
-    ":internet_shared_css.m",
-    ":internet_subpage.m",
-    ":network_always_on_vpn.m",
-    ":network_proxy_section.m",
-    ":network_summary.m",
-    ":network_summary_item.m",
-    ":tether_connection_dialog.m",
+    ":cellular_networks_list",
+    ":cellular_roaming_toggle_button",
+    ":cellular_setup_dialog",
+    ":cellular_setup_settings_delegate",
+    ":esim_install_error_dialog",
+    ":esim_remove_profile_dialog",
+    ":esim_rename_dialog",
+    ":internet_config",
+    ":internet_detail_menu",
+    ":internet_detail_page",
+    ":internet_known_networks_page",
+    ":internet_page",
+    ":internet_page_browser_proxy",
+    ":internet_shared_css",
+    ":internet_subpage",
+    ":network_always_on_vpn",
+    ":network_proxy_section",
+    ":network_summary",
+    ":network_summary_item",
+    ":tether_connection_dialog",
   ]
 }
 
-js_library("cellular_setup_dialog.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.m.js" ]
+js_library("cellular_setup_dialog") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_setup.m",
@@ -44,13 +42,11 @@
     "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":cellular_setup_dialog_module" ]
 }
 
-js_library("internet_config.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_config.m.js" ]
+js_library("internet_config") {
   deps = [
-    ":internet_shared_css.m",
+    ":internet_shared_css",
     "//chrome/browser/resources/settings:router",
     "//chrome/browser/resources/settings/chromeos:metrics_recorder.m",
     "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout",
@@ -62,11 +58,9 @@
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:util.m",
   ]
-  extra_deps = [ ":internet_config_module" ]
 }
 
-js_library("internet_detail_menu.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.m.js" ]
+js_library("internet_detail_menu") {
   deps = [
     "//chrome/browser/resources/settings:router",
     "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m",
@@ -78,17 +72,15 @@
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  extra_deps = [ ":internet_detail_menu_module" ]
 }
 
-js_library("internet_detail_page.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.m.js" ]
+js_library("internet_detail_page") {
   deps = [
-    ":cellular_roaming_toggle_button.m",
-    ":internet_page_browser_proxy.m",
-    ":internet_shared_css.m",
-    ":network_proxy_section.m",
-    ":tether_connection_dialog.m",
+    ":cellular_roaming_toggle_button",
+    ":internet_page_browser_proxy",
+    ":internet_shared_css",
+    ":network_proxy_section",
+    ":tether_connection_dialog",
     "//chrome/browser/resources/settings:router",
     "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m",
     "//chrome/browser/resources/settings/chromeos:metrics_recorder.m",
@@ -123,13 +115,11 @@
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  extra_deps = [ ":internet_detail_page_module" ]
 }
 
-js_library("internet_known_networks_page.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.m.js" ]
+js_library("internet_known_networks_page") {
   deps = [
-    ":internet_shared_css.m",
+    ":internet_shared_css",
     "//chrome/browser/resources/settings:router",
     "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m",
     "//chrome/browser/resources/settings/chromeos:metrics_recorder.m",
@@ -144,21 +134,19 @@
     "//ui/webui/resources/cr_elements/cr_link_row:cr_link_row",
     "//ui/webui/resources/js:assert.m",
   ]
-  extra_deps = [ ":internet_known_networks_page_module" ]
 }
 
-js_library("internet_page.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_page.m.js" ]
+js_library("internet_page") {
   deps = [
-    ":cellular_setup_dialog.m",
-    ":esim_remove_profile_dialog.m",
-    ":esim_rename_dialog.m",
-    ":internet_config.m",
-    ":internet_detail_page.m",
-    ":internet_known_networks_page.m",
-    ":internet_page_browser_proxy.m",
-    ":internet_subpage.m",
-    ":network_summary.m",
+    ":cellular_setup_dialog",
+    ":esim_remove_profile_dialog",
+    ":esim_rename_dialog",
+    ":internet_config",
+    ":internet_detail_page",
+    ":internet_known_networks_page",
+    ":internet_page_browser_proxy",
+    ":internet_subpage",
+    ":network_summary",
     "//chrome/browser/resources/settings:router",
     "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m",
     "//chrome/browser/resources/settings/chromeos:metrics_recorder.m",
@@ -182,34 +170,26 @@
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  extra_deps = [ ":internet_page_module" ]
 }
 
-js_library("internet_page_browser_proxy.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.m.js" ]
-  extra_deps = [ ":modulize" ]
+js_library("internet_page_browser_proxy") {
 }
 
-js_library("cellular_setup_settings_delegate.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.m.js" ]
+js_library("cellular_setup_settings_delegate") {
   deps = [
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_setup_delegate.m",
     "//ui/webui/resources/js:cr.m",
   ]
-  extra_deps = [ ":modulize" ]
 }
 
-js_library("internet_shared_css.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.m.js" ]
-  extra_deps = [ ":internet_shared_css_module" ]
+js_library("internet_shared_css") {
 }
 
-js_library("internet_subpage.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.m.js" ]
+js_library("internet_subpage") {
   deps = [
-    ":cellular_networks_list.m",
-    ":internet_page_browser_proxy.m",
-    ":network_always_on_vpn.m",
+    ":cellular_networks_list",
+    ":internet_page_browser_proxy",
+    ":network_always_on_vpn",
     "//chrome/browser/resources/settings:router",
     "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m",
     "//chrome/browser/resources/settings/chromeos:metrics_recorder.m",
@@ -230,25 +210,21 @@
     "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":internet_subpage_module" ]
 }
 
-js_library("network_always_on_vpn.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.m.js" ]
+js_library("network_always_on_vpn") {
   deps = [
-    ":internet_shared_css.m",
+    ":internet_shared_css",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":network_always_on_vpn_module" ]
 }
 
-js_library("network_proxy_section.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.m.js" ]
+js_library("network_proxy_section") {
   deps = [
-    ":internet_shared_css.m",
+    ":internet_shared_css",
     "//chrome/browser/resources/settings:router",
     "//chrome/browser/resources/settings/chromeos:os_route.m",
     "//chrome/browser/resources/settings/controls:extension_controlled_indicator",
@@ -263,23 +239,19 @@
     "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":network_proxy_section_module" ]
 }
 
-js_library("network_summary.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/network_summary.m.js" ]
+js_library("network_summary") {
   deps = [
-    ":network_summary_item.m",
+    ":network_summary_item",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//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",
   ]
-  extra_deps = [ ":network_summary_module" ]
 }
 
-js_library("network_summary_item.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.m.js" ]
+js_library("network_summary_item") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout-classes",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
@@ -294,11 +266,9 @@
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":network_summary_item_module" ]
 }
 
-js_library("tether_connection_dialog.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.m.js" ]
+js_library("tether_connection_dialog") {
   deps = [
     "//chrome/browser/resources/settings/chromeos:os_route.m",
     "//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile",
@@ -311,13 +281,11 @@
     "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":tether_connection_dialog_module" ]
 }
 
-js_library("cellular_networks_list.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.m.js" ]
+js_library("cellular_networks_list") {
   deps = [
-    ":esim_install_error_dialog.m",
+    ":esim_install_error_dialog",
     "../multidevice_page:multidevice_browser_proxy.m",
     "../multidevice_page:multidevice_constants.m",
     "//chrome/browser/resources/settings/chromeos/localized_link:localized_link",
@@ -332,11 +300,9 @@
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:web_ui_listener_behavior.m",
   ]
-  extra_deps = [ ":cellular_networks_list_module" ]
 }
 
-js_library("cellular_roaming_toggle_button.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.m.js" ]
+js_library("cellular_roaming_toggle_button") {
   deps = [
     "//chrome/browser/resources/settings/controls:settings_toggle_button",
     "//chrome/browser/resources/settings/prefs:prefs",
@@ -345,11 +311,9 @@
     "//ui/webui/resources/js:i18n_behavior.m",
     "//ui/webui/resources/js:load_time_data.m",
   ]
-  extra_deps = [ ":cellular_roaming_toggle_button_module" ]
 }
 
-js_library("esim_install_error_dialog.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.m.js" ]
+js_library("esim_install_error_dialog") {
   deps = [
     "//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite",
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils.m",
@@ -357,22 +321,18 @@
     "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":esim_install_error_dialog_module" ]
 }
 
-js_library("esim_rename_dialog.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.m.js" ]
+js_library("esim_rename_dialog") {
   deps = [
     "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_utils.m",
     "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
     "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":esim_rename_dialog_module" ]
 }
 
-js_library("esim_remove_profile_dialog.m") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.m.js" ]
+js_library("esim_remove_profile_dialog") {
   deps = [
     "//chrome/browser/resources/settings:router",
     "//chrome/browser/resources/settings/chromeos:os_route.m",
@@ -382,198 +342,27 @@
     "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
     "//ui/webui/resources/js:i18n_behavior.m",
   ]
-  extra_deps = [ ":esim_remove_profile_dialog_module" ]
 }
 
-group("polymer3_elements") {
-  public_deps = [
-    ":cellular_networks_list_module",
-    ":cellular_roaming_toggle_button_module",
-    ":cellular_setup_dialog_module",
-    ":esim_install_error_dialog_module",
-    ":esim_remove_profile_dialog_module",
-    ":esim_rename_dialog_module",
-    ":internet_config_module",
-    ":internet_detail_menu_module",
-    ":internet_detail_page_module",
-    ":internet_known_networks_page_module",
-    ":internet_page_module",
-    ":internet_shared_css_module",
-    ":internet_subpage_module",
-    ":modulize",
-    ":network_always_on_vpn_module",
-    ":network_proxy_section_module",
-    ":network_summary_item_module",
-    ":network_summary_module",
-    ":tether_connection_dialog_module",
+html_to_js("web_components") {
+  js_files = [
+    "cellular_networks_list.js",
+    "cellular_roaming_toggle_button.js",
+    "cellular_setup_dialog.js",
+    "esim_install_error_dialog.js",
+    "esim_remove_profile_dialog.js",
+    "esim_rename_dialog.js",
+    "internet_config.js",
+    "internet_detail_menu.js",
+    "internet_detail_page.js",
+    "internet_known_networks_page.js",
+    "internet_page.js",
+    "internet_shared_css.js",
+    "internet_subpage.js",
+    "network_always_on_vpn.js",
+    "network_proxy_section.js",
+    "network_summary_item.js",
+    "network_summary.js",
+    "tether_connection_dialog.js",
   ]
 }
-
-polymer_modulizer("internet_config") {
-  js_file = "internet_config.js"
-  html_file = "internet_config.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("internet_detail_menu") {
-  js_file = "internet_detail_menu.js"
-  html_file = "internet_detail_menu.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("internet_detail_page") {
-  js_file = "internet_detail_page.js"
-  html_file = "internet_detail_page.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports + [ "chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.html|InternetPageBrowserProxy,InternetPageBrowserProxyImpl" ]
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("internet_known_networks_page") {
-  js_file = "internet_known_networks_page.js"
-  html_file = "internet_known_networks_page.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("internet_page") {
-  js_file = "internet_page.js"
-  html_file = "internet_page.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("internet_shared_css") {
-  js_file = "internet_shared_css.m.js"
-  html_file = "internet_shared_css.html"
-  html_type = "style-module"
-  migrated_imports = os_settings_migrated_imports
-}
-
-polymer_modulizer("internet_subpage") {
-  js_file = "internet_subpage.js"
-  html_file = "internet_subpage.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("network_always_on_vpn") {
-  js_file = "network_always_on_vpn.js"
-  html_file = "network_always_on_vpn.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("network_proxy_section") {
-  js_file = "network_proxy_section.js"
-  html_file = "network_proxy_section.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports + [ "chrome/browser/resources/settings/controls/settings_toggle_button.html|SettingsToggleButtonElement" ]
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("network_summary") {
-  js_file = "network_summary.js"
-  html_file = "network_summary.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("network_summary_item") {
-  js_file = "network_summary_item.js"
-  html_file = "network_summary_item.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("tether_connection_dialog") {
-  js_file = "tether_connection_dialog.js"
-  html_file = "tether_connection_dialog.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites =
-      [ "cros_network_config.mojom.m.js|cros_network_config.mojom-lite.js" ]
-}
-
-polymer_modulizer("cellular_setup_dialog") {
-  js_file = "cellular_setup_dialog.js"
-  html_file = "cellular_setup_dialog.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("cellular_networks_list") {
-  js_file = "cellular_networks_list.js"
-  html_file = "cellular_networks_list.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("cellular_roaming_toggle_button") {
-  js_file = "cellular_roaming_toggle_button.js"
-  html_file = "cellular_roaming_toggle_button.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports + [ "chrome/browser/resources/settings/controls/settings_toggle_button.html|SettingsToggleButtonElement" ]
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("esim_install_error_dialog") {
-  js_file = "esim_install_error_dialog.js"
-  html_file = "esim_install_error_dialog.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("esim_rename_dialog") {
-  js_file = "esim_rename_dialog.js"
-  html_file = "esim_rename_dialog.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-polymer_modulizer("esim_remove_profile_dialog") {
-  js_file = "esim_remove_profile_dialog.js"
-  html_file = "esim_remove_profile_dialog.html"
-  html_type = "dom-module"
-  auto_imports = os_settings_auto_imports
-  migrated_imports = os_settings_migrated_imports
-  namespace_rewrites = os_settings_namespace_rewrites
-}
-
-js_modulizer("modulize") {
-  input_files = [
-    "internet_page_browser_proxy.js",
-    "cellular_setup_settings_delegate.js",
-  ]
-  namespace_rewrites = os_settings_namespace_rewrites
-}
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html
index 0ee0445..df33c50 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html
@@ -1,240 +1,211 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="cr-shared-style os-settings-icons settings-shared iron-flex">
+  :host > div {
+    /* network-list is padded to the right to allow space for a ripple */
+    padding-inline-end: calc(var(--cr-section-padding) -
+        var(--cr-icon-ripple-padding));
+    padding-inline-start: var(--cr-section-padding);
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_eid_dialog.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cellular_utils.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_list_types.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="../multidevice_page/multidevice_browser_proxy.html">
-<link rel="import" href="../multidevice_page/multidevice_constants.html">
-<link rel="import" href="../../chromeos/os_settings_icons_css.html">
-<link rel="import" href="esim_install_error_dialog.html">
+  .cellular-network-list-separator {
+    border-top: var(--cr-separator-line);
+    padding: 0;
+  }
 
-<dom-module id="cellular-networks-list">
-  <template>
-    <style include="cr-shared-style os-settings-icons settings-shared iron-flex">
-      :host > div {
-        /* network-list is padded to the right to allow space for a ripple */
-        padding-inline-end: calc(var(--cr-section-padding) -
-            var(--cr-icon-ripple-padding));
-        padding-inline-start: var(--cr-section-padding);
-      }
+  .cellular-network-list-header {
+    align-items: center;
+    display: flex;
+    height: 72px;
+  }
 
-      .cellular-network-list-separator {
-        border-top: var(--cr-separator-line);
-        padding: 0;
-      }
+  .esim-list-title {
+    align-self: center;
+  }
 
-      .cellular-network-list-header {
-        align-items: center;
-        display: flex;
-        height: 72px;
-      }
+  .cellular-network-content {
+    margin-inline-start: 32px;
+  }
 
-      .esim-list-title {
-        align-self: center;
-      }
+  .cellular-not-setup {
+    color: var(--google-grey-700);
+    font-size: small;
+    margin-bottom: 16px;
+  }
 
-      .cellular-network-content {
-        margin-inline-start: 32px;
-      }
+  .flex {
+    display: flex;
+  }
 
-      .cellular-not-setup {
-        color: var(--google-grey-700);
-        font-size: small;
-        margin-bottom: 16px;
-      }
+  .flex-column {
+    display: flex;
+    flex-direction: column;
+  }
 
-      .flex {
-        display: flex;
-      }
+  #eidPopupButton {
+    --cr-icon-button-size: 18px;
+    cursor: pointer;
+    margin-inline-start: 4px;
+  }
 
-      .flex-column {
-        display: flex;
-        flex-direction: column;
-      }
+  :host-context([dir='rtl']) #addESimButton {
+    transform: scaleX(1);
+  }
 
-      #eidPopupButton {
-        --cr-icon-button-size: 18px;
-        cursor: pointer;
-        margin-inline-start: 4px;
-      }
+  #alignEnd {
+    align-items: center;
+    display: flex;
+    margin-inline-end: 12px;
+    margin-inline-start: auto;
+  }
 
-      :host-context([dir='rtl']) #addESimButton {
-        transform: scaleX(1);
-      }
+  #inhibitedSubtext {
+    color: var(--cr-secondary-text-color);
+  }
 
-      #alignEnd {
-        align-items: center;
-        display: flex;
-        margin-inline-end: 12px;
-        margin-inline-start: auto;
-      }
+  paper-spinner-lite {
+    height: 20px;
+    width: 20px;
+  }
 
-      #inhibitedSubtext {
-        color: var(--cr-secondary-text-color);
-      }
-
-      paper-spinner-lite {
-        height: 20px;
-        width: 20px;
-      }
-
-      .separator {
-        margin-inline-end: 0;
-        margin-inline-start: 24px;
-      }
-    </style>
-    <template is="dom-if" if="[[shouldShowEsimSection_(euicc_,
-        cellularDeviceState, cellularDeviceState.*)]]" restamp>
-      <div class="cellular-network-list-separator"></div>
-        <div class="cellular-network-list-header flex settings-box-text">
-          <div class="flex-column">
-            <div class="flex header-row">
-              $i18n{cellularNetworkEsimLabel}
-            </div>
-            <div id="inhibitedSubtext" class="header-row secondary-box-text"
-                hidden="[[!isDeviceInhibited_]]" aria-live="assertive">
-              [[getInhibitedSubtextMessage_(isDeviceInhibited_)]]
-            </div>
-          </div>
-          <div id="alignEnd">
-            <template is="dom-if" if="[[canShowSpinner]]" restamp>
-              <paper-spinner-lite id="inhibitedSpinner"
-                  active="[[isDeviceInhibited_]]">
-              </paper-spinner-lite>
-            </template>
-            <template is="dom-if" if="[[showAddESimButton_(cellularDeviceState,
-                globalPolicy)]]" restamp>
-              <cr-icon-button class="icon-add-cellular add-button"
-                  aria-label="$i18n{internetAddCellular}" id="addESimButton"
-                  disabled="[[isDeviceInhibited_]]"
-                  on-click="onAddEsimButtonTap_">
-              </cr-icon-button>
-              <div class="separator"></div>
-            </template>
-            <cr-icon-button id="moreESim" class="icon-more-vert"
-                title="$i18n{moreActions}"
-                on-click="onESimDotsClick_">
-            </cr-icon-button>
-            <cr-lazy-render id="menu">
-              <template>
-                <cr-action-menu>
-                  <button class="dropdown-item"
-                      on-click="onShowEidDialogTap_"
-                      role="menuitem">
-                    $i18n{eidPopupMenuItemTitle}
-                  </button>
-                </cr-action-menu>
-              </template>
-            </cr-lazy-render>
-            <template is="dom-if" if="[[shouldShowEidDialog_]]" restamp>
-              <cellular-eid-dialog class="eid-dialog"
-                  on-close="onCloseEidDialog_"
-                  euicc="[[euicc_]]">
-              </cellular-eid-dialog>
-            </template>
-          </div>
+  .separator {
+    margin-inline-end: 0;
+    margin-inline-start: 24px;
+  }
+</style>
+<template is="dom-if" if="[[shouldShowEsimSection_(euicc_,
+    cellularDeviceState, cellularDeviceState.*)]]" restamp>
+  <div class="cellular-network-list-separator"></div>
+    <div class="cellular-network-list-header flex settings-box-text">
+      <div class="flex-column">
+        <div class="flex header-row">
+          $i18n{cellularNetworkEsimLabel}
+        </div>
+        <div id="inhibitedSubtext" class="header-row secondary-box-text"
+            hidden="[[!isDeviceInhibited_]]" aria-live="assertive">
+          [[getInhibitedSubtextMessage_(isDeviceInhibited_)]]
         </div>
       </div>
-      <template is="dom-if" if="[[shouldShowNetworkSublist_(eSimNetworks_,
-          eSimPendingProfileItems_)]]" restamp>
-        <div class="cellular-network-content">
-          <network-list id="esimNetworkList" show-buttons
-              show-technology-badge="[[showTechnologyBadge]]"
-              networks="[[eSimNetworks_]]"
-              custom-items="[[eSimPendingProfileItems_]]"
-              device-state="[[cellularDeviceState]]">
-          </network-list>
-        </div>
-      </template>
-      <template is="dom-if" if="[[!shouldShowNetworkSublist_(eSimNetworks_,
-          eSimPendingProfileItems_)]]" restamp>
-        <div id="eSimNoNetworkFound"
-            class="cellular-network-content cellular-not-setup">
-          <settings-localized-link
-              link-disabled = "[[isDeviceInhibited_]]"
-              on-link-clicked="onEsimLearnMoreClicked_"
-              localized-string="$i18n{eSimNetworkNotSetup}">
-          </settings-localized-link>
-        </div>
-      </template>
-    </template>
-    <template is="dom-if"
-        if="[[shouldShowPSimSection_(cellularDeviceState,
-          cellularDeviceState.*)]]" restamp>
-      <div class="cellular-network-list-separator"></div>
-      <div class="cellular-network-list-header settings-box-text">
-        $i18n{cellularNetworkPsimLabel}
+      <div id="alignEnd">
+        <template is="dom-if" if="[[canShowSpinner]]" restamp>
+          <paper-spinner-lite id="inhibitedSpinner"
+              active="[[isDeviceInhibited_]]">
+          </paper-spinner-lite>
+        </template>
+        <template is="dom-if" if="[[showAddESimButton_(cellularDeviceState,
+            globalPolicy)]]" restamp>
+          <cr-icon-button class="icon-add-cellular add-button"
+              aria-label="$i18n{internetAddCellular}" id="addESimButton"
+              disabled="[[isDeviceInhibited_]]"
+              on-click="onAddEsimButtonTap_">
+          </cr-icon-button>
+          <div class="separator"></div>
+        </template>
+        <cr-icon-button id="moreESim" class="icon-more-vert"
+            title="$i18n{moreActions}"
+            on-click="onESimDotsClick_">
+        </cr-icon-button>
+        <cr-lazy-render id="menu">
+          <template>
+            <cr-action-menu>
+              <button class="dropdown-item"
+                  on-click="onShowEidDialogTap_"
+                  role="menuitem">
+                $i18n{eidPopupMenuItemTitle}
+              </button>
+            </cr-action-menu>
+          </template>
+        </cr-lazy-render>
+        <template is="dom-if" if="[[shouldShowEidDialog_]]" restamp>
+          <cellular-eid-dialog class="eid-dialog"
+              on-close="onCloseEidDialog_"
+              euicc="[[euicc_]]">
+          </cellular-eid-dialog>
+        </template>
       </div>
-      <template
-          is="dom-if"
-          if="[[shouldShowNetworkSublist_(pSimNetworks_)]]" restamp>
-        <div class="cellular-network-content">
-          <network-list
-              id="psimNetworkList" show-buttons
-              show-technology-badge="[[showTechnologyBadge]]"
-              networks="[[pSimNetworks_]]"
-              device-state="[[cellularDeviceState]]">
-          </network-list>
-        </div>
-      </template>
-      <template
-          is="dom-if"
-          if="[[!shouldShowNetworkSublist_(pSimNetworks_)]]" restamp>
-        <div id="pSimNoNetworkFound"
-            class="cellular-network-content cellular-not-setup">
-          $i18n{pSimNotInsertedLabel}
-        </div>
-      </template>
-    </template>
-    <template is="dom-if"
-        if="[[shouldShowTetherSection_(multiDevicePageContentData_)]]" restamp>
-      <div class="cellular-network-list-separator"></div>
-      <div class="cellular-network-list-header settings-box-text">
-        $i18n{cellularNetworkTetherLabel}
-      </div>
-      <template is="dom-if"
-          if="[[shouldShowNetworkSublist_(tetherNetworks_)]]" restamp>
-        <div class="cellular-network-content">
-          <network-list
-              id="tetherNetworkList" show-buttons
-              show-technology-badge="[[showTechnologyBadge]]"
-              networks="[[tetherNetworks_]]"
-              device-state="[[tetherDeviceState]]">
-          </network-list>
-        </div>
-      </template>
-      <template is="dom-if"
-          if="[[!shouldShowNetworkSublist_(tetherNetworks_)]]" restamp>
-        <div id="tetherNetworksNotSetup"
-            class="cellular-network-content cellular-not-setup">
-          <settings-localized-link
-              localized-string="[[i18nAdvanced('tetherNetworkNotSetup')]]">
-          </settings-localized-link>
-        </div>
-      </template>
-    </template>
-
-    <template is="dom-if" if="[[shouldShowInstallErrorDialog_]]" restamp>
-      <esim-install-error-dialog id="installErrorDialog"
-          on-close="onCloseInstallErrorDialog_"
-          error-code="[[eSimProfileInstallError_]]"
-          profile="[[installingESimProfile_]]">
-      </esim-install-error-dialog>
-    </template>
+    </div>
+  </div>
+  <template is="dom-if" if="[[shouldShowNetworkSublist_(eSimNetworks_,
+      eSimPendingProfileItems_)]]" restamp>
+    <div class="cellular-network-content">
+      <network-list id="esimNetworkList" show-buttons
+          show-technology-badge="[[showTechnologyBadge]]"
+          networks="[[eSimNetworks_]]"
+          custom-items="[[eSimPendingProfileItems_]]"
+          device-state="[[cellularDeviceState]]">
+      </network-list>
+    </div>
   </template>
-  <script src="cellular_networks_list.js"></script>
-</dom-module>
\ No newline at end of file
+  <template is="dom-if" if="[[!shouldShowNetworkSublist_(eSimNetworks_,
+      eSimPendingProfileItems_)]]" restamp>
+    <div id="eSimNoNetworkFound"
+        class="cellular-network-content cellular-not-setup">
+      <settings-localized-link
+          link-disabled = "[[isDeviceInhibited_]]"
+          on-link-clicked="onEsimLearnMoreClicked_"
+          localized-string="$i18n{eSimNetworkNotSetup}">
+      </settings-localized-link>
+    </div>
+  </template>
+</template>
+<template is="dom-if"
+    if="[[shouldShowPSimSection_(cellularDeviceState,
+      cellularDeviceState.*)]]" restamp>
+  <div class="cellular-network-list-separator"></div>
+  <div class="cellular-network-list-header settings-box-text">
+    $i18n{cellularNetworkPsimLabel}
+  </div>
+  <template
+      is="dom-if"
+      if="[[shouldShowNetworkSublist_(pSimNetworks_)]]" restamp>
+    <div class="cellular-network-content">
+      <network-list
+          id="psimNetworkList" show-buttons
+          show-technology-badge="[[showTechnologyBadge]]"
+          networks="[[pSimNetworks_]]"
+          device-state="[[cellularDeviceState]]">
+      </network-list>
+    </div>
+  </template>
+  <template
+      is="dom-if"
+      if="[[!shouldShowNetworkSublist_(pSimNetworks_)]]" restamp>
+    <div id="pSimNoNetworkFound"
+        class="cellular-network-content cellular-not-setup">
+      $i18n{pSimNotInsertedLabel}
+    </div>
+  </template>
+</template>
+<template is="dom-if"
+    if="[[shouldShowTetherSection_(multiDevicePageContentData_)]]" restamp>
+  <div class="cellular-network-list-separator"></div>
+  <div class="cellular-network-list-header settings-box-text">
+    $i18n{cellularNetworkTetherLabel}
+  </div>
+  <template is="dom-if"
+      if="[[shouldShowNetworkSublist_(tetherNetworks_)]]" restamp>
+    <div class="cellular-network-content">
+      <network-list
+          id="tetherNetworkList" show-buttons
+          show-technology-badge="[[showTechnologyBadge]]"
+          networks="[[tetherNetworks_]]"
+          device-state="[[tetherDeviceState]]">
+      </network-list>
+    </div>
+  </template>
+  <template is="dom-if"
+      if="[[!shouldShowNetworkSublist_(tetherNetworks_)]]" restamp>
+    <div id="tetherNetworksNotSetup"
+        class="cellular-network-content cellular-not-setup">
+      <settings-localized-link
+          localized-string="[[i18nAdvanced('tetherNetworkNotSetup')]]">
+      </settings-localized-link>
+    </div>
+  </template>
+</template>
+
+<template is="dom-if" if="[[shouldShowInstallErrorDialog_]]" restamp>
+  <esim-install-error-dialog id="installErrorDialog"
+      on-close="onCloseInstallErrorDialog_"
+      error-code="[[eSimProfileInstallError_]]"
+      profile="[[installingESimProfile_]]">
+  </esim-install-error-dialog>
+</template>
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 37b36ea..ae2ec908 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
@@ -7,7 +7,33 @@
  * states
  */
 
+import '//resources/cr_components/chromeos/cellular_setup/cellular_eid_dialog.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_icons_css.m.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import '//resources/cr_elements/shared_style_css.m.js';
+import '//resources/cr_elements/shared_vars_css.m.js';
+import '../os_settings_icons_css.m.js';
+import './esim_install_error_dialog.js';
+
+import {Button, ButtonBarState, ButtonState, CellularSetupPageName} from '//resources/cr_components/chromeos/cellular_setup/cellular_types.m.js';
+import {ESimManagerListenerBehavior} from '//resources/cr_components/chromeos/cellular_setup/esim_manager_listener_behavior.m.js';
+import {getESimProfile, getESimProfileProperties, getEuicc, getNonPendingESimProfiles, getNumESimProfiles, getPendingESimProfiles} from '//resources/cr_components/chromeos/cellular_setup/esim_manager_utils.m.js';
+import {getCellularSetupRemote, getESimManagerRemote, observeESimManager, setCellularSetupRemoteForTesting, setESimManagerRemoteForTesting} from '//resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.m.js';
+import {getSimSlotCount, hasActiveCellularNetwork, isActiveSim, isConnectedToNonCellularNetwork} from '//resources/cr_components/chromeos/network/cellular_utils.m.js';
+import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from '//resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
+import {NetworkList} from '//resources/cr_components/chromeos/network/network_list_types.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {assert, assertNotReached} from '//resources/js/assert.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from '../multidevice_page/multidevice_browser_proxy.m.js';
+import {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubNotificationAccessStatus, SmartLockSignInEnabledState} from '../multidevice_page/multidevice_constants.m.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'cellular-networks-list',
 
   behaviors: [
@@ -168,7 +194,7 @@
     /**
      * Multi-device page data used to determine if the tether section should be
      * shown or not.
-     * @type {?settings.MultiDevicePageContentData}
+     * @type {?MultiDevicePageContentData}
      * @private
      */
     multiDevicePageContentData_: {
@@ -193,8 +219,8 @@
 
   /** @override */
   created() {
-    this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
-                              .getMojoServiceRemote();
+    this.networkConfig_ =
+        MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote();
     this.fetchESimPendingProfileList_();
   },
 
@@ -204,7 +230,7 @@
         'settings.updateMultidevicePageContentData',
         this.onMultiDevicePageContentDataChanged_.bind(this));
 
-    const browserProxy = settings.MultiDeviceBrowserProxyImpl.getInstance();
+    const browserProxy = MultiDeviceBrowserProxyImpl.getInstance();
     browserProxy.getPageContentData().then(
         this.onMultiDevicePageContentDataChanged_.bind(this));
   },
@@ -246,7 +272,7 @@
 
   /** @private */
   fetchESimPendingProfileList_() {
-    cellular_setup.getEuicc().then(euicc => {
+    getEuicc().then(euicc => {
       if (!euicc) {
         return;
       }
@@ -276,7 +302,7 @@
    * @private
    */
   fetchESimPendingProfileListForEuicc_(euicc) {
-    cellular_setup.getPendingESimProfiles(euicc).then(
+    getPendingESimProfiles(euicc).then(
         this.processESimPendingProfiles_.bind(this));
   },
 
@@ -376,7 +402,7 @@
   },
 
   /**
-   * @param {!settings.MultiDevicePageContentData} newData
+   * @param {!MultiDevicePageContentData} newData
    * @private
    */
   onMultiDevicePageContentDataChanged_(newData) {
@@ -384,7 +410,7 @@
   },
 
   /**
-   * @param {?settings.MultiDevicePageContentData} pageContentData
+   * @param {?MultiDevicePageContentData} pageContentData
    * @returns {boolean}
    * @private
    */
@@ -393,7 +419,7 @@
       return false;
     }
     return pageContentData.instantTetheringState ===
-        settings.MultiDeviceFeatureState.ENABLED_BY_USER;
+        MultiDeviceFeatureState.ENABLED_BY_USER;
   },
 
   /**
@@ -405,8 +431,7 @@
     event.stopPropagation();
 
     this.fire(
-        'show-cellular-setup',
-        {pageName: cellularSetup.CellularSetupPageName.ESIM_FLOW_UI});
+        'show-cellular-setup', {pageName: CellularSetupPageName.ESIM_FLOW_UI});
   },
 
   /**
@@ -502,8 +527,7 @@
   /** @private */
   onAddEsimButtonTap_() {
     this.fire(
-        'show-cellular-setup',
-        {pageName: cellularSetup.CellularSetupPageName.ESIM_FLOW_UI});
+        'show-cellular-setup', {pageName: CellularSetupPageName.ESIM_FLOW_UI});
   },
 
   /*
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.html b/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.html
index 6fda07d..14bafbb 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.html
@@ -1,23 +1,10 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/load_time_data.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="../../controls/settings_toggle_button.html">
-<link rel="import" href="../../prefs/prefs.html">
-
-<dom-module id="cellular-roaming-toggle-button">
-  <template>
-    <!-- TODO(crbug/1220691): Remove when allowPerNetworkRoaming flag
-        launches -->
-    <template is="dom-if" if="[[!allowPerNetworkRoaming_]]">
-      <settings-toggle-button id="cellularRoamingToggle" class="hr"
-          disabled="[[disabled]]"
-          label="$i18n{networkAllowDataRoaming}"
-          sub-label="[[getRoamingDetails_(managedProperties)]]"
-          pref="{{prefs.cros.signed.data_roaming_enabled}}">
-      </settings-toggle-button>
-    </template>
-  </template>
-  <script src="cellular_roaming_toggle_button.js"></script>
-</dom-module>
+<!-- TODO(crbug/1220691): Remove when allowPerNetworkRoaming flag
+    launches -->
+<template is="dom-if" if="[[!allowPerNetworkRoaming_]]">
+    <settings-toggle-button id="cellularRoamingToggle" class="hr"
+        disabled="[[disabled]]"
+        label="$i18n{networkAllowDataRoaming}"
+        sub-label="[[getRoamingDetails_(managedProperties)]]"
+        pref="{{prefs.cros.signed.data_roaming_enabled}}">
+    </settings-toggle-button>
+</template>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.js b/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.js
index 49e48a22..b4a01005 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.js
@@ -9,7 +9,17 @@
  * the transition to a more granular approach to roaming configuration.
  */
 
+import '../../prefs/prefs.js';
+
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {loadTimeData} from '//resources/js/load_time_data.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {SettingsToggleButtonElement} from '../../controls/settings_toggle_button.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'cellular-roaming-toggle-button',
 
   behaviors: [
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html b/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html
index 68d73dc..7269dbe3 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html
@@ -1,74 +1,58 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="settings-shared">
+  @media (min-width: 640px){
+    :host {
+      --cr-dialog-width: 512px;
+    }
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_delegate.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="../../settings_shared_css.html">
-<link rel="import" href="cellular_setup_settings_delegate.html">
+  @media (max-width: 640px){
+    :host {
+      --cr-dialog-width: 320px;
+    }
+  }
 
-<dom-module id="os-settings-cellular-setup-dialog">
-  <template>
-    <style include="settings-shared">
-      @media (min-width: 640px){
-        :host {
-          --cr-dialog-width: 512px;
-        }
-      }
+  :host {
+    --cr-dialog-body-padding-horizontal: 24px;
+    --cr-dialog-title-slot-padding-bottom: 0;
+    --cr-dialog-title-slot-padding-end: 0;
+    --cr-dialog-title-slot-padding-start: 0;
+    --cr-dialog-title-slot-padding-top: 0;
+  }
 
-      @media (max-width: 640px){
-        :host {
-          --cr-dialog-width: 320px;
-        }
-      }
+  #header {
+    padding-bottom: 8px;
+    padding-inline-end:  24px;
+    padding-inline-start: 24px;
+    padding-top: 24px;
+  }
 
-      :host {
-        --cr-dialog-body-padding-horizontal: 24px;
-        --cr-dialog-title-slot-padding-bottom: 0;
-        --cr-dialog-title-slot-padding-end: 0;
-        --cr-dialog-title-slot-padding-start: 0;
-        --cr-dialog-title-slot-padding-top: 0;
-      }
+  #title {
+    align-items: center;
+    background-color: var(--google-grey-200);
+    display: flex;
+    font-size: x-small;
+    height: 32px;
+    justify-content: center;
+  }
 
-      #header {
-        padding-bottom: 8px;
-        padding-inline-end:  24px;
-        padding-inline-start: 24px;
-        padding-top: 24px;
-      }
-
-      #title {
-        align-items: center;
-        background-color: var(--google-grey-200);
-        display: flex;
-        font-size: x-small;
-        height: 32px;
-        justify-content: center;
-      }
-
-    </style>
-    <!-- TODO(crbug/1093185): Change close logic when CellularSetup embedded -->
-    <cr-dialog id="dialog">
-      <div slot="title">
-        <template is="dom-if"
-            if="[[shouldShowDialogTitle_(dialogTitle_)]]" restamp>
-          <div id="title">
-            [[dialogTitle_]]
-          </div>
-        </template>
-        <div id="header">[[getDialogHeader_(dialogHeader_)]]</div>
+</style>
+<!-- TODO(crbug/1093185): Change close logic when CellularSetup embedded -->
+<cr-dialog id="dialog">
+  <div slot="title">
+    <template is="dom-if"
+        if="[[shouldShowDialogTitle_(dialogTitle_)]]" restamp>
+      <div id="title">
+        [[dialogTitle_]]
       </div>
-      <div slot="body">
-        <cellular-setup
-            flow-title="{{dialogTitle_}}"
-            flow-header="{{dialogHeader_}}"
-            delegate="[[delegate_]]"
-            current-page-name="[[pageName]]">
-        </cellular-setup>
-      </div>
-    </cr-dialog>
-  </template>
-  <script src="cellular_setup_dialog.js"></script>
-</dom-module>
+    </template>
+    <div id="header">[[getDialogHeader_(dialogHeader_)]]</div>
+  </div>
+  <div slot="body">
+    <cellular-setup
+        flow-title="{{dialogTitle_}}"
+        flow-header="{{dialogHeader_}}"
+        delegate="[[delegate_]]"
+        current-page-name="[[pageName]]">
+    </cellular-setup>
+  </div>
+</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.js b/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.js
index 24820a8..ea0c80a 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.js
@@ -6,7 +6,20 @@
  * @fileoverview 'os-settings-cellular-setup-dialog' embeds the <cellular-setup>
  * that is shared with OOBE in a dialog with OS Settings stylizations.
  */
+import '//resources/cr_components/chromeos/cellular_setup/cellular_setup.m.js';
+import '//resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import '//resources/cr_elements/shared_vars_css.m.js';
+import '../../settings_shared_css.js';
+
+import {CellularSetupDelegate} from '//resources/cr_components/chromeos/cellular_setup/cellular_setup_delegate.m.js';
+import {Button, ButtonBarState, ButtonState, CellularSetupPageName} from '//resources/cr_components/chromeos/cellular_setup/cellular_types.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {CellularSetupSettingsDelegate} from './cellular_setup_settings_delegate.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'os-settings-cellular-setup-dialog',
 
   behaviors: [I18nBehavior],
@@ -15,12 +28,12 @@
 
     /**
      * Name of cellular dialog page to be selected.
-     * @type {!cellularSetup.CellularSetupPageName}
+     * @type {!CellularSetupPageName}
      */
     pageName: String,
 
     /**
-     * @private {!cellular_setup.CellularSetupDelegate}
+     * @private {!CellularSetupDelegate}
      */
     delegate_: Object,
 
@@ -37,7 +50,7 @@
 
   /** @override */
   created() {
-    this.delegate_ = new settings.CellularSetupSettingsDelegate();
+    this.delegate_ = new CellularSetupSettingsDelegate();
   },
 
   listeners: {
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_settings_delegate.js b/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_settings_delegate.js
index a818db0..631b3198f 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_settings_delegate.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_settings_delegate.js
@@ -3,25 +3,18 @@
 // found in the LICENSE file.
 
 // clang-format off
-// #import {CellularSetupDelegate} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_delegate.m.js';
+import {CellularSetupDelegate} from 'chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_delegate.m.js';
 // clang-format on
 
-cr.define('settings', function() {
-  /** @implements {cellular_setup.CellularSetupDelegate} */
-  /* #export */ class CellularSetupSettingsDelegate {
-    /** @override */
-    shouldShowPageTitle() {
-      return false;
-    }
-
-    /** @override */
-    shouldShowCancelButton() {
-      return true;
-    }
+/** @implements {CellularSetupDelegate} */
+export class CellularSetupSettingsDelegate {
+  /** @override */
+  shouldShowPageTitle() {
+    return false;
   }
 
-  // #cr_define_end
-  return {
-    CellularSetupSettingsDelegate: CellularSetupSettingsDelegate,
-  };
-});
+  /** @override */
+  shouldShowCancelButton() {
+    return true;
+  }
+}
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.html b/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.html
index 899ca9f3..e94fd47 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.html
@@ -1,76 +1,63 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="iron-flex iron-positioning">
+  :host {
+    --cr-dialog-width: 372px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
+  paper-spinner-lite {
+    height: 20px;
+    position: absolute;
+    right: 16px;
+    top: 6px;
+    width: 20px;
+  }
 
-<dom-module id="esim-install-error-dialog">
-  <template>
-    <style include="iron-flex iron-positioning">
-      :host {
-        --cr-dialog-width: 372px;
-      }
+  #confirmationCodeMessage {
+    margin-bottom: 30px;
+  }
 
-      paper-spinner-lite {
-        height: 20px;
-        position: absolute;
-        right: 16px;
-        top: 6px;
-        width: 20px;
-      }
-
-      #confirmationCodeMessage {
-        margin-bottom: 30px;
-      }
-
-      #cancel {
-        margin-inline-end: 8px;
-      }
-    </style>
-    <cr-dialog id="installErrorDialog" show-on-attach>
-      <div slot="title">$i18n{eSimInstallErrorDialogTitle}</div>
-      <div slot="body">
-        <div id="genericErrorContainer"
-            hidden$="[[isConfirmationCodeError_(errorCode)]]">
-          $i18n{eSimInstallErrorDialogGenericErrorMessage}
+  #cancel {
+    margin-inline-end: 8px;
+  }
+</style>
+<cr-dialog id="installErrorDialog" show-on-attach>
+  <div slot="title">$i18n{eSimInstallErrorDialogTitle}</div>
+  <div slot="body">
+    <div id="genericErrorContainer"
+        hidden$="[[isConfirmationCodeError_(errorCode)]]">
+      $i18n{eSimInstallErrorDialogGenericErrorMessage}
+    </div>
+    <template is="dom-if" if="[[isConfirmationCodeError_(errorCode)]]" restamp>
+      <div id="confirmationCodeErrorContainer">
+        <div id="confirmationCodeMessage">
+          $i18n{eSimInstallErrorDialogConfirmationCodeMessage}
         </div>
-        <template is="dom-if" if="[[isConfirmationCodeError_(errorCode)]]" restamp>
-          <div id="confirmationCodeErrorContainer">
-            <div id="confirmationCodeMessage">
-              $i18n{eSimInstallErrorDialogConfirmationCodeMessage}
-            </div>
-            <div class="relative">
-              <cr-input id="confirmationCode"
-                  value="{{confirmationCode_}}"
-                  spellcheck="false"
-                  disabled="[[isInstallInProgress_]]"
-                  error-message="$i18n{eSimInstallErrorDialogConfirmationCodeError}"
-                  invalid="[[isConfirmationCodeInvalid_]]">
-              </cr-input>
-              <paper-spinner-lite active
-                  hidden$="[[!isInstallInProgress_]]">
-              </paper-spinner-lite>
-            </div>
-          </div>
-        </template>
+        <div class="relative">
+          <cr-input id="confirmationCode"
+              value="{{confirmationCode_}}"
+              spellcheck="false"
+              disabled="[[isInstallInProgress_]]"
+              error-message="$i18n{eSimInstallErrorDialogConfirmationCodeError}"
+              invalid="[[isConfirmationCodeInvalid_]]">
+          </cr-input>
+          <paper-spinner-lite active
+              hidden$="[[!isInstallInProgress_]]">
+          </paper-spinner-lite>
+        </div>
       </div>
-      <div slot="button-container">
-        <cr-button id="cancel"
-            on-click="onCancelClicked_"
-            class="cancel-button"
-            hidden$="[[!isConfirmationCodeError_(errorCode)]]">
-          $i18n{eSimRenameProfileDialogCancel}
-        </cr-button>
-        <cr-button id="done"
-            on-click="onDoneClicked_"
-            disabled="[[isDoneButtonDisabled_(errorCode, confirmationCode_, isInstallInProgress_)]]"
-            class="action-button">
-          $i18n{eSimRenameProfileDialogDone}
-        </cr-button>
-      </div>
-    </cr-dialog>
-  </template>
-  <script src="esim_install_error_dialog.js"></script>
-</dom-module>
\ No newline at end of file
+    </template>
+  </div>
+  <div slot="button-container">
+    <cr-button id="cancel"
+        on-click="onCancelClicked_"
+        class="cancel-button"
+        hidden$="[[!isConfirmationCodeError_(errorCode)]]">
+      $i18n{eSimRenameProfileDialogCancel}
+    </cr-button>
+    <cr-button id="done"
+        on-click="onDoneClicked_"
+        disabled="[[isDoneButtonDisabled_(errorCode, confirmationCode_, isInstallInProgress_)]]"
+        class="action-button">
+      $i18n{eSimRenameProfileDialogDone}
+    </cr-button>
+  </div>
+</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.js b/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.js
index 88a3b53..6a1d6d75 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.js
@@ -7,7 +7,16 @@
  * profile, such as requiring a confirmation code.
  */
 
+import '//resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import '//resources/cr_elements/cr_input/cr_input.m.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+
+import {getESimProfile, getESimProfileProperties, getEuicc, getNonPendingESimProfiles, getNumESimProfiles, getPendingESimProfiles} from '//resources/cr_components/chromeos/cellular_setup/esim_manager_utils.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'esim-install-error-dialog',
 
   behaviors: [
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.html b/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.html
index 4418b0d..27371a2 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.html
@@ -1,81 +1,65 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style>
+  :host {
+    --cr-dialog-width: 416px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_icons.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../os_route.html">
+  #title {
+    height: 15px;
+  }
 
-<dom-module id="esim-remove-profile-dialog">
-  <template>
-    <style>
-      :host {
-        --cr-dialog-width: 416px;
-      }
+  #warningMessage {
+    --iron-icon-fill-color: var(--google-grey-600);
+    --iron-icon-height: 16px;
+    --iron-icon-width: 16px;
+    font-size: smaller;
+    margin-top: 20px;
+  }
 
-      #title {
-        height: 15px;
-      }
+  #warningMessage iron-icon {
+    float: left;
+    padding-inline-end: 4px;
+  }
 
-      #warningMessage {
-        --iron-icon-fill-color: var(--google-grey-600);
-        --iron-icon-height: 16px;
-        --iron-icon-width: 16px;
-        font-size: smaller;
-        margin-top: 20px;
-      }
+  :host-context([dir='rtl']) #warningMessage iron-icon {
+    float: right;
+  }
 
-      #warningMessage iron-icon {
-        float: left;
-        padding-inline-end: 4px;
-      }
+  #warningMessage div {
+    overflow: hidden;
+  }
 
-      :host-context([dir='rtl']) #warningMessage iron-icon {
-        float: right;
-      }
+  #cancel {
+    margin-inline-end: 8px;
+  }
 
-      #warningMessage div {
-        overflow: hidden;
-      }
-
-      #cancel {
-        margin-inline-end: 8px;
-      }
-
-      #cancel:focus {
-        box-shadow: 0 0 0 2px var(--focus-shadow-color);
-      }
-    </style>
-    <cr-dialog id="dialog" show-on-attach>
-      <div id="title" slot="title">
-        [[getTitleString_(esimProfileName_)]]
-      </div>
-      <div slot="body">
-        <div id="description">$i18n{eSimRemoveProfileDialogDescription}</div>
-        <div id="warningMessage" hidden$="[[!showCellularDisconnectWarning]]">
-          <iron-icon icon="cr:info-outline"></iron-icon>
-          <div>$i18n{eSimDialogConnectionWarning}</div>
-        </div>
-      </div>
-      <div slot="button-container">
-        <cr-button id="cancel"
-            aria-label="[[getCancelBtnA11yLabel_(esimProfileName_)]]"
-            on-click="onCancelTap_"
-            class="cancel-button">
-          $i18n{eSimRemoveProfileDialogCancel}
-        </cr-button>
-        <cr-button id="remove"
-            aria-label$="[[getRemoveBtnA11yLabel_(esimProfileName_)]]"
-            aria-describedby="description warningMessage"
-            on-click="onRemoveProfileTap_"
-            class="action-button">
-          $i18n{eSimRemoveProfileDialogRemove}
-        </cr-button>
-      </div>
-    </cr-dialog>
-  </template>
-  <script src="esim_remove_profile_dialog.js"></script>
-</dom-module>
\ No newline at end of file
+  #cancel:focus {
+    box-shadow: 0 0 0 2px var(--focus-shadow-color);
+  }
+</style>
+<cr-dialog id="dialog" show-on-attach>
+  <div id="title" slot="title">
+    [[getTitleString_(esimProfileName_)]]
+  </div>
+  <div slot="body">
+    <div id="description">$i18n{eSimRemoveProfileDialogDescription}</div>
+    <div id="warningMessage" hidden$="[[!showCellularDisconnectWarning]]">
+      <iron-icon icon="cr:info-outline"></iron-icon>
+      <div>$i18n{eSimDialogConnectionWarning}</div>
+    </div>
+  </div>
+  <div slot="button-container">
+    <cr-button id="cancel"
+        aria-label="[[getCancelBtnA11yLabel_(esimProfileName_)]]"
+        on-click="onCancelTap_"
+        class="cancel-button">
+      $i18n{eSimRemoveProfileDialogCancel}
+    </cr-button>
+    <cr-button id="remove"
+        aria-label$="[[getRemoveBtnA11yLabel_(esimProfileName_)]]"
+        aria-describedby="description warningMessage"
+        on-click="onRemoveProfileTap_"
+        class="action-button">
+      $i18n{eSimRemoveProfileDialogRemove}
+    </cr-button>
+  </div>
+</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.js b/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.js
index 8a2ded6b1..445f11c 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.js
@@ -6,7 +6,20 @@
  * @fileoverview Polymer element to remove eSIM profile
  */
 
+import '//resources/cr_components/chromeos/cellular_setup/cellular_setup_icons.m.js';
+import '//resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import '//resources/cr_elements/cr_input/cr_input.m.js';
+
+import {getESimProfile, getESimProfileProperties, getEuicc, getNonPendingESimProfiles, getNumESimProfiles, getPendingESimProfiles} from '//resources/cr_components/chromeos/cellular_setup/esim_manager_utils.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {Route, RouteObserverBehavior, Router} from '../../router.js';
+import {routes} from '../os_route.m.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'esim-remove-profile-dialog',
 
   behaviors: [
@@ -48,8 +61,8 @@
               chromeos.networkConfig.mojom.NetworkType.kCellular)) {
       return;
     }
-    this.esimProfileRemote_ = await cellular_setup.getESimProfile(
-        this.networkState.typeState.cellular.iccid);
+    this.esimProfileRemote_ =
+        await getESimProfile(this.networkState.typeState.cellular.iccid);
     // Fail gracefully if init is incomplete, see crbug/1194729.
     if (!this.esimProfileRemote_) {
       this.fire('show-error-toast', this.i18n('eSimRemoveProfileDialogError'));
@@ -99,8 +112,8 @@
         'type',
         OncMojo.getNetworkTypeString(
             chromeos.networkConfig.mojom.NetworkType.kCellular));
-    settings.Router.getInstance().setCurrentRoute(
-        settings.routes.INTERNET_NETWORKS, params, /*isPopState=*/ true);
+    Router.getInstance().setCurrentRoute(
+        routes.INTERNET_NETWORKS, params, /*isPopState=*/ true);
   },
 
   /**
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.html b/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.html
index aba954d..bc195df4 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.html
@@ -1,145 +1,131 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="iron-positioning">
+  :host {
+    --cr-dialog-width: 416px;
+    --cr-dialog-title-slot-padding-bottom: 10px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_icons.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+  #body {
+    overflow: hidden;
+    padding: 0 20px 2px 20px;
+  }
 
-<dom-module id="esim-rename-dialog">
-  <template>
-    <style include="iron-positioning">
-      :host {
-        --cr-dialog-width: 416px;
-        --cr-dialog-title-slot-padding-bottom: 10px;
-      }
+  #warningMessage {
+    --iron-icon-fill-color: var(--google-grey-600);
+    --iron-icon-height: 16px;
+    --iron-icon-width: 16px;
+    font-size: smaller;
+    padding-bottom: 12px;
+  }
 
-      #body {
-        overflow: hidden;
-        padding: 0 20px 2px 20px;
-      }
+  #warningMessage iron-icon {
+    float: left;
+    padding-inline-end: 4px;
+  }
 
-      #warningMessage {
-        --iron-icon-fill-color: var(--google-grey-600);
-        --iron-icon-height: 16px;
-        --iron-icon-width: 16px;
-        font-size: smaller;
-        padding-bottom: 12px;
-      }
+  :host-context([dir='rtl']) #warningMessage iron-icon {
+    float: right;
+  }
 
-      #warningMessage iron-icon {
-        float: left;
-        padding-inline-end: 4px;
-      }
+  #warningMessage div {
+    overflow: hidden;
+  }
 
-      :host-context([dir='rtl']) #warningMessage iron-icon {
-        float: right;
-      }
+  #inputContainer {
+    margin-top: 12px;
+  }
 
-      #warningMessage div {
-        overflow: hidden;
-      }
+  #inputInfo {
+    background-color: white;
+    color: var(--google-grey-700);
+    font-size: var(--cr-form-field-label-font-size);
+    font-weight: 400;
+    height: 30px;
+    line-height: var(--cr-form-field-label-line-height);
+    padding-top: 8px;
+    position: absolute;
+    top: 50px;
+    width: 100%;
+  }
 
-      #inputContainer {
-        margin-top: 12px;
-      }
+  #inputInfo.error {
+    color: var(--google-red-600);
+  }
 
-      #inputInfo {
-        background-color: white;
-        color: var(--google-grey-700);
-        font-size: var(--cr-form-field-label-font-size);
-        font-weight: 400;
-        height: 30px;
-        line-height: var(--cr-form-field-label-line-height);
-        padding-top: 8px;
-        position: absolute;
-        top: 50px;
-        width: 100%;
-      }
+  #inputSubtitle {
+    display: block;
+    width: 260px;
+  }
 
-      #inputInfo.error {
-        color: var(--google-red-600);
-      }
+  #inputCount {
+    position: absolute;
+    right: 0;
+    top: 8px;
+  }
 
-      #inputSubtitle {
-        display: block;
-        width: 260px;
-      }
+  :host-context([dir='rtl']) #inputCount {
+    left: 0;
+    right: auto;
+  }
 
-      #inputCount {
-        position: absolute;
-        right: 0;
-        top: 8px;
-      }
-
-      :host-context([dir='rtl']) #inputCount {
-        left: 0;
-        right: auto;
-      }
-
-      #cancel {
-        margin-inline-end: 8px;
-      }
-    </style>
-    <cr-dialog id="profileRenameDialog" show-on-attach>
-      <div slot="title">$i18n{eSimRenameProfileDialogLabel}</div>
-      <div id="body" slot="body">
-        <div id="warningMessage" hidden$="[[!showCellularDisconnectWarning]]">
-          <iron-icon icon="cr:info-outline"></iron-icon>
-          <div>$i18n{eSimDialogConnectionWarning}</div>
-        </div>
-        <template is="dom-if" if="[[!errorMessage_]]" restamp>
-          <div id="inputContainer" class="relative">
-            <!-- Set error-message so then it is read out by ChromeVox
-              when cr-input is invalid. Since we already display the error
-              message in #inputInfo, this is visually hidden by #inputInfo. -->
-            <cr-input id="eSimprofileName"
-                value="{{esimProfileName_}}"
-                spellcheck="false"
-                disabled="[[isRenameInProgress_]]"
-                invalid="[[isInputInvalid_]]"
-                label="$i18n{eSimRenameProfileInputTitle}"
-                aria-label="[[i18n('eSimRenameProfileDialogLabel')]]"
-                aria-description="[[i18n('eSimRenameProfileInputA11yLabel',
-                    MAX_INPUT_LENGTH)]]"
-                error-message="[[i18n('eSimRenameProfileInputA11yLabel',
-                    MAX_INPUT_LENGTH)]]">
-            </cr-input>
-            <div id="inputInfo"
-                class$="[[getInputInfoClass_(isInputInvalid_)]]"
-                aria-hidden="true">
-              <span id="inputSubtitle">$i18n{eSimRenameProfileInputSubtitle}</span>
-              <span id="inputCount">
-                [[getInputCountString_(esimProfileName_)]]
-              </span>
-            </div>
-          </div>
-        </template>
-        <div id="errorMessage" aria-live="polite" hidden$="[[!errorMessage_]]">
-          [[errorMessage_]]
+  #cancel {
+    margin-inline-end: 8px;
+  }
+</style>
+<cr-dialog id="profileRenameDialog" show-on-attach>
+  <div slot="title">$i18n{eSimRenameProfileDialogLabel}</div>
+  <div id="body" slot="body">
+    <div id="warningMessage" hidden$="[[!showCellularDisconnectWarning]]">
+      <iron-icon icon="cr:info-outline"></iron-icon>
+      <div>$i18n{eSimDialogConnectionWarning}</div>
+    </div>
+    <template is="dom-if" if="[[!errorMessage_]]" restamp>
+      <div id="inputContainer" class="relative">
+        <!-- Set error-message so then it is read out by ChromeVox
+          when cr-input is invalid. Since we already display the error
+          message in #inputInfo, this is visually hidden by #inputInfo. -->
+        <cr-input id="eSimprofileName"
+            value="{{esimProfileName_}}"
+            spellcheck="false"
+            disabled="[[isRenameInProgress_]]"
+            invalid="[[isInputInvalid_]]"
+            label="$i18n{eSimRenameProfileInputTitle}"
+            aria-label="[[i18n('eSimRenameProfileDialogLabel')]]"
+            aria-description="[[i18n('eSimRenameProfileInputA11yLabel',
+                MAX_INPUT_LENGTH)]]"
+            error-message="[[i18n('eSimRenameProfileInputA11yLabel',
+                MAX_INPUT_LENGTH)]]">
+        </cr-input>
+        <div id="inputInfo"
+            class$="[[getInputInfoClass_(isInputInvalid_)]]"
+            aria-hidden="true">
+          <span id="inputSubtitle">$i18n{eSimRenameProfileInputSubtitle}</span>
+          <span id="inputCount">
+            [[getInputCountString_(esimProfileName_)]]
+          </span>
         </div>
       </div>
-      <div slot="button-container">
-        <template is="dom-if" if="[[!errorMessage_]]" restamp>
-          <cr-button id="cancel"
-              on-click="onCancelTap_"
-              disabled="[[isRenameInProgress_]]"
-              class="cancel-button">
-            $i18n{eSimRenameProfileDialogCancel}
-          </cr-button>
-        </template>
-        <cr-button id="done"
-            on-click="onRenameDialogDoneTap_"
-            disabled="[[isDoneButtonDisabled_(isRenameInProgress_,
-                esimProfileName_)]]"
-            aria-label$="[[getDoneBtnA11yLabel_(esimProfileName_)]]"
-            aria-describedby="warningMessage"
-            class="action-button">
-          $i18n{eSimRenameProfileDialogDone}
-        </cr-button>
-      </div>
-    </cr-dialog>
-  </template>
-  <script src="esim_rename_dialog.js"></script>
-</dom-module>
\ No newline at end of file
+    </template>
+    <div id="errorMessage" aria-live="polite" hidden$="[[!errorMessage_]]">
+      [[errorMessage_]]
+    </div>
+  </div>
+  <div slot="button-container">
+    <template is="dom-if" if="[[!errorMessage_]]" restamp>
+      <cr-button id="cancel"
+          on-click="onCancelTap_"
+          disabled="[[isRenameInProgress_]]"
+          class="cancel-button">
+        $i18n{eSimRenameProfileDialogCancel}
+      </cr-button>
+    </template>
+    <cr-button id="done"
+        on-click="onRenameDialogDoneTap_"
+        disabled="[[isDoneButtonDisabled_(isRenameInProgress_,
+            esimProfileName_)]]"
+        aria-label$="[[getDoneBtnA11yLabel_(esimProfileName_)]]"
+        aria-describedby="warningMessage"
+        class="action-button">
+      $i18n{eSimRenameProfileDialogDone}
+    </cr-button>
+  </div>
+</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.js b/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.js
index d3305da..dcd1422 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.js
@@ -16,7 +16,17 @@
  * @fileoverview Polymer element to rename eSIM profile name
  */
 
+import {afterNextRender, Polymer, html, flush, Templatizer, TemplateInstanceBase} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import '//resources/cr_components/chromeos/cellular_setup/cellular_setup_icons.m.js';
+import {getPendingESimProfiles, getNonPendingESimProfiles, getNumESimProfiles, getEuicc, getESimProfile, getESimProfileProperties} from '//resources/cr_components/chromeos/cellular_setup/esim_manager_utils.m.js';
+import '//resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import '//resources/cr_elements/cr_input/cr_input.m.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'esim-rename-dialog',
 
   behaviors: [
@@ -83,8 +93,8 @@
               chromeos.networkConfig.mojom.NetworkType.kCellular)) {
       return;
     }
-    this.esimProfileRemote_ = await cellular_setup.getESimProfile(
-        this.networkState.typeState.cellular.iccid);
+    this.esimProfileRemote_ =
+        await getESimProfile(this.networkState.typeState.cellular.iccid);
     // Fail gracefully if init is incomplete, see crbug/1194729.
     if (!this.esimProfileRemote_) {
       this.errorMessage_ = this.i18n('eSimRenameProfileDialogError');
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.html
index cb7a444..afb9a5de 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.html
@@ -1,67 +1,50 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="internet-shared iron-flex">
+  cr-dialog::part(dialog) {
+    width: 460px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_config.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/util.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
-<link rel="import" href="../metrics_recorder.html">
-<link rel="import" href="internet_shared_css.html">
+  .error {
+    color: red;
+    font-weight: 500;
+  }
+</style>
 
-<dom-module id="internet-config">
-  <template>
-    <style include="internet-shared iron-flex">
-      cr-dialog::part(dialog) {
-        width: 460px;
-      }
+<cr-dialog id="dialog" close-text="$i18n{close}">
+  <div slot="title">
+    [[getDialogTitle_(name, type, showConnect)]]
+  </div>
+  <div slot="body">
+    <network-config id="networkConfig" class="flex"
+        guid="[[guid]]" name="{{name}}" type="{{type}}"
+        enable-connect="{{enableConnect_}}" enable-save="{{enableSave_}}"
+        share-allow-enable="[[shareAllowEnable_]]"
+        share-default="[[shareDefault_]]"
+        error="{{error_}}"
+        on-close="onClose_"
+        connect-on-enter="[[showConnect]]"
+        on-properties-set="onPropertiesSet_">
+    </network-config>
+  </div>
 
-      .error {
-        color: red;
-        font-weight: 500;
-      }
-    </style>
+  <div class="layout horizontal center" slot="button-container">
+    <template is="dom-if" if="[[error_]]" restamp>
+      <div class="flex error">[[getError_(error_)]]</div>
+    </template>
+    <cr-button class="cancel-button" on-click="onCancelTap_">
+      $i18n{cancel}
+    </cr-button>
+    <template is="dom-if" if="[[!showConnect]]">
+      <cr-button id="saveButton" class="action-button"
+          on-click="onSaveTap_" disabled="[[!enableSave_]]">
+        $i18n{save}
+      </cr-button>
+    </template>
+    <template is="dom-if" if="[[showConnect]]">
+      <cr-button id="connectButton" class="action-button"
+          on-click="onConnectTap_" disabled="[[!enableConnect_]]">
+        $i18n{networkButtonConnect}
+      </cr-button>
+    </template>
+  </div>
 
-    <cr-dialog id="dialog" close-text="$i18n{close}">
-      <div slot="title">
-        [[getDialogTitle_(name, type, showConnect)]]
-      </div>
-      <div slot="body">
-        <network-config id="networkConfig" class="flex"
-            guid="[[guid]]" name="{{name}}" type="{{type}}"
-            enable-connect="{{enableConnect_}}" enable-save="{{enableSave_}}"
-            share-allow-enable="[[shareAllowEnable_]]"
-            share-default="[[shareDefault_]]"
-            error="{{error_}}"
-            on-close="onClose_"
-            connect-on-enter="[[showConnect]]"
-            on-properties-set="onPropertiesSet_">
-        </network-config>
-      </div>
-
-      <div class="layout horizontal center" slot="button-container">
-        <template is="dom-if" if="[[error_]]" restamp>
-          <div class="flex error">[[getError_(error_)]]</div>
-        </template>
-        <cr-button class="cancel-button" on-click="onCancelTap_">
-          $i18n{cancel}
-        </cr-button>
-        <template is="dom-if" if="[[!showConnect]]">
-          <cr-button id="saveButton" class="action-button"
-              on-click="onSaveTap_" disabled="[[!enableSave_]]">
-            $i18n{save}
-          </cr-button>
-        </template>
-        <template is="dom-if" if="[[showConnect]]">
-          <cr-button id="connectButton" class="action-button"
-              on-click="onConnectTap_" disabled="[[!enableConnect_]]">
-            $i18n{networkButtonConnect}
-          </cr-button>
-        </template>
-      </div>
-
-    </cr-dialog>
-  </template>
-  <script src="internet_config.js"></script>
-</dom-module>
+</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
index f30c445..0decdca3 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_config.js
@@ -6,7 +6,21 @@
  * @fileoverview
  * 'internet-config' is a Settings dialog wrapper for network-config.
  */
+import '//resources/cr_components/chromeos/network/network_config.m.js';
+import '//resources/cr_elements/cr_button/cr_button.m.js';
+import '//resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import './internet_shared_css.js';
+
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {HTMLEscape, listenOnce} from '//resources/js/util.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from '../metrics_recorder.m.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'internet-config',
 
   behaviors: [I18nBehavior],
@@ -149,11 +163,11 @@
     if (this.type ===
         OncMojo.getNetworkTypeString(
             chromeos.networkConfig.mojom.NetworkType.kWiFi)) {
-      settings.recordSettingChange(
+      recordSettingChange(
           chromeos.settings.mojom.Setting.kWifiAddNetwork,
           {stringValue: this.guid});
     } else {
-      settings.recordSettingChange();
+      recordSettingChange();
     }
   },
 });
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html
index e791958f..a15e01dfa 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html
@@ -1,60 +1,40 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="cr-shared-style settings-shared iron-flex">
+  cr-action-menu.dropdown-item {
+    min-height: 36px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../../settings_shared_css.html">
-<link rel="import" href="../deep_linking_behavior.html">
-<link rel="import" href="../os_route.html">
-
-<dom-module id="settings-internet-detail-menu">
+  cr-action-menu hr {
+    /* Override user-agent border and margin. */
+    border: none;
+    border-top: var(--cr-separator-line);
+    margin: 6px 0 0 0;
+  }
+</style>
+<template is="dom-if"
+    if="[[shouldShowDotsMenuButton_(eSimNetworkState_, isGuest_)]]" restamp>
+  <cr-icon-button class="icon-more-vert"
+      title="$i18n{moreActions}"
+      id="moreNetworkDetail"
+      on-click="onDotsClick_"
+      disabled="[[isDotsMenuButtonDisabled_(deviceState.*)]]">
+  </cr-icon-button>
+</template>
+<cr-lazy-render id="menu">
   <template>
-    <style include="cr-shared-style settings-shared iron-flex">
-      cr-action-menu.dropdown-item {
-        min-height: 36px;
-      }
-
-      cr-action-menu hr {
-        /* Override user-agent border and margin. */
-        border: none;
-        border-top: var(--cr-separator-line);
-        margin: 6px 0 0 0;
-      }
-    </style>
-    <template is="dom-if"
-        if="[[shouldShowDotsMenuButton_(eSimNetworkState_, isGuest_)]]" restamp>
-      <cr-icon-button class="icon-more-vert"
-          title="$i18n{moreActions}"
-          id="moreNetworkDetail"
-          on-click="onDotsClick_"
-          disabled="[[isDotsMenuButtonDisabled_(deviceState.*)]]">
-      </cr-icon-button>
-    </template>
-    <cr-lazy-render id="menu">
-      <template>
-        <cr-action-menu role-description="$i18n{menu}">
-          <button class="dropdown-item"
-              id="renameBtn"
-              on-click="onRenameESimProfileTap_"
-              role="menuitem">
-            $i18n{networkDetailMenuRenameESim}
-          </button>
-          <hr>
-          <button class="dropdown-item"
-              on-click="onRemoveESimProfileTap_"
-              role="menuitem"
-              id="removeBtn">
-            $i18n{networkDetailMenuRemoveESim}
-          </button>
-        </cr-action-menu>
-      </template>
-    </cr-lazy-render>
+    <cr-action-menu role-description="$i18n{menu}">
+      <button class="dropdown-item"
+          id="renameBtn"
+          on-click="onRenameESimProfileTap_"
+          role="menuitem">
+        $i18n{networkDetailMenuRenameESim}
+      </button>
+      <hr>
+      <button class="dropdown-item"
+          on-click="onRemoveESimProfileTap_"
+          role="menuitem"
+          id="removeBtn">
+        $i18n{networkDetailMenuRemoveESim}
+      </button>
+    </cr-action-menu>
   </template>
-  <script src="internet_detail_menu.js"></script>
-</dom-module>
+</cr-lazy-render>
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 3cd36c25..0ac4c74 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
@@ -6,13 +6,30 @@
  * @fileoverview 'settings-internet-detail-menu' is a menu that provides
  * additional actions for a network in the network detail page.
  */
+import '//resources/cr_elements/cr_action_menu/cr_action_menu.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_lazy_render/cr_lazy_render.m.js';
+import '//resources/cr_elements/shared_vars_css.m.js';
+import '../../settings_shared_css.js';
+
+import {ESimManagerListenerBehavior} from '//resources/cr_components/chromeos/cellular_setup/esim_manager_listener_behavior.m.js';
+import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from '//resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {Route, RouteObserverBehavior, Router} from '../../router.js';
+import {DeepLinkingBehavior} from '../deep_linking_behavior.m.js';
+import {routes} from '../os_route.m.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'settings-internet-detail-menu',
 
   // TODO(crbug.com/1093185): Implement DeepLinkingBehavior and override methods
   // to show the actions for search result.
   behaviors: [
-    settings.RouteObserverBehavior,
+    RouteObserverBehavior,
     ESimManagerListenerBehavior,
     DeepLinkingBehavior,
   ],
@@ -74,12 +91,12 @@
    * @return {boolean}
    */
   beforeDeepLinkAttempt(settingId) {
-    Polymer.RenderStatus.afterNextRender(this, () => {
+    afterNextRender(this, () => {
       const menu = /** @type {!CrActionMenuElement} */ (this.$.menu.get());
       menu.showAt(/** @type {!Element} */ (this.$$('#moreNetworkDetail')));
 
       // Wait for menu to open.
-      Polymer.RenderStatus.afterNextRender(this, () => {
+      afterNextRender(this, () => {
         let element;
         if (settingId ===
             chromeos.settings.mojom.Setting.kCellularRenameESimNetwork) {
@@ -103,16 +120,15 @@
   },
 
   /**
-   * settings.RouteObserverBehavior
-   * @param {!settings.Route} route
-   * @param {!settings.Route} oldRoute
+   * RouteObserverBehavior
+   * @param {!Route} route
+   * @param {!Route} oldRoute
    * @protected
    */
   currentRouteChanged(route, oldRoute) {
     this.eSimNetworkState_ = null;
     this.guid_ = '';
-    if (route !== settings.routes.NETWORK_DETAIL ||
-        !this.isUpdatedCellularUiEnabled_) {
+    if (route !== routes.NETWORK_DETAIL || !this.isUpdatedCellularUiEnabled_) {
       return;
     }
 
@@ -120,7 +136,7 @@
     // current route. We can't use the 'type' parameter in the url
     // directly because Cellular and Tethering share the same subpage and have
     // the same 'type' in the route.
-    const queryParams = settings.Router.getInstance().getQueryParameters();
+    const queryParams = Router.getInstance().getQueryParameters();
     const guid = queryParams.get('guid') || '';
     if (!guid) {
       console.error('No guid specified for page:' + route);
@@ -146,8 +162,8 @@
    * @private
    */
   setESimNetworkState_() {
-    const networkConfig = network_config.MojoInterfaceProviderImpl.getInstance()
-                              .getMojoServiceRemote();
+    const networkConfig =
+        MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote();
     networkConfig.getNetworkState(this.guid_).then(response => {
       if (!response.result ||
           response.result.type !==
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html
index b85251e..8408f13 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html
@@ -1,481 +1,433 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="internet-shared settings-shared iron-flex">
+  :host {
+    padding-bottom: 40px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cr_policy_network_indicator_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_apnlist.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_choose_mobile.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_config_toggle.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_icon.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_ip_config.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_nameservers.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_property_list_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_siminfo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cellular_utils.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
-<link rel="import" href="../../controls/controlled_button.html">
-<link rel="import" href="../../controls/settings_toggle_button.html">
-<link rel="import" href="../../people_page/sync_browser_proxy.html">
-<link rel="import" href="../../prefs/prefs.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../deep_linking_behavior.html">
-<link rel="import" href="../metrics_recorder.html">
-<link rel="import" href="../os_people_page/os_sync_browser_proxy.html">
-<link rel="import" href="../os_route.html">
-<link rel="import" href="cellular_roaming_toggle_button.html">
-<link rel="import" href="internet_page_browser_proxy.html">
-<link rel="import" href="internet_shared_css.html">
-<link rel="import" href="network_proxy_section.html">
-<link rel="import" href="tether_connection_dialog.html">
+  iron-icon {
+    margin-inline-end: 10px;
+  }
 
-<dom-module id="settings-internet-detail-page">
-  <template>
-    <style include="internet-shared settings-shared iron-flex">
-      :host {
-        padding-bottom: 40px;
-      }
+  cr-policy-indicator {
+    margin-inline-start: var(--settings-controlled-by-spacing);
+  }
 
-      iron-icon {
-        margin-inline-end: 10px;
-      }
+  cr-policy-network-indicator-mojo {
+    margin: 0 var(--settings-controlled-by-spacing);
+  }
 
-      cr-policy-indicator {
-        margin-inline-start: var(--settings-controlled-by-spacing);
-      }
+  #networkState[connected] {
+    color: var(--google-green-500);
+  }
 
-      cr-policy-network-indicator-mojo {
-        margin: 0 var(--settings-controlled-by-spacing);
-      }
+  #networkState[error] {
+    color: var(--google-red-500);
+  }
 
-      #networkState[connected] {
-        color: var(--google-green-500);
-      }
+  #preferNetworkToggleContainer:hover {
+    background-color: var(--cr-hover-background-color);
+  }
 
-      #networkState[error] {
-        color: var(--google-red-500);
-      }
+  #preferNetworkToggleContainer:active {
+    background-color: var(--cr-active-background-color);
+  }
 
-      #preferNetworkToggleContainer:hover {
-        background-color: var(--cr-hover-background-color);
-      }
+  paper-spinner-lite {
+    height: var(--cr-icon-size);
+    width: var(--cr-icon-size);
+  }
 
-      #preferNetworkToggleContainer:active {
-        background-color: var(--cr-active-background-color);
-      }
+  .warning {
+    color: var(--cr-secondary-text-color);
+    margin-inline-start: var(--settings-controlled-by-spacing);
+  }
 
-      paper-spinner-lite {
-        height: var(--cr-icon-size);
-        width: var(--cr-icon-size);
-      }
-
-      .warning {
-        color: var(--cr-secondary-text-color);
-        margin-inline-start: var(--settings-controlled-by-spacing);
-      }
-
-      #mac-address-container {
-        border-top: none;
-      }
-    </style>
-    <!-- Title section: Icon + name + connection state. -->
-    <div id="titleDiv" class="settings-box first">
-      <div class="start layout horizontal center">
-        <network-icon
-            show-technology-badge="[[showTechnologyBadge_]]"
-            network-state="[[getNetworkState_(managedProperties_)]]">
-        </network-icon>
-        <div id="networkState" class="title settings-box-text"
-            connected$="[[isConnectedState_(managedProperties_)]]"
-            error$="[[isOutOfRangeOrNotEnabled_(outOfRange_, deviceState_)]]">
-          [[getStateText_(managedProperties_, propertiesReceived_,
-              outOfRange_, deviceState_)]]
-        </div>
-        <template is="dom-if"
-            if="[[isPolicySource(managedProperties_.source))]]">
-          <cr-policy-indicator
-              indicator-type="[[getIndicatorTypeForSource(
-                  managedProperties_.source)]]">
-          </cr-policy-indicator>
-        </template>
-      </div>
-      <cr-button id="forgetButton" on-click="onForgetTap_"
-          hidden$="[[!showForget_(managedProperties_)]]"
-          disabled="[[disableForget_(managedProperties_,
-              prefs.vpn_config_allowed, disabled_)]]">
-        $i18n{networkButtonForget}
-      </cr-button>
-      <cr-button id="viewAccountButton"
-          on-click="onViewAccountTap_"
-          hidden$="[[!showViewAccount_(managedProperties_)]]"
-          disabled="[[disabled_]]">
-        $i18n{networkButtonViewAccount}
-      </cr-button>
-      <cr-button id="activateButton"
-          on-click="onActivateTap_"
-          hidden$="[[!showActivate_(managedProperties_)]]"
-          disabled="[[disabled_]]">
-        $i18n{networkButtonActivate}
-      </cr-button>
-      <cr-button id="configureButton" on-click="onConfigureTap_"
-          hidden$="[[!showConfigure_(managedProperties_, globalPolicy,
-              managedNetworkAvailable)]]"
-          disabled="[[disableConfigure_(managedProperties_,
-              prefs.vpn_config_allowed, disabled_)]]"
-          deep-link-focus-id$="[[Setting.kConfigureEthernet]]">
-        $i18n{networkButtonConfigure}
-      </cr-button>
-      <!-- Use policy properties from vpn_config_allowed to indicate when that
-          pref disables buttons in this row. -->
-      <controlled-button id="connectDisconnect" class="action-button"
-          on-click="onConnectDisconnectTap_"
-          hidden$="[[shouldConnectDisconnectButtonBeHidden_(
-              managedProperties_, globalPolicy, managedNetworkAvailable,
-              deviceState_)]]"
-          disabled="[[shouldConnectDisconnectButtonBeDisabled_(
-              managedProperties_, defaultNetwork, propertiesReceived_,
-              outOfRange_, globalPolicy, managedNetworkAvailable,
-              deviceState_, disabled_)]]"
-          label="[[getConnectDisconnectButtonLabel_(managedProperties_,
-              globalPolicy,managedNetworkAvailable, deviceState_)]]"
-          pref="[[getFakeVpnConfigPrefForEnforcement_(managedProperties_,
-              prefs.vpn_config_allowed)]]"
-          deep-link-focus-id$="[[Setting.kDisconnectWifiNetwork]]
-              [[Setting.kDisconnectCellularNetwork]]
-              [[Setting.kDisconnectTetherNetwork]]">
-      </controlled-button>
+  #mac-address-container {
+    border-top: none;
+  }
+</style>
+<!-- Title section: Icon + name + connection state. -->
+<div id="titleDiv" class="settings-box first">
+  <div class="start layout horizontal center">
+    <network-icon
+        show-technology-badge="[[showTechnologyBadge_]]"
+        network-state="[[getNetworkState_(managedProperties_)]]">
+    </network-icon>
+    <div id="networkState" class="title settings-box-text"
+        connected$="[[isConnectedState_(managedProperties_)]]"
+        error$="[[isOutOfRangeOrNotEnabled_(outOfRange_, deviceState_)]]">
+      [[getStateText_(managedProperties_, propertiesReceived_,
+          outOfRange_, deviceState_)]]
     </div>
-
-
-    <!-- Start of NOTICES section. -->
-    <!-- If row ordering changes, messagesDividerClass_() must be updated. -->
-    <template is="dom-if" if="[[isBlockedByPolicy_(managedProperties_,
-                                globalPolicy, managedNetworkAvailable)]]">
-      <!-- Disabled by policy -->
-      <div class="settings-box continuation">
-        <iron-icon class="policy" icon="cr20:domain"></iron-icon>
-        <div class="settings-box-text">$i18n{networkConnectNotAllowed}</div>
-      </div>
-    </template>
-
-    <template is="dom-if" if="[[isSecondaryUser_]]">
-      <!-- Non primary users. -->
-      <div class$="settings-box single-column
-                  [[messagesDividerClass_('secondary', managedProperties_,
-                      globalPolicy, managedNetworkAvailable,
-                      isSecondaryUser_, isWifiSyncEnabled_)]]">
-        <div class="layout horizontal center">
-          <iron-icon class="policy" icon="cr:group"></iron-icon>
-          <div class="settings-box-text">
-            [[i18n('networkPrimaryUserControlled', primaryUserEmail_)]]
-          </div>
-        </div>
-      </div>
-    </template>
-
-
     <template is="dom-if"
-        if="[[showShared_(managedProperties_, globalPolicy,
+        if="[[isPolicySource(managedProperties_.source))]]">
+      <cr-policy-indicator
+          indicator-type="[[getIndicatorTypeForSource(
+              managedProperties_.source)]]">
+      </cr-policy-indicator>
+    </template>
+  </div>
+  <cr-button id="forgetButton" on-click="onForgetTap_"
+      hidden$="[[!showForget_(managedProperties_)]]"
+      disabled="[[disableForget_(managedProperties_,
+          prefs.vpn_config_allowed, disabled_)]]">
+    $i18n{networkButtonForget}
+  </cr-button>
+  <cr-button id="viewAccountButton"
+      on-click="onViewAccountTap_"
+      hidden$="[[!showViewAccount_(managedProperties_)]]"
+      disabled="[[disabled_]]">
+    $i18n{networkButtonViewAccount}
+  </cr-button>
+  <cr-button id="activateButton"
+      on-click="onActivateTap_"
+      hidden$="[[!showActivate_(managedProperties_)]]"
+      disabled="[[disabled_]]">
+    $i18n{networkButtonActivate}
+  </cr-button>
+  <cr-button id="configureButton" on-click="onConfigureTap_"
+      hidden$="[[!showConfigure_(managedProperties_, globalPolicy,
+          managedNetworkAvailable)]]"
+      disabled="[[disableConfigure_(managedProperties_,
+          prefs.vpn_config_allowed, disabled_)]]"
+      deep-link-focus-id$="[[Setting.kConfigureEthernet]]">
+    $i18n{networkButtonConfigure}
+  </cr-button>
+  <!-- Use policy properties from vpn_config_allowed to indicate when that
+      pref disables buttons in this row. -->
+  <controlled-button id="connectDisconnect" class="action-button"
+      on-click="onConnectDisconnectTap_"
+      hidden$="[[shouldConnectDisconnectButtonBeHidden_(
+          managedProperties_, globalPolicy, managedNetworkAvailable,
+          deviceState_)]]"
+      disabled="[[shouldConnectDisconnectButtonBeDisabled_(
+          managedProperties_, defaultNetwork, propertiesReceived_,
+          outOfRange_, globalPolicy, managedNetworkAvailable,
+          deviceState_, disabled_)]]"
+      label="[[getConnectDisconnectButtonLabel_(managedProperties_,
+          globalPolicy,managedNetworkAvailable, deviceState_)]]"
+      pref="[[getFakeVpnConfigPrefForEnforcement_(managedProperties_,
+          prefs.vpn_config_allowed)]]"
+      deep-link-focus-id$="[[Setting.kDisconnectWifiNetwork]]
+          [[Setting.kDisconnectCellularNetwork]]
+          [[Setting.kDisconnectTetherNetwork]]">
+  </controlled-button>
+</div>
+
+
+<!-- Start of NOTICES section. -->
+<!-- If row ordering changes, messagesDividerClass_() must be updated. -->
+<template is="dom-if" if="[[isBlockedByPolicy_(managedProperties_,
+                            globalPolicy, managedNetworkAvailable)]]">
+  <!-- Disabled by policy -->
+  <div class="settings-box continuation">
+    <iron-icon class="policy" icon="cr20:domain"></iron-icon>
+    <div class="settings-box-text">$i18n{networkConnectNotAllowed}</div>
+  </div>
+</template>
+
+<template is="dom-if" if="[[isSecondaryUser_]]">
+  <!-- Non primary users. -->
+  <div class$="settings-box single-column
+              [[messagesDividerClass_('secondary', managedProperties_,
+                  globalPolicy, managedNetworkAvailable,
+                  isSecondaryUser_, isWifiSyncEnabled_)]]">
+    <div class="layout horizontal center">
+      <iron-icon class="policy" icon="cr:group"></iron-icon>
+      <div class="settings-box-text">
+        [[i18n('networkPrimaryUserControlled', primaryUserEmail_)]]
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<template is="dom-if"
+    if="[[showShared_(managedProperties_, globalPolicy,
+        managedNetworkAvailable)]]">
+  <!-- Shared network. -->
+  <div class$="settings-box settings-box-text
+              [[messagesDividerClass_('shared', managedProperties_,
+                  globalPolicy, managedNetworkAvailable,
+                  isSecondaryUser_, isWifiSyncEnabled_)]]">
+      [[sharedString_(managedProperties_)]]
+  </div>
+</template>
+<template is="dom-if"
+    if="[[showSynced_(managedProperties_, globalPolicy,
+        managedNetworkAvailable, isWifiSyncEnabled_)]]">
+  <!-- Synced network. -->
+  <div class$="settings-box settings-box-text
+              [[messagesDividerClass_('synced', managedProperties_,
+                  globalPolicy, managedNetworkAvailable,
+                  isSecondaryUser_, isWifiSyncEnabled_)]]">
+      <settings-localized-link
+        localized-string="[[syncedString_(managedProperties_)]]">
+      </settings-localized-link>
+  </div>
+</template>
+<!-- End of NOTICES section -->
+
+<template is="dom-if" if="[[!isSecondaryUser_]]">
+  <template is="dom-if" if="[[showConfigurableSections_]]"  restamp>
+    <!-- Prefer this network. -->
+    <template is="dom-if"
+        if="[[showPreferNetwork_(managedProperties_, globalPolicy,
             managedNetworkAvailable)]]">
-      <!-- Shared network. -->
-      <div class$="settings-box settings-box-text
-                  [[messagesDividerClass_('shared', managedProperties_,
-                      globalPolicy, managedNetworkAvailable,
-                      isSecondaryUser_, isWifiSyncEnabled_)]]">
-          [[sharedString_(managedProperties_)]]
+      <div id="preferNetworkToggleContainer" class="settings-box"
+          on-click="onPreferNetworkRowClicked_"
+          actionable$="[[!isNetworkPolicyEnforced(
+              managedProperties_.priority)]]">
+        <div id="preferNetworkToggleLabel" class="start settings-box-text">
+          $i18n{networkPrefer}
+        </div>
+        <cr-policy-network-indicator-mojo
+            property="[[managedProperties_.priority]]">
+        </cr-policy-network-indicator-mojo>
+        <cr-toggle id="preferNetworkToggle" checked="{{preferNetwork_}}"
+            disabled="[[shouldPreferNetworkToggleBeDisabled_(
+                managedProperties_.priority, disabled_)]]"
+            aria-labelledby="preferNetworkToggleLabel"
+            deep-link-focus-id$="[[Setting.kPreferWifiNetwork]]">
+        </cr-toggle>
       </div>
     </template>
+    <!-- Hidden. -->
     <template is="dom-if"
-        if="[[showSynced_(managedProperties_, globalPolicy,
-            managedNetworkAvailable, isWifiSyncEnabled_)]]">
-      <!-- Synced network. -->
-      <div class$="settings-box settings-box-text
-                  [[messagesDividerClass_('synced', managedProperties_,
-                      globalPolicy, managedNetworkAvailable,
-                      isSecondaryUser_, isWifiSyncEnabled_)]]">
-          <settings-localized-link
-            localized-string="[[syncedString_(managedProperties_)]]">
-          </settings-localized-link>
+        if="[[showHiddenNetwork_(managedProperties_, globalPolicy,
+            managedNetworkAvailable)]]">
+      <settings-toggle-button id="hiddenToggle" class="hr"
+          pref="{{hiddenPref_}}"
+          label="$i18n{networkHidden}"
+          sub-label="$i18n{networkHiddenSublabel}"
+          sub-label-icon="cr20:warning"
+          learn-more-url="$i18n{wifiHiddenNetworkLearnMoreUrl}"
+          deep-link-focus-id$="[[Setting.kWifiHidden]]">
+      </settings-toggle-button>
+    </template>
+    <!-- Autoconnect. -->
+    <template is="dom-if"
+        if="[[showAutoConnect_(managedProperties_, globalPolicy,
+            managedNetworkAvailable)]]">
+      <settings-toggle-button id="autoConnectToggle" class="hr"
+          pref="{{autoConnectPref_}}"
+          label="[[getAutoConnectToggleLabel_(managedProperties_)]]"
+          deep-link-focus-id$="[[Setting.kWifiAutoConnectToNetwork]]
+              [[Setting.kCellularAutoConnectToNetwork]]"
+          disabled="[[disabled_]]">
+      </settings-toggle-button>
+      <!-- Hidden Network Warning -->
+      <template is="dom-if"
+          if="[[showHiddenNetworkWarning_(autoConnectPref_.*,
+              managedProperties_)]]"
+          restamp>
+        <div class="warning">
+          <iron-icon icon="cr:warning"></iron-icon>
+          [[i18n('hiddenNetworkWarning')]]
+        </div>
+      </template>
+    </template>
+    <!-- Always-on VPN. -->
+    <template is="dom-if"
+        if="[[showAlwaysOnVpn_(managedProperties_)]]">
+      <settings-toggle-button id="alwaysOnVpnToggle" class="hr"
+          pref="{{alwaysOnVpn_}}"
+          label="$i18n{networkAlwaysOnVpn}"
+          disabled="[[disabled_]]">
+      </settings-toggle-button>
+    </template>
+    <!-- Data roaming (Cellular only). -->
+    <template is="dom-if" if="[[isCellular_(managedProperties_)]]">
+      <cellular-roaming-toggle-button
+        disabled="[[disabled_]]"
+        prefs="{{prefs}}"
+        managed-properties="[[managedProperties_]]">
+      </cellular-roaming-toggle-button>
+    </template>
+    <!-- SIM Info (Cellular only). -->
+    <!-- TODO(crbug/1093185): Remove when updatedCellularActivationUi
+        flag launches -->
+    <template is="dom-if" if="[[showCellularSim_(managedProperties_)]]"
+        restamp>
+      <div class="settings-box single-column stretch">
+        <network-siminfo id="cellularSimInfo"
+            network-state="[[getNetworkState_(managedProperties_)]]"
+            device-state="[[deviceState_]]"
+            disabled="[[disabled_]]">
+        </network-siminfo>
       </div>
     </template>
-    <!-- End of NOTICES section -->
+    <!-- IP Address. -->
+    <div
+      class="settings-box two-line single-column stretch settings-box-text"
+      hidden$="[[!showIpAddress_(ipAddress_, managedProperties_)]]">
+      <div>$i18n{networkIPAddress}</div>
+      <div class="secondary">[[ipAddress_]]</div>
+    </div>
+    <!-- Properties to always show if present. -->
+    <template is="dom-if" if="[[hasInfoFields_(managedProperties_)]]">
+      <div class="settings-box single-column stretch">
+        <network-property-list-mojo id="infoFields"
+            fields="[[getInfoFields_(managedProperties_)]]"
+            edit-field-types="[[getInfoEditFieldTypes_(
+              managedProperties_)]]"
+            property-dict="[[managedProperties_]]"
+            on-property-change="onNetworkPropertyChange_"
+            disabled="[[disabled_]]">
+        </network-property-list-mojo>
+      </div>
+    </template>
+  </template>
+  <template is="dom-if" if="[[hasAdvancedSection_(managedProperties_,
+                              propertiesReceived_, showMeteredToggle_,
+                              deviceState_)]]">
+    <!-- Advanced toggle. -->
+    <cr-expand-button
+        aria-label="$i18n{networkSectionAdvancedA11yLabel}"
+        class="settings-box"
+        expanded="{{advancedExpanded_}}">
+      $i18n{networkSectionAdvanced}
+    </cr-expand-button>
 
-    <template is="dom-if" if="[[!isSecondaryUser_]]">
-      <template is="dom-if" if="[[showConfigurableSections_]]"  restamp>
-        <!-- Prefer this network. -->
+    <!-- Advanced section -->
+    <iron-collapse opened="[[advancedExpanded_]]">
+      <div class="settings-box single-column stretch indented first">
+          <!-- SIM Info (Cellular only). -->
         <template is="dom-if"
-            if="[[showPreferNetwork_(managedProperties_, globalPolicy,
-                managedNetworkAvailable)]]">
-          <div id="preferNetworkToggleContainer" class="settings-box"
-              on-click="onPreferNetworkRowClicked_"
-              actionable$="[[!isNetworkPolicyEnforced(
-                  managedProperties_.priority)]]">
-            <div id="preferNetworkToggleLabel" class="start settings-box-text">
-              $i18n{networkPrefer}
-            </div>
-            <cr-policy-network-indicator-mojo
-                property="[[managedProperties_.priority]]">
-            </cr-policy-network-indicator-mojo>
-            <cr-toggle id="preferNetworkToggle" checked="{{preferNetwork_}}"
-                disabled="[[shouldPreferNetworkToggleBeDisabled_(
-                    managedProperties_.priority, disabled_)]]"
-                aria-labelledby="preferNetworkToggleLabel"
-                deep-link-focus-id$="[[Setting.kPreferWifiNetwork]]">
-            </cr-toggle>
-          </div>
-        </template>
-        <!-- Hidden. -->
-        <template is="dom-if"
-            if="[[showHiddenNetwork_(managedProperties_, globalPolicy,
-                managedNetworkAvailable)]]">
-          <settings-toggle-button id="hiddenToggle" class="hr"
-              pref="{{hiddenPref_}}"
-              label="$i18n{networkHidden}"
-              sub-label="$i18n{networkHiddenSublabel}"
-              sub-label-icon="cr20:warning"
-              learn-more-url="$i18n{wifiHiddenNetworkLearnMoreUrl}"
-              deep-link-focus-id$="[[Setting.kWifiHidden]]">
-          </settings-toggle-button>
-        </template>
-        <!-- Autoconnect. -->
-        <template is="dom-if"
-            if="[[showAutoConnect_(managedProperties_, globalPolicy,
-                managedNetworkAvailable)]]">
-          <settings-toggle-button id="autoConnectToggle" class="hr"
-              pref="{{autoConnectPref_}}"
-              label="[[getAutoConnectToggleLabel_(managedProperties_)]]"
-              deep-link-focus-id$="[[Setting.kWifiAutoConnectToNetwork]]
-                  [[Setting.kCellularAutoConnectToNetwork]]"
-              disabled="[[disabled_]]">
-          </settings-toggle-button>
-          <!-- Hidden Network Warning -->
-          <template is="dom-if"
-              if="[[showHiddenNetworkWarning_(autoConnectPref_.*,
-                  managedProperties_)]]"
-              restamp>
-            <div class="warning">
-              <iron-icon icon="cr:warning"></iron-icon>
-              [[i18n('hiddenNetworkWarning')]]
-            </div>
-          </template>
-        </template>
-        <!-- Always-on VPN. -->
-        <template is="dom-if"
-            if="[[showAlwaysOnVpn_(managedProperties_)]]">
-          <settings-toggle-button id="alwaysOnVpnToggle" class="hr"
-              pref="{{alwaysOnVpn_}}"
-              label="$i18n{networkAlwaysOnVpn}"
-              disabled="[[disabled_]]">
-          </settings-toggle-button>
-        </template>
-        <!-- Data roaming (Cellular only). -->
-        <template is="dom-if" if="[[isCellular_(managedProperties_)]]">
-          <cellular-roaming-toggle-button
-            disabled="[[disabled_]]"
-            prefs="{{prefs}}"
-            managed-properties="[[managedProperties_]]">
-          </cellular-roaming-toggle-button>
-        </template>
-        <!-- SIM Info (Cellular only). -->
-        <!-- TODO(crbug/1093185): Remove when updatedCellularActivationUi
-            flag launches -->
-        <template is="dom-if" if="[[showCellularSim_(managedProperties_)]]"
-            restamp>
-          <div class="settings-box single-column stretch">
-            <network-siminfo id="cellularSimInfo"
+            if="[[showCellularSimUpdatedUi_(managedProperties_)]]" restamp>
+          <div class="single-column stretch">
+            <network-siminfo id="cellularSimInfoAdvanced"
                 network-state="[[getNetworkState_(managedProperties_)]]"
                 device-state="[[deviceState_]]"
                 disabled="[[disabled_]]">
             </network-siminfo>
           </div>
         </template>
-        <!-- IP Address. -->
-        <div
-          class="settings-box two-line single-column stretch settings-box-text"
-          hidden$="[[!showIpAddress_(ipAddress_, managedProperties_)]]">
-          <div>$i18n{networkIPAddress}</div>
-          <div class="secondary">[[ipAddress_]]</div>
+        <!-- Metered (WiFi and Cellular only). -->
+        <template is="dom-if"
+            if="[[showMetered_(managedProperties_, showMeteredToggle_)]]">
+          <network-config-toggle id="meteredToggle" policy-on-left
+              property="[[managedProperties_.metered]]"
+              label="$i18n{networkMetered}"
+              sub-label="$i18n{networkMeteredDesc}"
+              checked="{{meteredOverride_}}"
+              on-checked-changed="meteredChanged_"
+              deep-link-focus-id$="[[Setting.kWifiMetered]]
+                  [[Setting.kCellularMetered]]"
+              disabled="[[disabled_]]">
+          </network-config-toggle>
+        </template>
+        <!-- Advanced properties -->
+        <template is="dom-if"
+            if="[[hasAdvancedFields_(managedProperties_)]]">
+          <network-property-list-mojo id="advancedFields"
+              fields="[[getAdvancedFields_(managedProperties_)]]"
+              property-dict="[[managedProperties_]]"
+              disabled="[[disabled_]]">
+          </network-property-list-mojo>
+        </template>
+        <!-- Device properties -->
+        <template is="dom-if"
+            if="[[hasDeviceFields_(managedProperties_, deviceState_)]]">
+          <network-property-list-mojo id="deviceFields"
+              fields="[[getDeviceFields_(managedProperties_,
+                  deviceState_)]]"
+              property-dict="[[managedProperties_]]"
+              disabled="[[disabled_]]">
+          </network-property-list-mojo>
+        </template>
+      </div>
+    </iron-collapse>
+  </template>
+
+  <template is="dom-if" if="[[showConfigurableSections_]]"  restamp>
+    <template is="dom-if" if="[[hasNetworkSection_(managedProperties_,
+        globalPolicy, managedNetworkAvailable)]]">
+      <!-- Network toggle -->
+      <cr-expand-button
+          id="configurableSections"
+          aria-label="$i18n{networkSectionNetworkExpandA11yLabel}"
+          class="settings-box"
+          expanded="{{networkExpanded_}}">
+        <div class="settings-row">
+          <div class="start">
+            $i18n{networkSectionNetwork}
+          </div>
+          <template is="dom-if" if="[[showScanningSpinner_(
+              managedProperties_, deviceState_)]]">
+            <paper-spinner-lite active></paper-spinner-lite>
+          </template>
         </div>
-        <!-- Properties to always show if present. -->
-        <template is="dom-if" if="[[hasInfoFields_(managedProperties_)]]">
-          <div class="settings-box single-column stretch">
-            <network-property-list-mojo id="infoFields"
-                fields="[[getInfoFields_(managedProperties_)]]"
-                edit-field-types="[[getInfoEditFieldTypes_(
-                  managedProperties_)]]"
-                property-dict="[[managedProperties_]]"
-                on-property-change="onNetworkPropertyChange_"
-                disabled="[[disabled_]]">
-            </network-property-list-mojo>
-          </div>
-        </template>
-      </template>
-      <template is="dom-if" if="[[hasAdvancedSection_(managedProperties_,
-                                 propertiesReceived_, showMeteredToggle_,
-                                 deviceState_)]]">
-        <!-- Advanced toggle. -->
-        <cr-expand-button
-            aria-label="$i18n{networkSectionAdvancedA11yLabel}"
-            class="settings-box"
-            expanded="{{advancedExpanded_}}">
-          $i18n{networkSectionAdvanced}
-        </cr-expand-button>
+      </cr-expand-button>
 
-        <!-- Advanced section -->
-        <iron-collapse opened="[[advancedExpanded_]]">
-          <div class="settings-box single-column stretch indented first">
-             <!-- SIM Info (Cellular only). -->
-            <template is="dom-if"
-                if="[[showCellularSimUpdatedUi_(managedProperties_)]]" restamp>
-              <div class="single-column stretch">
-                <network-siminfo id="cellularSimInfoAdvanced"
-                    network-state="[[getNetworkState_(managedProperties_)]]"
-                    device-state="[[deviceState_]]"
-                    disabled="[[disabled_]]">
-                </network-siminfo>
-              </div>
-            </template>
-            <!-- Metered (WiFi and Cellular only). -->
-            <template is="dom-if"
-                if="[[showMetered_(managedProperties_, showMeteredToggle_)]]">
-              <network-config-toggle id="meteredToggle" policy-on-left
-                  property="[[managedProperties_.metered]]"
-                  label="$i18n{networkMetered}"
-                  sub-label="$i18n{networkMeteredDesc}"
-                  checked="{{meteredOverride_}}"
-                  on-checked-changed="meteredChanged_"
-                  deep-link-focus-id$="[[Setting.kWifiMetered]]
-                      [[Setting.kCellularMetered]]"
-                  disabled="[[disabled_]]">
-              </network-config-toggle>
-            </template>
-            <!-- Advanced properties -->
-            <template is="dom-if"
-                if="[[hasAdvancedFields_(managedProperties_)]]">
-              <network-property-list-mojo id="advancedFields"
-                  fields="[[getAdvancedFields_(managedProperties_)]]"
-                  property-dict="[[managedProperties_]]"
-                  disabled="[[disabled_]]">
-              </network-property-list-mojo>
-            </template>
-            <!-- Device properties -->
-            <template is="dom-if"
-                if="[[hasDeviceFields_(managedProperties_, deviceState_)]]">
-              <network-property-list-mojo id="deviceFields"
-                  fields="[[getDeviceFields_(managedProperties_,
-                      deviceState_)]]"
-                  property-dict="[[managedProperties_]]"
-                  disabled="[[disabled_]]">
-              </network-property-list-mojo>
-            </template>
-          </div>
-        </iron-collapse>
-      </template>
-
-      <template is="dom-if" if="[[showConfigurableSections_]]"  restamp>
-        <template is="dom-if" if="[[hasNetworkSection_(managedProperties_,
-            globalPolicy, managedNetworkAvailable)]]">
-          <!-- Network toggle -->
-          <cr-expand-button
-              id="configurableSections"
-              aria-label="$i18n{networkSectionNetworkExpandA11yLabel}"
-              class="settings-box"
-              expanded="{{networkExpanded_}}">
-            <div class="settings-row">
-              <div class="start">
-                $i18n{networkSectionNetwork}
-              </div>
-              <template is="dom-if" if="[[showScanningSpinner_(
-                  managedProperties_, deviceState_)]]">
-                <paper-spinner-lite active></paper-spinner-lite>
-              </template>
-            </div>
-          </cr-expand-button>
-
-          <iron-collapse opened="[[networkExpanded_]]">
-            <div class="settings-box single-column stretch indented first">
-              <!-- Choose Mobile Network (Cellular only). -->
-              <template is="dom-if"
-                  if="[[showCellularChooseNetwork_(managedProperties_)]]">
-                <network-choose-mobile device-state="[[deviceState_]]"
-                    managed-properties="[[managedProperties_]]"
-                    disabled="[[disabled_]]">
-                </network-choose-mobile>
-              </template>
-
-              <!-- APN -->
-              <template is="dom-if" if="[[isCellular_(managedProperties_)]]">
-                <network-apnlist on-apn-change="onApnChange_"
-                    managed-properties="[[managedProperties_]]"
-                    disabled="[[disabled_]]">
-                </network-apnlist>
-              </template>
-
-              <!-- IP Config, Nameservers -->
-              <template is="dom-if"
-                  if="[[isRememberedOrConnected_(managedProperties_)]]">
-                <network-ip-config on-ip-change="onIPConfigChange_"
-                    managed-properties="[[managedProperties_]]"
-                    disabled="[[disabled_]]">
-                </network-ip-config>
-                <network-nameservers on-nameservers-change="onIPConfigChange_"
-                    managed-properties="[[managedProperties_]]"
-                    disabled="[[disabled_]]">
-                </network-nameservers>
-              </template>
-            </div>
-
-            <!-- MAC Address. -->
-            <div class="settings-box two-line single-column stretch indented"
-                id="mac-address-container"
-                hidden$="[[!shouldShowMacAddress_(deviceState_)]]">
-              <div>$i18n{OncMacAddress}</div>
-              <div class="secondary">[[getMacAddress_(deviceState_)]]</div>
-            </div>
-          </iron-collapse>
-        </template>
-
-        <template is="dom-if" if="[[hasProxySection_(managedProperties_,
-            globalPolicy, managedNetworkAvailable)]]">
-          <!-- Proxy toggle -->
-          <cr-expand-button
-              aria-label="$i18n{networkSectionProxyExpandA11yLabel}"
-              class="settings-box"
-              expanded="{{proxyExpanded_}}">
-            $i18n{networkSectionProxy}
-          </cr-expand-button>
-
-          <iron-collapse opened="[[proxyExpanded_]]">
-            <network-proxy-section prefs="{{prefs}}"
-                on-proxy-change="onProxyChange_"
+      <iron-collapse opened="[[networkExpanded_]]">
+        <div class="settings-box single-column stretch indented first">
+          <!-- Choose Mobile Network (Cellular only). -->
+          <template is="dom-if"
+              if="[[showCellularChooseNetwork_(managedProperties_)]]">
+            <network-choose-mobile device-state="[[deviceState_]]"
                 managed-properties="[[managedProperties_]]"
                 disabled="[[disabled_]]">
-            </network-proxy-section>
-          </iron-collapse>
-        </template>
-      </template>
+            </network-choose-mobile>
+          </template>
+
+          <!-- APN -->
+          <template is="dom-if" if="[[isCellular_(managedProperties_)]]">
+            <network-apnlist on-apn-change="onApnChange_"
+                managed-properties="[[managedProperties_]]"
+                disabled="[[disabled_]]">
+            </network-apnlist>
+          </template>
+
+          <!-- IP Config, Nameservers -->
+          <template is="dom-if"
+              if="[[isRememberedOrConnected_(managedProperties_)]]">
+            <network-ip-config on-ip-change="onIPConfigChange_"
+                managed-properties="[[managedProperties_]]"
+                disabled="[[disabled_]]">
+            </network-ip-config>
+            <network-nameservers on-nameservers-change="onIPConfigChange_"
+                managed-properties="[[managedProperties_]]"
+                disabled="[[disabled_]]">
+            </network-nameservers>
+          </template>
+        </div>
+
+        <!-- MAC Address. -->
+        <div class="settings-box two-line single-column stretch indented"
+            id="mac-address-container"
+            hidden$="[[!shouldShowMacAddress_(deviceState_)]]">
+          <div>$i18n{OncMacAddress}</div>
+          <div class="secondary">[[getMacAddress_(deviceState_)]]</div>
+        </div>
+      </iron-collapse>
     </template>
-    <template is="dom-if" if="[[showConfigurableSections_]]"  restamp>
-      <template is="dom-if" if="[[isTether_(managedProperties_)]]" restamp>
-        <tether-connection-dialog id="tetherDialog"
+
+    <template is="dom-if" if="[[hasProxySection_(managedProperties_,
+        globalPolicy, managedNetworkAvailable)]]">
+      <!-- Proxy toggle -->
+      <cr-expand-button
+          aria-label="$i18n{networkSectionProxyExpandA11yLabel}"
+          class="settings-box"
+          expanded="{{proxyExpanded_}}">
+        $i18n{networkSectionProxy}
+      </cr-expand-button>
+
+      <iron-collapse opened="[[proxyExpanded_]]">
+        <network-proxy-section prefs="{{prefs}}"
+            on-proxy-change="onProxyChange_"
             managed-properties="[[managedProperties_]]"
-            on-tether-connect="onTetherConnect_"
-            out-of-range="[[outOfRange_]]">
-        </tether-connection-dialog>
-      </template>
+            disabled="[[disabled_]]">
+        </network-proxy-section>
+      </iron-collapse>
     </template>
   </template>
-  <script src="internet_detail_page.js"></script>
-</dom-module>
+</template>
+<template is="dom-if" if="[[showConfigurableSections_]]"  restamp>
+  <template is="dom-if" if="[[isTether_(managedProperties_)]]" restamp>
+    <tether-connection-dialog id="tetherDialog"
+        managed-properties="[[managedProperties_]]"
+        on-tether-connect="onTetherConnect_"
+        out-of-range="[[outOfRange_]]">
+    </tether-connection-dialog>
+  </template>
+</template>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.js
index 3ba10d2..a2025be1 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.js
@@ -8,14 +8,60 @@
  * for a network.
  */
 
+import '//resources/cr_components/chromeos/network/cr_policy_network_indicator_mojo.m.js';
+import '//resources/cr_components/chromeos/network/network_apnlist.m.js';
+import '//resources/cr_components/chromeos/network/network_choose_mobile.m.js';
+import '//resources/cr_components/chromeos/network/network_config_toggle.m.js';
+import '//resources/cr_components/chromeos/network/network_icon.m.js';
+import '//resources/cr_components/chromeos/network/network_ip_config.m.js';
+import '//resources/cr_components/chromeos/network/network_nameservers.m.js';
+import '//resources/cr_components/chromeos/network/network_property_list_mojo.m.js';
+import '//resources/cr_components/chromeos/network/network_siminfo.m.js';
+import '//resources/cr_elements/cr_button/cr_button.m.js';
+import '//resources/cr_elements/cr_expand_button/cr_expand_button.m.js';
+import '//resources/cr_elements/cr_toggle/cr_toggle.m.js';
+import '//resources/cr_elements/icons.m.js';
+import '//resources/cr_elements/policy/cr_policy_indicator.m.js';
+import '//resources/polymer/v3_0/iron-collapse/iron-collapse.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '//resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js';
+import '../../controls/controlled_button.js';
+import '../../controls/settings_toggle_button.js';
+import '../../prefs/prefs.js';
+import './cellular_roaming_toggle_button.js';
+import './internet_shared_css.js';
+import './network_proxy_section.js';
+import './tether_connection_dialog.js';
+
+import {getSimSlotCount, hasActiveCellularNetwork, isActiveSim, isConnectedToNonCellularNetwork} from '//resources/cr_components/chromeos/network/cellular_utils.m.js';
+import {CrPolicyNetworkBehaviorMojo} from '//resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.m.js';
+import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from '//resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
+import {NetworkListenerBehavior} from '//resources/cr_components/chromeos/network/network_listener_behavior.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {assert, assertNotReached} from '//resources/js/assert.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {StatusAction, SyncBrowserProxy, SyncBrowserProxyImpl, SyncPrefs, SyncStatus} from '../../people_page/sync_browser_proxy.js';
+import {Route, RouteObserverBehavior, Router} from '../../router.js';
+import {DeepLinkingBehavior} from '../deep_linking_behavior.m.js';
+import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from '../metrics_recorder.m.js';
+import {OsSyncBrowserProxy, OsSyncBrowserProxyImpl, OsSyncPrefs} from '../os_people_page/os_sync_browser_proxy.m.js';
+import {routes} from '../os_route.m.js';
+
+import {InternetPageBrowserProxy, InternetPageBrowserProxyImpl} from './internet_page_browser_proxy.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'settings-internet-detail-page',
 
   behaviors: [
     NetworkListenerBehavior,
     CrPolicyNetworkBehaviorMojo,
     DeepLinkingBehavior,
-    settings.RouteObserverBehavior,
+    RouteObserverBehavior,
     I18nBehavior,
     WebUIListenerBehavior,
   ],
@@ -319,13 +365,13 @@
    */
   shouldShowConfigureWhenNetworkLoaded_: false,
 
-  /** @private  {settings.InternetPageBrowserProxy} */
+  /** @private  {InternetPageBrowserProxy} */
   browserProxy_: null,
 
-  /** @private {?settings.OsSyncBrowserProxy} */
+  /** @private {?OsSyncBrowserProxy} */
   osSyncBrowserProxy_: null,
 
-  /** @private {?settings.SyncBrowserProxy} */
+  /** @private {?SyncBrowserProxy} */
   syncBrowserProxy_: null,
 
   /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
@@ -359,14 +405,14 @@
 
   /** @override */
   created() {
-    this.browserProxy_ = settings.InternetPageBrowserProxyImpl.getInstance();
-    this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
-                              .getMojoServiceRemote();
+    this.browserProxy_ = InternetPageBrowserProxyImpl.getInstance();
+    this.networkConfig_ =
+        MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote();
 
     if (loadTimeData.getBoolean('splitSettingsSyncEnabled')) {
-      this.osSyncBrowserProxy_ = settings.OsSyncBrowserProxyImpl.getInstance();
+      this.osSyncBrowserProxy_ = OsSyncBrowserProxyImpl.getInstance();
     } else {
-      this.syncBrowserProxy_ = settings.SyncBrowserProxyImpl.getInstance();
+      this.syncBrowserProxy_ = SyncBrowserProxyImpl.getInstance();
     }
   },
 
@@ -378,7 +424,7 @@
    */
   afterRenderShowDeepLink(settingId, elementCallback) {
     // Wait for element to load.
-    Polymer.RenderStatus.afterNextRender(this, () => {
+    afterNextRender(this, () => {
       const deepLinkElement = elementCallback();
       if (!deepLinkElement || deepLinkElement.hidden) {
         console.warn(`Element with deep link id ${settingId} not focusable.`);
@@ -478,17 +524,17 @@
   },
 
   /**
-   * settings.RouteObserverBehavior
-   * @param {!settings.Route} route
-   * @param {!settings.Route} oldRoute
+   * RouteObserverBehavior
+   * @param {!Route} route
+   * @param {!Route} oldRoute
    * @protected
    */
   currentRouteChanged(route, oldRoute) {
-    if (route !== settings.routes.NETWORK_DETAIL) {
+    if (route !== routes.NETWORK_DETAIL) {
       return;
     }
 
-    const queryParams = settings.Router.getInstance().getQueryParameters();
+    const queryParams = Router.getInstance().getQueryParameters();
     const guid = queryParams.get('guid') || '';
     if (!guid) {
       console.warn('No guid specified for page:' + route);
@@ -554,7 +600,7 @@
       this.managedProperties_ = undefined;
       this.propertiesReceived_ = false;
 
-      settings.Router.getInstance().navigateToPreviousRoute();
+      Router.getInstance().navigateToPreviousRoute();
     });
   },
 
@@ -631,17 +677,17 @@
     // Update the detail page title.
     const networkName = OncMojo.getNetworkName(this.managedProperties_);
     this.parentNode.pageTitle = networkName;
-    Polymer.dom.flush();
+    flush();
 
     if (!this.didSetFocus_ &&
-        !settings.Router.getInstance().getQueryParameters().has('search') &&
+        !Router.getInstance().getQueryParameters().has('search') &&
         !this.getDeepLinkSettingId()) {
       // Unless the page was navigated to via search or has a deep linked
       // setting, focus a button once the initial state is set.
       this.didSetFocus_ = true;
       const button = this.$$('#titleDiv .action-button:not([hidden])');
       if (button) {
-        Polymer.RenderStatus.afterNextRender(this, () => button.focus());
+        afterNextRender(this, () => button.focus());
       }
     }
 
@@ -737,7 +783,7 @@
     // This is slightly preferable to requestAnimationFrame used within
     // network-siminfo to focus elements since it can be reproduced in
     // testing.
-    Polymer.RenderStatus.afterNextRender(this, () => {
+    afterNextRender(this, () => {
       if (simLockStatus && !!simLockStatus.lockType) {
         this.afterRenderShowDeepLink(
             settingId, () => this.$$('network-siminfo').getUnlockButton());
@@ -763,7 +809,7 @@
     if (!this.propertiesReceived_) {
       return;
     }
-    settings.recordSettingChange(
+    recordSettingChange(
         chromeos.settings.mojom.Setting.kWifiHidden,
         {boolValue: !!this.hiddenPref_.value});
     const config = this.getDefaultConfigProperties_();
@@ -1006,7 +1052,7 @@
           this.managedProperties_.typeProperties.cellular;
     }
     this.managedProperties_ = properties;
-    Polymer.RenderStatus.afterNextRender(this, () => {
+    afterNextRender(this, () => {
       this.applyingChanges_ = false;
     });
   },
@@ -1083,7 +1129,7 @@
         this.getNetworkDetails_();
       }
     });
-    settings.recordSettingChange();
+    recordSettingChange();
   },
 
   /**
@@ -1556,7 +1602,7 @@
     this.fire(
         'network-connect',
         {networkState: networkState, bypassConnectionDialog: bypassDialog});
-    settings.recordSettingChange();
+    recordSettingChange();
   },
 
   /** @private */
@@ -1566,7 +1612,7 @@
         console.warn('Disconnect failed for: ' + this.guid);
       }
     });
-    settings.recordSettingChange();
+    recordSettingChange();
   },
 
   /** @private */
@@ -1646,10 +1692,9 @@
 
     if (this.managedProperties_.type ===
         chromeos.networkConfig.mojom.NetworkType.kWiFi) {
-      settings.recordSettingChange(
-          chromeos.settings.mojom.Setting.kForgetWifiNetwork);
+      recordSettingChange(chromeos.settings.mojom.Setting.kForgetWifiNetwork);
     } else {
-      settings.recordSettingChange();
+      recordSettingChange();
     }
   },
 
@@ -1664,7 +1709,7 @@
         (this.isThirdPartyVpn_(this.managedProperties_) ||
          this.isArcVpn_(this.managedProperties_))) {
       this.browserProxy_.configureThirdPartyVpn(this.guid);
-      settings.recordSettingChange();
+      recordSettingChange();
       return;
     }
 
@@ -2031,7 +2076,7 @@
     }
 
     this.preferNetwork_ = !this.preferNetwork_;
-    settings.recordSettingChange();
+    recordSettingChange();
   },
 
   /**
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html
index 10b93a9..f1c21688 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html
@@ -1,107 +1,84 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="internet-shared iron-flex">
+  cr-policy-indicator {
+    margin-inline-start: var(--settings-controlled-by-spacing);
+  }
+</style>
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html">
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../../settings_shared_css.html">
-<link rel="import" href="../deep_linking_behavior.html">
-<link rel="import" href="../metrics_recorder.html">
-<link rel="import" href="../os_route.html">
-<link rel="import" href="internet_shared_css.html">
+<div class="settings-box first">
+  <div class="settings-box-text">$i18n{knownNetworksMessage}</div>
+</div>
 
-<dom-module id="settings-internet-known-networks-page">
-  <template>
-    <style include="internet-shared iron-flex">
-      cr-policy-indicator {
-        margin-inline-start: var(--settings-controlled-by-spacing);
-      }
-    </style>
-
-    <div class="settings-box first">
-      <div class="settings-box-text">$i18n{knownNetworksMessage}</div>
+<div class="settings-box settings-box-text">
+  <div class="secondary">$i18n{knownNetworksPreferred}</div>
+</div>
+<div class="list-frame vertical-list"
+    hidden$="[[havePreferred_(networkStateList_)]]">
+  <div class="list-item settings-box-text">
+    $i18n{internetNoNetworks}
+  </div>
+</div>
+<div id="preferredNetworkList" class="list-frame vertical-list"
+    hidden$="[[!havePreferred_(networkStateList_)]]">
+  <template is="dom-repeat" items="[[networkStateList_]]"
+      filter="networkIsPreferred_">
+    <div class="list-item">
+      <cr-link-row embedded label="[[getNetworkDisplayName_(item)]]"
+          on-click="fireShowDetails_"
+          role-description="$i18n{subpageArrowRoleDescription}"
+          deep-link-focus-id$="[[Setting.kForgetWifiNetwork]]">
+        <template is="dom-if" if="[[isPolicySource(item.source))]]">
+          <cr-policy-indicator on-click="doNothing_"
+              indicator-type="[[getIndicatorTypeForSource(item.source)]]">
+          </cr-policy-indicator>
+        </template>
+      </cr-link-row>
+      <div class="separator"></div>
+      <cr-icon-button class="icon-more-vert" tabindex$="[[tabindex]]"
+          on-click="onMenuButtonTap_" title="$i18n{moreActions}">
+      </cr-icon-button>
     </div>
-
-    <div class="settings-box settings-box-text">
-      <div class="secondary">$i18n{knownNetworksPreferred}</div>
-    </div>
-    <div class="list-frame vertical-list"
-        hidden$="[[havePreferred_(networkStateList_)]]">
-      <div class="list-item settings-box-text">
-        $i18n{internetNoNetworks}
-      </div>
-    </div>
-    <div id="preferredNetworkList" class="list-frame vertical-list"
-        hidden$="[[!havePreferred_(networkStateList_)]]">
-      <template is="dom-repeat" items="[[networkStateList_]]"
-          filter="networkIsPreferred_">
-        <div class="list-item">
-          <cr-link-row embedded label="[[getNetworkDisplayName_(item)]]"
-              on-click="fireShowDetails_"
-              role-description="$i18n{subpageArrowRoleDescription}"
-              deep-link-focus-id$="[[Setting.kForgetWifiNetwork]]">
-            <template is="dom-if" if="[[isPolicySource(item.source))]]">
-              <cr-policy-indicator on-click="doNothing_"
-                  indicator-type="[[getIndicatorTypeForSource(item.source)]]">
-              </cr-policy-indicator>
-            </template>
-          </cr-link-row>
-          <div class="separator"></div>
-          <cr-icon-button class="icon-more-vert" tabindex$="[[tabindex]]"
-              on-click="onMenuButtonTap_" title="$i18n{moreActions}">
-          </cr-icon-button>
-        </div>
-      </template>
-    </div>
-
-    <div class="settings-box settings-box-text">
-      <div class="secondary">$i18n{knownNetworksAll}</div>
-    </div>
-    <div id="notPreferredNetworkList" class="list-frame vertical-list"
-        hidden$="[[!haveNotPreferred_(networkStateList_)]]">
-      <template is="dom-repeat" items="[[networkStateList_]]"
-          filter="networkIsNotPreferred_">
-        <div class="list-item">
-          <cr-link-row embedded label="[[getNetworkDisplayName_(item)]]"
-              on-click="fireShowDetails_"
-              role-description="$i18n{subpageArrowRoleDescription}"
-              deep-link-focus-id$="[[Setting.kPreferWifiNetwork]]
-                  [[Setting.kForgetWifiNetwork]]">
-            <template is="dom-if" if="[[isPolicySource(item.source))]]">
-              <cr-policy-indicator on-click="doNothing_"
-                  indicator-type="[[getIndicatorTypeForSource(item.source)]]">
-              </cr-policy-indicator>
-            </template>
-          </cr-link-row>
-          <div class="separator"></div>
-          <cr-icon-button class="icon-more-vert" tabindex$="[[tabindex]]"
-              on-click="onMenuButtonTap_" title="$i18n{moreActions}">
-          </cr-icon-button>
-        </div>
-      </template>
-    </div>
-
-    <cr-action-menu id="dotsMenu" role-description="$i18n{menu}">
-      <button class="dropdown-item" hidden="[[!showAddPreferred_]]"
-          on-click="onAddPreferredTap_">
-        $i18n{knownNetworksMenuAddPreferred}
-      </button>
-      <button class="dropdown-item"
-          hidden="[[!showRemovePreferred_]]" on-click="onRemovePreferredTap_">
-        $i18n{knownNetworksMenuRemovePreferred}
-      </button>
-      <button class="dropdown-item" disabled="[[!enableForget_]]"
-          on-click="onForgetTap_">
-        $i18n{knownNetworksMenuForget}
-      </button>
-    </cr-action-menu>
-
   </template>
-  <script src="internet_known_networks_page.js"></script>
-</dom-module>
+</div>
+
+<div class="settings-box settings-box-text">
+  <div class="secondary">$i18n{knownNetworksAll}</div>
+</div>
+<div id="notPreferredNetworkList" class="list-frame vertical-list"
+    hidden$="[[!haveNotPreferred_(networkStateList_)]]">
+  <template is="dom-repeat" items="[[networkStateList_]]"
+      filter="networkIsNotPreferred_">
+    <div class="list-item">
+      <cr-link-row embedded label="[[getNetworkDisplayName_(item)]]"
+          on-click="fireShowDetails_"
+          role-description="$i18n{subpageArrowRoleDescription}"
+          deep-link-focus-id$="[[Setting.kPreferWifiNetwork]]
+              [[Setting.kForgetWifiNetwork]]">
+        <template is="dom-if" if="[[isPolicySource(item.source))]]">
+          <cr-policy-indicator on-click="doNothing_"
+              indicator-type="[[getIndicatorTypeForSource(item.source)]]">
+          </cr-policy-indicator>
+        </template>
+      </cr-link-row>
+      <div class="separator"></div>
+      <cr-icon-button class="icon-more-vert" tabindex$="[[tabindex]]"
+          on-click="onMenuButtonTap_" title="$i18n{moreActions}">
+      </cr-icon-button>
+    </div>
+  </template>
+</div>
+
+<cr-action-menu id="dotsMenu" role-description="$i18n{menu}">
+  <button class="dropdown-item" hidden="[[!showAddPreferred_]]"
+      on-click="onAddPreferredTap_">
+    $i18n{knownNetworksMenuAddPreferred}
+  </button>
+  <button class="dropdown-item"
+      hidden="[[!showRemovePreferred_]]" on-click="onRemovePreferredTap_">
+    $i18n{knownNetworksMenuRemovePreferred}
+  </button>
+  <button class="dropdown-item" disabled="[[!enableForget_]]"
+      on-click="onForgetTap_">
+    $i18n{knownNetworksMenuForget}
+  </button>
+</cr-action-menu>
+
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 c1eec2c..fd35083 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
@@ -7,14 +7,34 @@
  * 'settings-internet-known-networks' is the settings subpage listing the
  * known networks for a type (currently always WiFi).
  */
+import '//resources/cr_elements/cr_action_menu/cr_action_menu.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_link_row/cr_link_row.js';
+import '//resources/cr_elements/icons.m.js';
+import '../../settings_shared_css.js';
+import './internet_shared_css.js';
+
+import {CrPolicyNetworkBehaviorMojo} from '//resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.m.js';
+import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from '//resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
+import {NetworkListenerBehavior} from '//resources/cr_components/chromeos/network/network_listener_behavior.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {assert, assertNotReached} from '//resources/js/assert.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {Route, RouteObserverBehavior, Router} from '../../router.js';
+import {DeepLinkingBehavior} from '../deep_linking_behavior.m.js';
+import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from '../metrics_recorder.m.js';
+import {routes} from '../os_route.m.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'settings-internet-known-networks-page',
 
   behaviors: [
     DeepLinkingBehavior,
     NetworkListenerBehavior,
     CrPolicyNetworkBehaviorMojo,
-    settings.RouteObserverBehavior,
+    RouteObserverBehavior,
   ],
 
   properties: {
@@ -83,19 +103,19 @@
 
   /** @override */
   created() {
-    this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
-                              .getMojoServiceRemote();
+    this.networkConfig_ =
+        MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote();
   },
 
   /**
-   * settings.RouteObserverBehavior
-   * @param {!settings.Route} route
-   * @param {!settings.Route} oldRoute
+   * RouteObserverBehavior
+   * @param {!Route} route
+   * @param {!Route} oldRoute
    * @protected
    */
   currentRouteChanged(route, oldRoute) {
     // Does not apply to this page.
-    if (route !== settings.routes.KNOWN_NETWORKS) {
+    if (route !== routes.KNOWN_NETWORKS) {
       return;
     }
 
@@ -242,7 +262,7 @@
                 JSON.stringify(config));
           }
         });
-    settings.recordSettingChange();
+    recordSettingChange();
   },
 
   /** @private */
@@ -272,10 +292,9 @@
     });
 
     if (this.networkType === chromeos.networkConfig.mojom.NetworkType.kWiFi) {
-      settings.recordSettingChange(
-          chromeos.settings.mojom.Setting.kForgetWifiNetwork);
+      recordSettingChange(chromeos.settings.mojom.Setting.kForgetWifiNetwork);
     } else {
-      settings.recordSettingChange();
+      recordSettingChange();
     }
 
     /** @type {!CrActionMenuElement} */ (this.$.dotsMenu).close();
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.html
index 7d51597..6863673 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.html
@@ -1,216 +1,172 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="os-settings-icons settings-shared">
+  iron-icon.policy {
+    height: 24px;
+    margin-inline-end: 12px;
+    margin-inline-start: 4px;
+    width: 24px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup_icons.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_types.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/esim_manager_utils.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cellular_utils.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/sim_lock_dialogs.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html">
-<link rel="import" href="chrome://resources/cr_elements/icons.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="../../chromeos/os_settings_icons_css.html">
-<link rel="import" href="../../prefs/prefs.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../../settings_page/settings_animated_pages.html">
-<link rel="import" href="../../settings_page/settings_subpage.html">
-<link rel="import" href="../../settings_shared_css.html">
-<link rel="import" href="../deep_linking_behavior.html">
-<link rel="import" href="../metrics_recorder.html">
-<link rel="import" href="../os_route.html">
-<link rel="import" href="cellular_setup_dialog.html">
-<link rel="import" href="internet_config.html">
-<link rel="import" href="internet_detail_menu.html">
-<link rel="import" href="internet_detail_page.html">
-<link rel="import" href="internet_known_networks_page.html">
-<link rel="import" href="internet_page_browser_proxy.html">
-<link rel="import" href="internet_subpage.html">
-<link rel="import" href="network_summary.html">
-<link rel="import" href="esim_rename_dialog.html">
-<link rel="import" href="esim_remove_profile_dialog.html">
+  cr-toast {
+    --iron-icon-fill-color: var(--google-yellow-500);
+  }
 
-<dom-module id="settings-internet-page">
-  <template>
-    <style include="os-settings-icons settings-shared">
-      iron-icon.policy {
-        height: 24px;
-        margin-inline-end: 12px;
-        margin-inline-start: 4px;
-        width: 24px;
-      }
-
-      cr-toast {
-        --iron-icon-fill-color: var(--google-yellow-500);
-      }
-
-      cr-toast iron-icon {
-        margin-inline-end: 16px;
-      }
-    </style>
-    <settings-animated-pages id="pages" section="internet"
-        focus-config="[[focusConfig_]]">
-      <div route-path="default">
-        <network-summary default-network="{{defaultNetwork}}"
-            device-states="{{deviceStates}}"
-            on-active-networks-updated="attemptDeepLink">
-        </network-summary>
-        <template is="dom-if" if="[[allowAddConnection_(globalPolicy_,
-            managedNetworkAvailable)]]">
-          <cr-expand-button
-              aria-label="$i18n{internetAddConnectionExpandA11yLabel}"
-              class="settings-box two-line"
-              expanded="{{addConnectionExpanded_}}"
-              id="expandAddConnections">
-            <span aria-hidden="true">
-              $i18n{internetAddConnection}
-            </span>
-          </cr-expand-button>
-          <template is="dom-if" if="[[addConnectionExpanded_]]">
-            <div class="list-frame vertical-list">
-              <template is="dom-if" if="[[wifiIsEnabled_(deviceStates)]]">
-                <div actionable class="list-item" on-click="onAddWiFiTap_">
-                  <div class="start settings-box-text"
-                      id="add-wifi-label" aria-hidden="true">
-                    $i18n{internetAddWiFi}
-                  </div>
-                  <cr-icon-button class="icon-add-wifi"
-                      aria-labelledby="add-wifi-label"></cr-icon-button>
-                </div>
-              </template>
-              <div actionable$="[[!vpnIsProhibited_]]" class="list-item"
-                  on-click="onAddVPNTap_">
-                <div class="start settings-box-text"
-                    id="add-vpn-label" aria-hidden="true">
-                  $i18n{internetAddVPN}
-                </div>
-                <template is="dom-if" if="[[vpnIsProhibited_]]">
-                  <cr-policy-indicator id="vpnPolicyIndicator"
-                      icon-aria-label="$i18n{networkVpnBuiltin}"
-                      indicator-type="devicePolicy"
-                      on-click="doNothing_">
-                  </cr-policy-indicator>
-                </template>
-                <cr-icon-button class="icon-add-circle"
-                    aria-labelledby="add-vpn-label"
-                    disabled="[[vpnIsProhibited_]]">
-                </cr-icon-button>
+  cr-toast iron-icon {
+    margin-inline-end: 16px;
+  }
+</style>
+<settings-animated-pages id="pages" section="internet"
+    focus-config="[[focusConfig_]]">
+  <div route-path="default">
+    <network-summary default-network="{{defaultNetwork}}"
+        device-states="{{deviceStates}}"
+        on-active-networks-updated="attemptDeepLink">
+    </network-summary>
+    <template is="dom-if" if="[[allowAddConnection_(globalPolicy_,
+        managedNetworkAvailable)]]">
+      <cr-expand-button
+          aria-label="$i18n{internetAddConnectionExpandA11yLabel}"
+          class="settings-box two-line"
+          expanded="{{addConnectionExpanded_}}"
+          id="expandAddConnections">
+        <span aria-hidden="true">
+          $i18n{internetAddConnection}
+        </span>
+      </cr-expand-button>
+      <template is="dom-if" if="[[addConnectionExpanded_]]">
+        <div class="list-frame vertical-list">
+          <template is="dom-if" if="[[wifiIsEnabled_(deviceStates)]]">
+            <div actionable class="list-item" on-click="onAddWiFiTap_">
+              <div class="start settings-box-text"
+                  id="add-wifi-label" aria-hidden="true">
+                $i18n{internetAddWiFi}
               </div>
-              <template is="dom-repeat" items="[[vpnProviders_]]">
-                <div actionable class="list-item"
-                    on-click="onAddThirdPartyVpnTap_">
-                  <div class="start settings-box-text">
-                    [[getAddThirdPartyVpnLabel_(item)]]
-                  </div>
-                  <cr-icon-button class="icon-external"
-                     aria-label$="[[getAddThirdPartyVpnLabel_(item)]]">
-                  </cr-icon-button>
-                </div>
-              </template>
+              <cr-icon-button class="icon-add-wifi"
+                  aria-labelledby="add-wifi-label"></cr-icon-button>
             </div>
           </template>
-        </template>
-        <template is="dom-if" if="[[!allowAddConnection_(globalPolicy_,
-            managedNetworkAvailable)]]">
-          <div class="settings-box">
-            <iron-icon class="policy" icon="cr20:domain"></iron-icon>
-            <div class="settings-box-text">
-              $i18n{internetAddConnectionNotAllowed}
+          <div actionable$="[[!vpnIsProhibited_]]" class="list-item"
+              on-click="onAddVPNTap_">
+            <div class="start settings-box-text"
+                id="add-vpn-label" aria-hidden="true">
+              $i18n{internetAddVPN}
             </div>
+            <template is="dom-if" if="[[vpnIsProhibited_]]">
+              <cr-policy-indicator id="vpnPolicyIndicator"
+                  icon-aria-label="$i18n{networkVpnBuiltin}"
+                  indicator-type="devicePolicy"
+                  on-click="doNothing_">
+              </cr-policy-indicator>
+            </template>
+            <cr-icon-button class="icon-add-circle"
+                aria-labelledby="add-vpn-label"
+                disabled="[[vpnIsProhibited_]]">
+            </cr-icon-button>
           </div>
-        </template>
-      </div>
-
-      <template is="dom-if" route-path="/networkDetail" no-search restamp>
-        <settings-subpage page-title="$i18n{internetDetailPageTitle}">
-          <template is="dom-if" if="[[isUpdatedCellularUiEnabled_]]" restamp>
-            <settings-internet-detail-menu
-                slot="subpage-title-extra"
-                device-state="[[getDeviceState_(subpageType_, deviceStates)]]">
-            </settings-internet-detail-menu>
+          <template is="dom-repeat" items="[[vpnProviders_]]">
+            <div actionable class="list-item"
+                on-click="onAddThirdPartyVpnTap_">
+              <div class="start settings-box-text">
+                [[getAddThirdPartyVpnLabel_(item)]]
+              </div>
+              <cr-icon-button class="icon-external"
+                  aria-label$="[[getAddThirdPartyVpnLabel_(item)]]">
+              </cr-icon-button>
+            </div>
           </template>
-          <settings-internet-detail-page prefs="{{prefs}}"
-              default-network="[[defaultNetwork]]"
-              global-policy="[[globalPolicy_]]"
-              managed-network-available="[[managedNetworkAvailable]]">
-          </settings-internet-detail-page>
-        </settings-subpage>
+        </div>
       </template>
+    </template>
+    <template is="dom-if" if="[[!allowAddConnection_(globalPolicy_,
+        managedNetworkAvailable)]]">
+      <div class="settings-box">
+        <iron-icon class="policy" icon="cr20:domain"></iron-icon>
+        <div class="settings-box-text">
+          $i18n{internetAddConnectionNotAllowed}
+        </div>
+      </div>
+    </template>
+  </div>
 
-      <template is="dom-if" route-path="/knownNetworks" no-search restamp>
-        <settings-subpage page-title="$i18n{internetKnownNetworksPageTitle}">
-          <settings-internet-known-networks-page
-              network-type="[[knownNetworksType_]]">
-          </settings-internet-known-networks-page>
-        </settings-subpage>
+  <template is="dom-if" route-path="/networkDetail" no-search restamp>
+    <settings-subpage page-title="$i18n{internetDetailPageTitle}">
+      <template is="dom-if" if="[[isUpdatedCellularUiEnabled_]]" restamp>
+        <settings-internet-detail-menu
+            slot="subpage-title-extra"
+            device-state="[[getDeviceState_(subpageType_, deviceStates)]]">
+        </settings-internet-detail-menu>
       </template>
-
-      <template is="dom-if" route-path="/networks" no-search restamp>
-        <settings-subpage page-title="[[getNetworksPageTitle_(subpageType_)]]"
-            show-spinner="[[showSpinner_]]"
-            spinner-title="$i18n{networkScanningLabel}">
-          <settings-internet-subpage
-              default-network="[[defaultNetwork]]"
-              device-state="[[getDeviceState_(subpageType_, deviceStates)]]"
-              tether-device-state="[[getTetherDeviceState_(deviceStates)]]"
-              global-policy="[[globalPolicy_]]"
-              vpn-providers="[[vpnProviders_]]"
-              show-spinner="{{showSpinner_}}"
-              is-connected-to-non-cellular-network="[[isConnectedToNonCellularNetwork_]]"
-              is-cellular-setup-active="[[showCellularSetupDialog_]]">
-          </settings-internet-subpage>
-        </settings-subpage>
-      </template>
-
-    </settings-animated-pages>
-
-    <template is="dom-if" if="[[showInternetConfig_]]" restamp>
-      <internet-config id="configDialog" on-close="onInternetConfigClose_">
-      </internet-config>
-    </template>
-
-    <template is="dom-if" if="[[showCellularSetupDialog_]]" restamp>
-      <os-settings-cellular-setup-dialog id="cellularSetupDialog"
-          on-close="onCloseCellularSetupDialog_"
-          page-name="[[cellularSetupDialogPageName_]]">
-      </os-settings-cellular-setup-dialog>
-    </template>
-
-    <template is="dom-if" if="[[showESimProfileRenameDialog_]]" restamp>
-      <esim-rename-dialog id="esimRenameDialog"
-          on-close="onCloseESimProfileRenameDialog_"
-          network-state="[[eSimNetworkState_]]"
-          show-cellular-disconnect-warning="[[hasActiveCellularNetwork_]]">
-      </esim-rename-dialog>
-    </template>
-
-    <template is="dom-if" if="[[showESimRemoveProfileDialog_]]" restamp>
-      <esim-remove-profile-dialog id="esimRemoveProfileDialog"
-          on-close="onCloseESimRemoveProfileDialog_"
-          on-show-error-toast="onShowErrorToast_"
-          network-state="[[eSimNetworkState_]]"
-          show-cellular-disconnect-warning="[[hasActiveCellularNetwork_]]">
-      </esim-remove-profile-dialog>
-    </template>
-
-    <template is="dom-if" if="[[showSimLockDialog_]]" restamp>
-      <sim-lock-dialogs
-          is-dialog-open="{{showSimLockDialog_}}"
-          device-state="[[getDeviceState_(subpageType_, deviceStates)]]">
-      </sim-lock-dialogs>
-    </template>
-
-    <cr-toast id="errorToast" duration="5000">
-      <iron-icon icon="cellular-setup:warning"></iron-icon>
-      <span id="errorToastMessage">[[errorToastMessage_]]</span>
-    </cr-toast>
+      <settings-internet-detail-page prefs="{{prefs}}"
+          default-network="[[defaultNetwork]]"
+          global-policy="[[globalPolicy_]]"
+          managed-network-available="[[managedNetworkAvailable]]">
+      </settings-internet-detail-page>
+    </settings-subpage>
   </template>
-  <script src="internet_page.js"></script>
-</dom-module>
+
+  <template is="dom-if" route-path="/knownNetworks" no-search restamp>
+    <settings-subpage page-title="$i18n{internetKnownNetworksPageTitle}">
+      <settings-internet-known-networks-page
+          network-type="[[knownNetworksType_]]">
+      </settings-internet-known-networks-page>
+    </settings-subpage>
+  </template>
+
+  <template is="dom-if" route-path="/networks" no-search restamp>
+    <settings-subpage page-title="[[getNetworksPageTitle_(subpageType_)]]"
+        show-spinner="[[showSpinner_]]"
+        spinner-title="$i18n{networkScanningLabel}">
+      <settings-internet-subpage
+          default-network="[[defaultNetwork]]"
+          device-state="[[getDeviceState_(subpageType_, deviceStates)]]"
+          tether-device-state="[[getTetherDeviceState_(deviceStates)]]"
+          global-policy="[[globalPolicy_]]"
+          vpn-providers="[[vpnProviders_]]"
+          show-spinner="{{showSpinner_}}"
+          is-connected-to-non-cellular-network="[[isConnectedToNonCellularNetwork_]]"
+          is-cellular-setup-active="[[showCellularSetupDialog_]]">
+      </settings-internet-subpage>
+    </settings-subpage>
+  </template>
+
+</settings-animated-pages>
+
+<template is="dom-if" if="[[showInternetConfig_]]" restamp>
+  <internet-config id="configDialog" on-close="onInternetConfigClose_">
+  </internet-config>
+</template>
+
+<template is="dom-if" if="[[showCellularSetupDialog_]]" restamp>
+  <os-settings-cellular-setup-dialog id="cellularSetupDialog"
+      on-close="onCloseCellularSetupDialog_"
+      page-name="[[cellularSetupDialogPageName_]]">
+  </os-settings-cellular-setup-dialog>
+</template>
+
+<template is="dom-if" if="[[showESimProfileRenameDialog_]]" restamp>
+  <esim-rename-dialog id="esimRenameDialog"
+      on-close="onCloseESimProfileRenameDialog_"
+      network-state="[[eSimNetworkState_]]"
+      show-cellular-disconnect-warning="[[hasActiveCellularNetwork_]]">
+  </esim-rename-dialog>
+</template>
+
+<template is="dom-if" if="[[showESimRemoveProfileDialog_]]" restamp>
+  <esim-remove-profile-dialog id="esimRemoveProfileDialog"
+      on-close="onCloseESimRemoveProfileDialog_"
+      on-show-error-toast="onShowErrorToast_"
+      network-state="[[eSimNetworkState_]]"
+      show-cellular-disconnect-warning="[[hasActiveCellularNetwork_]]">
+  </esim-remove-profile-dialog>
+</template>
+
+<template is="dom-if" if="[[showSimLockDialog_]]" restamp>
+  <sim-lock-dialogs
+      is-dialog-open="{{showSimLockDialog_}}"
+      device-state="[[getDeviceState_(subpageType_, deviceStates)]]">
+  </sim-lock-dialogs>
+</template>
+
+<cr-toast id="errorToast" duration="5000">
+  <iron-icon icon="cellular-setup:warning"></iron-icon>
+  <span id="errorToastMessage">[[errorToastMessage_]]</span>
+</cr-toast>
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 500636f5..497f6d23 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_page.js
@@ -2,7 +2,47 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function() {
+import '//resources/cr_components/chromeos/cellular_setup/cellular_setup_icons.m.js';
+import '//resources/cr_components/chromeos/network/sim_lock_dialogs.m.js';
+import '//resources/cr_elements/cr_expand_button/cr_expand_button.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_toast/cr_toast.m.js';
+import '//resources/cr_elements/icons.m.js';
+import '//resources/cr_elements/policy/cr_policy_indicator.m.js';
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../os_settings_icons_css.m.js';
+import '../../prefs/prefs.js';
+import '../../settings_page/settings_animated_pages.js';
+import '../../settings_page/settings_subpage.js';
+import '../../settings_shared_css.js';
+import './cellular_setup_dialog.js';
+import './internet_config.js';
+import './internet_detail_menu.js';
+import './internet_detail_page.js';
+import './internet_known_networks_page.js';
+import './internet_subpage.js';
+import './network_summary.js';
+import './esim_rename_dialog.js';
+import './esim_remove_profile_dialog.js';
+
+import {Button, ButtonBarState, ButtonState, CellularSetupPageName} from '//resources/cr_components/chromeos/cellular_setup/cellular_types.m.js';
+import {getESimProfile, getESimProfileProperties, getEuicc, getNonPendingESimProfiles, getNumESimProfiles, getPendingESimProfiles} from '//resources/cr_components/chromeos/cellular_setup/esim_manager_utils.m.js';
+import {getSimSlotCount, hasActiveCellularNetwork, isActiveSim, isConnectedToNonCellularNetwork} from '//resources/cr_components/chromeos/network/cellular_utils.m.js';
+import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from '//resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
+import {NetworkListenerBehavior} from '//resources/cr_components/chromeos/network/network_listener_behavior.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {assert, assertNotReached} from '//resources/js/assert.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {Route, RouteObserverBehavior, Router} from '../../router.js';
+import {DeepLinkingBehavior} from '../deep_linking_behavior.m.js';
+import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from '../metrics_recorder.m.js';
+import {routes} from '../os_route.m.js';
+
+import {InternetPageBrowserProxy, InternetPageBrowserProxyImpl} from './internet_page_browser_proxy.js';
+
 
 const mojom = chromeos.networkConfig.mojom;
 
@@ -15,13 +55,14 @@
  * settings.
  */
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'settings-internet-page',
 
   behaviors: [
     NetworkListenerBehavior,
     DeepLinkingBehavior,
     I18nBehavior,
-    settings.RouteObserverBehavior,
+    RouteObserverBehavior,
     WebUIListenerBehavior,
   ],
 
@@ -125,7 +166,7 @@
     /**
      * Page name, if defined, indicating that the next deviceStates update
      * should call attemptShowCellularSetupDialog_().
-     * @private {cellularSetup.CellularSetupPageName|null}
+     * @private {CellularSetupPageName|null}
      */
     pendingShowCellularSetupDialogAttemptPageName_: {
       type: String,
@@ -140,7 +181,7 @@
 
     /**
      * Name of cellular setup dialog page.
-     * @private {!cellularSetup.CellularSetupPageName|null}
+     * @private {!CellularSetupPageName|null}
      */
     cellularSetupDialogPageName_: String,
 
@@ -248,7 +289,7 @@
     'show-error-toast': 'onShowErrorToast_',
   },
 
-  /** @private  {?settings.InternetPageBrowserProxy} */
+  /** @private  {?InternetPageBrowserProxy} */
   browserProxy_: null,
 
   /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
@@ -256,9 +297,9 @@
 
   /** @override */
   created() {
-    this.browserProxy_ = settings.InternetPageBrowserProxyImpl.getInstance();
-    this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
-                              .getMojoServiceRemote();
+    this.browserProxy_ = InternetPageBrowserProxyImpl.getInstance();
+    this.networkConfig_ =
+        MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote();
   },
 
   /** @override */
@@ -284,7 +325,7 @@
       networkType = mojom.NetworkType.kCellular;
     }
 
-    Polymer.RenderStatus.afterNextRender(this, () => {
+    afterNextRender(this, () => {
       const networkRow = this.$$('network-summary').getNetworkRow(networkType);
       if (networkRow && networkRow.getDeviceEnabledToggle()) {
         this.showDeepLinkElement(networkRow.getDeviceEnabledToggle());
@@ -297,16 +338,16 @@
   },
 
   /**
-   * settings.RouteObserverBehavior
-   * @param {!settings.Route} route
-   * @param {!settings.Route} oldRoute
+   * RouteObserverBehavior
+   * @param {!Route} route
+   * @param {!Route} oldRoute
    * @protected
    */
   currentRouteChanged(route, oldRoute) {
-    if (route === settings.routes.INTERNET_NETWORKS) {
+    if (route === routes.INTERNET_NETWORKS) {
       // Handle direct navigation to the networks page,
       // e.g. chrome://settings/internet/networks?type=WiFi
-      const queryParams = settings.Router.getInstance().getQueryParameters();
+      const queryParams = Router.getInstance().getQueryParameters();
       const type = queryParams.get('type');
       if (type) {
         this.subpageType_ = OncMojo.getNetworkTypeFromString(type);
@@ -314,8 +355,8 @@
 
       if (!oldRoute && queryParams.get('showCellularSetup') === 'true') {
         const pageName = queryParams.get('showPsimFlow') === 'true' ?
-            cellularSetup.CellularSetupPageName.PSIM_FLOW_UI :
-            cellularSetup.CellularSetupPageName.ESIM_FLOW_UI;
+            CellularSetupPageName.PSIM_FLOW_UI :
+            CellularSetupPageName.ESIM_FLOW_UI;
         // If the page just loaded, deviceStates will not be fully initialized
         // yet. Set pendingShowCellularSetupDialogAttemptPageName_ to indicate
         // showCellularSetupDialogAttempt_() should be called next deviceStates
@@ -331,30 +372,29 @@
           !!queryParams.get('showSimLockDialog') &&
           this.subpageType_ === mojom.NetworkType.kCellular &&
           this.isUpdatedCellularUiEnabled_;
-    } else if (route === settings.routes.KNOWN_NETWORKS) {
+    } else if (route === routes.KNOWN_NETWORKS) {
       // Handle direct navigation to the known networks page,
       // e.g. chrome://settings/internet/knownNetworks?type=WiFi
-      const queryParams = settings.Router.getInstance().getQueryParameters();
+      const queryParams = Router.getInstance().getQueryParameters();
       const type = queryParams.get('type');
       if (type) {
         this.knownNetworksType_ = OncMojo.getNetworkTypeFromString(type);
       }
-    } else if (route === settings.routes.INTERNET) {
+    } else if (route === routes.INTERNET) {
       // Show deep links for the internet page.
       this.attemptDeepLink();
-    } else if (route !== settings.routes.BASIC) {
+    } else if (route !== routes.BASIC) {
       // If we are navigating to a non internet section, do not set focus.
       return;
     }
 
-    if (!settings.routes.INTERNET ||
-        !settings.routes.INTERNET.contains(oldRoute)) {
+    if (!routes.INTERNET || !routes.INTERNET.contains(oldRoute)) {
       return;
     }
 
     // Focus the subpage arrow where appropriate.
     let element;
-    if (route === settings.routes.INTERNET_NETWORKS) {
+    if (route === routes.INTERNET_NETWORKS) {
       // iron-list makes the correct timing to focus an item in the list
       // very complicated, and the item may not exist, so just focus the
       // entire list for now.
@@ -418,7 +458,7 @@
   onDeviceEnabledToggled_(event) {
     this.networkConfig_.setNetworkTypeEnabledState(
         event.detail.type, event.detail.enabled);
-    settings.recordSettingChange();
+    recordSettingChange();
   },
 
   /**
@@ -449,7 +489,7 @@
    * Opens the cellular setup dialog if pageName is PSIM_FLOW_UI, or if pageName
    * is ESIM_FLOW_UI and isConnectedToNonCellularNetwork_ is true. If
    * isConnectedToNonCellularNetwork_ is false, shows an error toast.
-   * @param {cellularSetup.CellularSetupPageName} pageName
+   * @param {CellularSetupPageName} pageName
    * @private
    */
   attemptShowCellularSetupDialog_(pageName) {
@@ -461,7 +501,7 @@
       return;
     }
 
-    if (pageName === cellularSetup.CellularSetupPageName.PSIM_FLOW_UI) {
+    if (pageName === CellularSetupPageName.PSIM_FLOW_UI) {
       this.showCellularSetupDialog_ = true;
       this.cellularSetupDialogPageName_ = pageName;
     } else {
@@ -471,7 +511,7 @@
 
   /** @private */
   async attemptShowESimSetupDialog_() {
-    const numProfiles = await cellular_setup.getNumESimProfiles();
+    const numProfiles = await getNumESimProfiles();
     if (numProfiles >= ESIM_PROFILE_LIMIT) {
       this.showErrorToast_(
           this.i18n('eSimProfileLimitReachedErrorToast', ESIM_PROFILE_LIMIT));
@@ -488,7 +528,7 @@
             return;
           }
           this.cellularSetupDialogPageName_ =
-              cellularSetup.CellularSetupPageName.ESIM_FLOW_UI;
+              CellularSetupPageName.ESIM_FLOW_UI;
         }).bind(this));
   },
 
@@ -558,8 +598,7 @@
     params.append('guid', networkState.guid);
     params.append('type', OncMojo.getNetworkTypeString(networkState.type));
     params.append('name', OncMojo.getNetworkStateDisplayName(networkState));
-    settings.Router.getInstance().navigateTo(
-        settings.routes.NETWORK_DETAIL, params);
+    Router.getInstance().navigateTo(routes.NETWORK_DETAIL, params);
   },
 
   /**
@@ -699,8 +738,7 @@
     this.knownNetworksType_ = type;
     const params = new URLSearchParams;
     params.append('type', OncMojo.getNetworkTypeString(type));
-    settings.Router.getInstance().navigateTo(
-        settings.routes.KNOWN_NETWORKS, params);
+    Router.getInstance().navigateTo(routes.KNOWN_NETWORKS, params);
   },
 
   /** @private */
@@ -726,7 +764,7 @@
   onAddThirdPartyVpnTap_(event) {
     const provider = event.model.item;
     this.browserProxy_.addThirdPartyVpn(provider.appId);
-    settings.recordSettingChange();
+    recordSettingChange();
   },
 
   /**
@@ -738,8 +776,7 @@
     const params = new URLSearchParams;
     params.append('type', OncMojo.getNetworkTypeString(type));
     this.subpageType_ = type;
-    settings.Router.getInstance().navigateTo(
-        settings.routes.INTERNET_NETWORKS, params);
+    Router.getInstance().navigateTo(routes.INTERNET_NETWORKS, params);
   },
 
   /**
@@ -825,8 +862,7 @@
       params.append('name', displayName);
       params.append('showConfigure', true.toString());
 
-      settings.Router.getInstance().navigateTo(
-          settings.routes.NETWORK_DETAIL, params);
+      Router.getInstance().navigateTo(routes.NETWORK_DETAIL, params);
       return;
     }
 
@@ -867,4 +903,3 @@
     });
   },
 });
-})();
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.js
index a5e2f7dc..f4c37f5 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.js
@@ -3,95 +3,89 @@
 // found in the LICENSE file.
 
 // clang-format off
-// #import {addSingletonGetter, addWebUIListener} from 'chrome://resources/js/cr.m.js';
+import {addSingletonGetter, addWebUIListener} from 'chrome://resources/js/cr.m.js';
 // clang-format on
 
 /** @fileoverview A helper object used for Internet page. */
-cr.define('settings', function() {
   /** @interface */
-  /* #export */ class InternetPageBrowserProxy {
-    /**
-     * Shows the account details page of a cellular network.
-     * @param {string} guid
-     */
-    showCarrierAccountDetail(guid) {}
-
-    /**
-     * Shows the Cellular activation UI.
-     * @param {string} guid
-     */
-    showCellularSetupUI(guid) {}
-
-    /**
-     * Shows configuration for external VPNs. Includes ThirdParty (extension
-     * configured) VPNs, and Arc VPNs.
-     * @param {string} guid
-     */
-    configureThirdPartyVpn(guid) {}
-
-    /**
-     * Sends an add VPN request to the external VPN provider (ThirdParty VPN
-     * extension or Arc VPN provider app).
-     * @param {string} appId
-     */
-    addThirdPartyVpn(appId) {}
-
-    /**
-     * Requests that Chrome send the list of devices whose "Google Play
-     * Services" notifications are disabled (these notifications must be enabled
-     * to utilize Instant Tethering). The names will be provided via
-     * setGmsCoreNotificationsDisabledDeviceNamesCallback().
-     */
-    requestGmsCoreNotificationsDisabledDeviceNames() {}
-
-    /**
-     * Sets the callback to be used to receive the list of devices whose "Google
-     * Play Services" notifications are disabled. |callback| is invoked with an
-     * array of the names of these devices; note that if no devices have this
-     * property, the provided list of device names is empty.
-     * @param {function(!Array<string>):void} callback
-     */
-    setGmsCoreNotificationsDisabledDeviceNamesCallback(callback) {}
-  }
+export class InternetPageBrowserProxy {
+  /**
+   * Shows the account details page of a cellular network.
+   * @param {string} guid
+   */
+  showCarrierAccountDetail(guid) {}
 
   /**
-   * @implements {settings.InternetPageBrowserProxy}
+   * Shows the Cellular activation UI.
+   * @param {string} guid
    */
-  /* #export */ class InternetPageBrowserProxyImpl {
-    /** @override */
-    showCarrierAccountDetail(guid) {
-      chrome.send('showCarrierAccountDetail', [guid]);
-    }
+  showCellularSetupUI(guid) {}
 
-    /** @override */
-    showCellularSetupUI(guid) {
-      chrome.send('showCellularSetupUI', [guid]);
-    }
+  /**
+   * Shows configuration for external VPNs. Includes ThirdParty (extension
+   * configured) VPNs, and Arc VPNs.
+   * @param {string} guid
+   */
+  configureThirdPartyVpn(guid) {}
 
-    /** @override */
-    configureThirdPartyVpn(guid) {
-      chrome.send('configureThirdPartyVpn', [guid]);
-    }
+  /**
+   * Sends an add VPN request to the external VPN provider (ThirdParty VPN
+   * extension or Arc VPN provider app).
+   * @param {string} appId
+   */
+  addThirdPartyVpn(appId) {}
 
-    /** @override */
-    addThirdPartyVpn(appId) {
-      chrome.send('addThirdPartyVpn', [appId]);
-    }
+  /**
+   * Requests that Chrome send the list of devices whose "Google Play
+   * Services" notifications are disabled (these notifications must be enabled
+   * to utilize Instant Tethering). The names will be provided via
+   * setGmsCoreNotificationsDisabledDeviceNamesCallback().
+   */
+  requestGmsCoreNotificationsDisabledDeviceNames() {}
 
-    /** @override */
-    requestGmsCoreNotificationsDisabledDeviceNames() {
-      chrome.send('requestGmsCoreNotificationsDisabledDeviceNames');
-    }
+  /**
+   * Sets the callback to be used to receive the list of devices whose "Google
+   * Play Services" notifications are disabled. |callback| is invoked with an
+   * array of the names of these devices; note that if no devices have this
+   * property, the provided list of device names is empty.
+   * @param {function(!Array<string>):void} callback
+   */
+  setGmsCoreNotificationsDisabledDeviceNamesCallback(callback) {}
+}
 
-    /** @override */
-    setGmsCoreNotificationsDisabledDeviceNamesCallback(callback) {
-      cr.addWebUIListener(
-          'sendGmsCoreNotificationsDisabledDeviceNames', callback);
-    }
+/**
+ * @implements {InternetPageBrowserProxy}
+ */
+export class InternetPageBrowserProxyImpl {
+  /** @override */
+  showCarrierAccountDetail(guid) {
+    chrome.send('showCarrierAccountDetail', [guid]);
   }
 
-  cr.addSingletonGetter(InternetPageBrowserProxyImpl);
+  /** @override */
+  showCellularSetupUI(guid) {
+    chrome.send('showCellularSetupUI', [guid]);
+  }
 
-  // #cr_define_end
-  return {InternetPageBrowserProxy, InternetPageBrowserProxyImpl};
-});
+  /** @override */
+  configureThirdPartyVpn(guid) {
+    chrome.send('configureThirdPartyVpn', [guid]);
+  }
+
+  /** @override */
+  addThirdPartyVpn(appId) {
+    chrome.send('addThirdPartyVpn', [appId]);
+  }
+
+  /** @override */
+  requestGmsCoreNotificationsDisabledDeviceNames() {
+    chrome.send('requestGmsCoreNotificationsDisabledDeviceNames');
+  }
+
+  /** @override */
+  setGmsCoreNotificationsDisabledDeviceNamesCallback(callback) {
+    addWebUIListener('sendGmsCoreNotificationsDisabledDeviceNames', callback);
+  }
+}
+
+addSingletonGetter(InternetPageBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.html
index acb8f9b..f56ed93 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.html
@@ -1,30 +1,25 @@
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="../../settings_shared_css.html">
 
-<!-- Common styles for Internet settings. -->
-<dom-module id="internet-shared">
-  <template>
-    <style include="settings-shared">
-      network-icon {
-        padding-inline-end: var(--cr-section-padding);
-      }
+<template>
+  <style include="settings-shared">
+    network-icon {
+      padding-inline-end: var(--cr-section-padding);
+    }
 
-      iron-icon.policy {
-        margin-inline-end: var(--cr-controlled-by-spacing);
-      }
+    iron-icon.policy {
+      margin-inline-end: var(--cr-controlled-by-spacing);
+    }
 
-      .indented {
-        margin-inline-start: var(--cr-section-padding);
-      }
+    .indented {
+      margin-inline-start: var(--cr-section-padding);
+    }
 
-      .stretch {
-        align-items: stretch;
-      }
+    .stretch {
+      align-items: stretch;
+    }
 
-      .title {
-        font-size: 107.69%;  /* 14px / 13px */
-        font-weight: 500;
-      }
-    </style>
-  </template>
-</dom-module>
+    .title {
+      font-size: 107.69%;  /* 14px / 13px */
+      font-weight: 500;
+    }
+  </style>
+</template>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.js
new file mode 100644
index 0000000..659d6aa
--- /dev/null
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.js
@@ -0,0 +1,7 @@
+import '//resources/cr_elements/shared_vars_css.m.js';
+import '../../settings_shared_css.js';
+const template = document.createElement('template');
+template.innerHTML = `
+<dom-module id="internet-shared" assetpath="chrome://resources/">{__html_template__}</dom-module>
+`;
+document.body.appendChild(template.content.cloneNode(true));
\ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html
index 0d400cf..a516ade 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html
@@ -1,289 +1,254 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="cr-shared-style os-settings-icons settings-shared iron-flex">
+  #networkListDiv {
+    min-height: var(--settings-row-min-height);
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_list.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html">
-<link rel="import" href="chrome://resources/cr_elements/md_select_css.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="../../chromeos/os_settings_icons_css.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../../settings_shared_css.html">
-<link rel="import" href="../deep_linking_behavior.html">
-<link rel="import" href="../localized_link/localized_link.html">
-<link rel="import" href="../metrics_recorder.html">
-<link rel="import" href="../os_route.html">
-<link rel="import" href="./cellular_networks_list.html">
-<link rel="import" href="../route_origin_behavior.html">
-<link rel="import" href="internet_page_browser_proxy.html">
-<link rel="import" href="network_always_on_vpn.html">
+  :host(:not([is-showing-vpn_])) #networkListDiv {
+    margin-top: var(--cr-section-vertical-margin);
+  }
 
-<dom-module id="settings-internet-subpage">
-  <template>
-    <style include="cr-shared-style os-settings-icons settings-shared iron-flex">
-      #networkListDiv {
-        min-height: var(--settings-row-min-height);
-      }
+  #cellularNetworkList {
+    /* No extra margin-top when displaying the cellular network list. */
+    margin-top: calc(-1*var(--cr-section-vertical-margin));
+  }
 
-      :host(:not([is-showing-vpn_])) #networkListDiv {
-        margin-top: var(--cr-section-vertical-margin);
-      }
+  /* Set padding on children instead of the container itself to ensure that
+      separator lines can fill the entire width of the page. */
+  #networkListDiv > * {
+    /* network-list is padded to the right to allow space for a ripple */
+    padding-inline-end: calc(var(--cr-section-padding) -
+        var(--cr-icon-ripple-padding));
+    padding-inline-start: var(--cr-section-padding);
+  }
 
-      #cellularNetworkList {
-        /* No extra margin-top when displaying the cellular network list. */
-        margin-top: calc(-1*var(--cr-section-vertical-margin));
-      }
+  .add-button {
+    margin-inline-end: var(--settings-control-label-spacing);
+  }
 
-      /* Set padding on children instead of the container itself to ensure that
-         separator lines can fill the entire width of the page. */
-      #networkListDiv > * {
-        /* network-list is padded to the right to allow space for a ripple */
-        padding-inline-end: calc(var(--cr-section-padding) -
-            var(--cr-icon-ripple-padding));
-        padding-inline-start: var(--cr-section-padding);
-      }
+  #onOff {
+    font-weight: 500;
+  }
 
-      .add-button {
-        margin-inline-end: var(--settings-control-label-spacing);
-      }
+  #onOff[on] {
+    color: var(--cr-toggle-color);
+  }
 
-      #onOff {
-        font-weight: 500;
-      }
+  .vpn-header {
+    margin-bottom: 8px;
+    margin-inline-end: 12px;
+    margin-inline-start: 4px;
+    margin-top: 8px;
+  }
 
-      #onOff[on] {
-        color: var(--cr-toggle-color);
-      }
+  .no-networks {
+    margin: 4px;
+  }
 
-      .vpn-header {
-        margin-bottom: 8px;
-        margin-inline-end: 12px;
-        margin-inline-start: 4px;
-        margin-top: 8px;
-      }
+  network-list {
+    flex: 1;
+  }
 
-      .no-networks {
-        margin: 4px;
-      }
+  network-always-on-vpn {
+    width: 100%;
+  }
 
-      network-list {
-        flex: 1;
-      }
+  #gmscore-notifications-container {
+    border-top: var(--cr-separator-line);
+    margin: 10px 0;
+    padding-bottom: var(--cr-section-padding);
+    padding-top: var(--cr-section-padding);
+  }
 
-      network-always-on-vpn {
-        width: 100%;
-      }
+  #gmscore-notifications-container[no-networks-text-below] {
+    border-bottom: var(--cr-separator-line);
+    margin-top: 0;
+  }
 
-      #gmscore-notifications-container {
-        border-top: var(--cr-separator-line);
-        margin: 10px 0;
-        padding-bottom: var(--cr-section-padding);
-        padding-top: var(--cr-section-padding);
-      }
+  #gmscore-notifications-device-string {
+    margin-top: 5px;
+  }
 
-      #gmscore-notifications-container[no-networks-text-below] {
-        border-bottom: var(--cr-separator-line);
-        margin-top: 0;
-      }
+  #gmscore-notifications-instructions {
+    margin: 0;
+    padding-inline-start: 15px;
+  }
 
-      #gmscore-notifications-device-string {
-        margin-top: 5px;
-      }
+  #cellularNetworkList {
+    padding-inline-end: 0;
+    padding-inline-start: 0;
+  }
+</style>
+<template is="dom-if" if="[[enableToggleIsVisible_(deviceState)]]">
+  <div class="settings-box first">
+    <div id="onOff" class="start" on$="[[deviceIsEnabled_(deviceState)]]"
+        aria-hidden="true">
+      [[getOffOnString_(deviceState,
+        '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]]
+    </div>
+    <!-- The add button in this row is only shown for WiFi networks. -->
+    <cr-icon-button class="icon-add-wifi add-button" id="addWifiButton"
+        hidden$="[[!showAddWifiButton_(deviceState, globalPolicy)]]"
+        aria-label="$i18n{internetAddWiFi}" on-click="onAddWifiButtonTap_"
+        tabindex$="[[tabindex]]"
+        deep-link-focus-id$="[[Setting.kWifiAddNetwork]]">
+    </cr-icon-button>
+    <cr-toggle id="deviceEnabledButton"
+        aria-label$="[[getToggleA11yString_(deviceState)]]"
+        checked="[[deviceIsEnabled_(deviceState)]]"
+        disabled="[[!enableToggleIsEnabled_(deviceState,
+          deviceState.inhibitReason)]]"
+        on-change="onDeviceEnabledChange_"
+        deep-link-focus-id$="[[Setting.kWifiOnOff]]
+            [[Setting.kMobileOnOff]]">
+    </cr-toggle>
+  </div>
+</template>
 
-      #gmscore-notifications-instructions {
-        margin: 0;
-        padding-inline-start: 15px;
-      }
+<template is="dom-if" if="[[knownNetworksIsVisible_(deviceState)]]">
+  <cr-link-row
+      id="knownNetworksSubpageButton"
+      class="hr"
+      label="$i18n{knownNetworksButton}"
+      on-click="onKnownNetworksTap_"
+      role-description="$i18n{subpageArrowRoleDescription}">
+  </cr-link-row>
+</template>
 
-      #cellularNetworkList {
-        padding-inline-end: 0;
-        padding-inline-start: 0;
-      }
-    </style>
-    <template is="dom-if" if="[[enableToggleIsVisible_(deviceState)]]">
-      <div class="settings-box first">
-        <div id="onOff" class="start" on$="[[deviceIsEnabled_(deviceState)]]"
-            aria-hidden="true">
-          [[getOffOnString_(deviceState,
-            '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]]
-        </div>
-        <!-- The add button in this row is only shown for WiFi networks. -->
-        <cr-icon-button class="icon-add-wifi add-button" id="addWifiButton"
-            hidden$="[[!showAddWifiButton_(deviceState, globalPolicy)]]"
-            aria-label="$i18n{internetAddWiFi}" on-click="onAddWifiButtonTap_"
-            tabindex$="[[tabindex]]"
-            deep-link-focus-id$="[[Setting.kWifiAddNetwork]]">
+<template is="dom-if" if="[[deviceIsEnabled_(deviceState)]]">
+  <div id="networkListDiv" class="layout vertical flex">
+    <!-- VPN only header for built-in VPNs. -->
+    <template is="dom-if" if="[[isShowingVpn_]]">
+      <div class="vpn-header layout horizontal center">
+        <div class="flex settings-box-text">$i18n{networkVpnBuiltin}</div>
+        <template is="dom-if" if="[[!vpnIsEnabled_]]">
+          <cr-policy-indicator indicator-type="devicePolicy">
+          </cr-policy-indicator>
+        </template>
+        <cr-icon-button class="icon-add-circle"
+            disabled="[[!vpnIsEnabled_]]"
+            aria-label="$i18n{internetAddVPN}"
+            on-click="onAddVpnButtonTap_"
+            tabindex$="[[tabindex]]">
         </cr-icon-button>
-        <cr-toggle id="deviceEnabledButton"
-            aria-label$="[[getToggleA11yString_(deviceState)]]"
-            checked="[[deviceIsEnabled_(deviceState)]]"
-            disabled="[[!enableToggleIsEnabled_(deviceState,
-              deviceState.inhibitReason)]]"
-            on-change="onDeviceEnabledChange_"
-            deep-link-focus-id$="[[Setting.kWifiOnOff]]
-                [[Setting.kMobileOnOff]]">
-        </cr-toggle>
       </div>
     </template>
 
-    <template is="dom-if" if="[[knownNetworksIsVisible_(deviceState)]]">
-      <cr-link-row
-          id="knownNetworksSubpageButton"
-          class="hr"
-          label="$i18n{knownNetworksButton}"
-          on-click="onKnownNetworksTap_"
-          role-description="$i18n{subpageArrowRoleDescription}">
-      </cr-link-row>
+    <!-- List of networks (empty if no networks exist). -->
+    <template is="dom-if"
+        if="[[shouldShowNetworkList_(networkStateList_, deviceState)]]">
+      <network-list id="networkList" show-buttons
+          show-technology-badge="[[showTechnologyBadge_]]"
+          networks="[[networkStateList_]]"
+          on-selected="onNetworkSelected_"
+          device-state="[[deviceState]]">
+      </network-list>
     </template>
 
-    <template is="dom-if" if="[[deviceIsEnabled_(deviceState)]]">
-      <div id="networkListDiv" class="layout vertical flex">
-        <!-- VPN only header for built-in VPNs. -->
-        <template is="dom-if" if="[[isShowingVpn_]]">
-          <div class="vpn-header layout horizontal center">
-            <div class="flex settings-box-text">$i18n{networkVpnBuiltin}</div>
-            <template is="dom-if" if="[[!vpnIsEnabled_]]">
-              <cr-policy-indicator indicator-type="devicePolicy">
-              </cr-policy-indicator>
-            </template>
-            <cr-icon-button class="icon-add-circle"
-                disabled="[[!vpnIsEnabled_]]"
-                aria-label="$i18n{internetAddVPN}"
-                on-click="onAddVpnButtonTap_"
-                tabindex$="[[tabindex]]">
-            </cr-icon-button>
-          </div>
-        </template>
+    <!-- List of cellular and instant tethering networks -->
+    <template is="dom-if"
+        if="[[shouldShowCellularNetworkList_(networkStateList_,
+                                              deviceState)]]">
+      <cellular-networks-list id="cellularNetworkList"
+          networks="[[networkStateList_]]"
+          show-technology-badge="[[showTechnologyBadge_]]"
+          on-selected="onNetworkSelected_"
+          cellular-device-state="[[deviceState]]"
+          tether-device-state="[[tetherDeviceState]]"
+          global-policy="[[globalPolicy]]"
+          is-connected-to-non-cellular-network="[[isConnectedToNonCellularNetwork]]"
+          can-show-spinner="[[!isCellularSetupActive]]">
+      </cellular-networks-list>
+    </template>
 
-        <!-- List of networks (empty if no networks exist). -->
-        <template is="dom-if"
-            if="[[shouldShowNetworkList_(networkStateList_, deviceState)]]">
-          <network-list id="networkList" show-buttons
-              show-technology-badge="[[showTechnologyBadge_]]"
-              networks="[[networkStateList_]]"
-              on-selected="onNetworkSelected_"
-              device-state="[[deviceState]]">
-          </network-list>
-        </template>
-
-        <!-- List of cellular and instant tethering networks -->
-        <template is="dom-if"
-            if="[[shouldShowCellularNetworkList_(networkStateList_,
-                                                 deviceState)]]">
-          <cellular-networks-list id="cellularNetworkList"
-              networks="[[networkStateList_]]"
-              show-technology-badge="[[showTechnologyBadge_]]"
-              on-selected="onNetworkSelected_"
-              cellular-device-state="[[deviceState]]"
-              tether-device-state="[[tetherDeviceState]]"
-              global-policy="[[globalPolicy]]"
-              is-connected-to-non-cellular-network="[[isConnectedToNonCellularNetwork]]"
-              can-show-spinner="[[!isCellularSetupActive]]">
-          </cellular-networks-list>
-        </template>
-
-        <!-- Instructions for how to enable "Google Play Services" notifications
-            (needed for Instant Tethering). -->
-        <template is="dom-if" if="[[showGmsCoreNotificationsSection_(
-            notificationsDisabledDeviceNames_)]]">
-          <div id="gmscore-notifications-container"
-              no-networks-text-below$="[[!networkStateList_.length]]">
-            <div>$i18n{gmscoreNotificationsTitle}</div>
-            <div id="gmscore-notifications-device-string"
-                class="cr-secondary-text">
-              [[getGmsCoreNotificationsDevicesString_(
-                  notificationsDisabledDeviceNames_)]]
-            </div>
-            <ol id="gmscore-notifications-instructions"
-                class="cr-secondary-text">
-              <li>$i18n{gmscoreNotificationsFirstStep}</li>
-              <li>$i18n{gmscoreNotificationsSecondStep}</li>
-              <li>$i18n{gmscoreNotificationsThirdStep}</li>
-              <li>$i18n{gmscoreNotificationsFourthStep}</li>
-            </ol>
-          </div>
-        </template>
-
-        <!-- Text shown if no networks exist. -->
-        <settings-localized-link
-            class="no-networks"
-            hidden="[[hideNoNetworksMessage_(networkStateList_, deviceState)]]"
-            localized-string=
-                "[[getNoNetworksInnerHtml_(deviceState, tetherDeviceState)]]">
-        </settings-localized-link>
-
-        <template is="dom-if" if="[[isShowingVpn_]]">
-          <!-- Third party VPNs. -->
-          <template is="dom-repeat"
-              items="[[getVpnProviders_(vpnProviders, thirdPartyVpns_)]]">
-            <div id="[[item.providerName]]"
-                class="vpn-header layout horizontal center">
-              <div class="flex settings-box-text">[[item.providerName]]</div>
-              <cr-icon-button class="icon-add-circle"
-                  aria-label$="[[getAddThirdPartyVpnA11yString_(item)]]"
-                  on-click="onAddThirdPartyVpnTap_" tabindex$="[[tabindex]]">
-              </cr-icon-button>
-            </div>
-            <network-list show-buttons
-                hidden$="[[!haveThirdPartyVpnNetwork_(thirdPartyVpns_, item)]]"
-                networks="[[getThirdPartyVpnNetworks_(thirdPartyVpns_, item)]]"
-                on-selected="onNetworkSelected_">
-            </network-list>
-            <div hidden$="[[haveThirdPartyVpnNetwork_(thirdPartyVpns_, item)]]"
-                class="no-networks settings-box-text">
-              $i18n{internetNoNetworks}
-            </div>
-          </template>
-        </template>
+    <!-- Instructions for how to enable "Google Play Services" notifications
+        (needed for Instant Tethering). -->
+    <template is="dom-if" if="[[showGmsCoreNotificationsSection_(
+        notificationsDisabledDeviceNames_)]]">
+      <div id="gmscore-notifications-container"
+          no-networks-text-below$="[[!networkStateList_.length]]">
+        <div>$i18n{gmscoreNotificationsTitle}</div>
+        <div id="gmscore-notifications-device-string"
+            class="cr-secondary-text">
+          [[getGmsCoreNotificationsDevicesString_(
+              notificationsDisabledDeviceNames_)]]
+        </div>
+        <ol id="gmscore-notifications-instructions"
+            class="cr-secondary-text">
+          <li>$i18n{gmscoreNotificationsFirstStep}</li>
+          <li>$i18n{gmscoreNotificationsSecondStep}</li>
+          <li>$i18n{gmscoreNotificationsThirdStep}</li>
+          <li>$i18n{gmscoreNotificationsFourthStep}</li>
+        </ol>
       </div>
+    </template>
 
-      <template is="dom-if"
-          if="[[shouldShowVpnPreferences_(isManaged_, isShowingVpn_)]]">
-        <div class="settings-box first">
-          <h2>$i18n{networkVpnPreferences}</h2>
-        </div>
-        <div class="settings-box first">
-          <network-always-on-vpn id="alwaysOnVpnSelector"
-              networks="[[getAlwaysOnVpnNetworks_(deviceState,
-                networkStateList_, thirdPartyVpns_)]]"
-              mode="{{alwaysOnVpnMode_}}"
-              service="{{alwaysOnVpnService_}}">
-          </network-always-on-vpn>
-        </div>
-      </template>
+    <!-- Text shown if no networks exist. -->
+    <settings-localized-link
+        class="no-networks"
+        hidden="[[hideNoNetworksMessage_(networkStateList_, deviceState)]]"
+        localized-string=
+            "[[getNoNetworksInnerHtml_(deviceState, tetherDeviceState)]]">
+    </settings-localized-link>
 
-      <template is="dom-if"
-          if="[[tetherToggleIsVisible_(deviceState, tetherDeviceState)]]">
-        <div class="settings-box two-line" actionable
-            on-click="onTetherEnabledChange_">
-          <div class="start settings-box-text">
-            $i18n{internetToggleTetherLabel}
-            <div id="tetherSecondary" class="secondary">
-              $i18n{internetToggleTetherSubtext}
-            </div>
-          </div>
-          <cr-toggle id="tetherEnabledButton"
-              aria-label="$i18n{internetToggleTetherLabel}"
-              aria-describedby="tetherSecondary"
-              checked="[[deviceIsEnabled_(tetherDeviceState)]]"
-              disabled="[[!tetherToggleIsEnabled_(deviceState,
-                         tetherDeviceState)]]"
-              on-change="onTetherEnabledChange_">
-          </cr-toggle>
+    <template is="dom-if" if="[[isShowingVpn_]]">
+      <!-- Third party VPNs. -->
+      <template is="dom-repeat"
+          items="[[getVpnProviders_(vpnProviders, thirdPartyVpns_)]]">
+        <div id="[[item.providerName]]"
+            class="vpn-header layout horizontal center">
+          <div class="flex settings-box-text">[[item.providerName]]</div>
+          <cr-icon-button class="icon-add-circle"
+              aria-label$="[[getAddThirdPartyVpnA11yString_(item)]]"
+              on-click="onAddThirdPartyVpnTap_" tabindex$="[[tabindex]]">
+          </cr-icon-button>
+        </div>
+        <network-list show-buttons
+            hidden$="[[!haveThirdPartyVpnNetwork_(thirdPartyVpns_, item)]]"
+            networks="[[getThirdPartyVpnNetworks_(thirdPartyVpns_, item)]]"
+            on-selected="onNetworkSelected_">
+        </network-list>
+        <div hidden$="[[haveThirdPartyVpnNetwork_(thirdPartyVpns_, item)]]"
+            class="no-networks settings-box-text">
+          $i18n{internetNoNetworks}
         </div>
       </template>
     </template>
+  </div>
 
+  <template is="dom-if"
+      if="[[shouldShowVpnPreferences_(isManaged_, isShowingVpn_)]]">
+    <div class="settings-box first">
+      <h2>$i18n{networkVpnPreferences}</h2>
+    </div>
+    <div class="settings-box first">
+      <network-always-on-vpn id="alwaysOnVpnSelector"
+          networks="[[getAlwaysOnVpnNetworks_(deviceState,
+            networkStateList_, thirdPartyVpns_)]]"
+          mode="{{alwaysOnVpnMode_}}"
+          service="{{alwaysOnVpnService_}}">
+      </network-always-on-vpn>
+    </div>
   </template>
-  <script src="internet_subpage.js"></script>
-</dom-module>
+
+  <template is="dom-if"
+      if="[[tetherToggleIsVisible_(deviceState, tetherDeviceState)]]">
+    <div class="settings-box two-line" actionable
+        on-click="onTetherEnabledChange_">
+      <div class="start settings-box-text">
+        $i18n{internetToggleTetherLabel}
+        <div id="tetherSecondary" class="secondary">
+          $i18n{internetToggleTetherSubtext}
+        </div>
+      </div>
+      <cr-toggle id="tetherEnabledButton"
+          aria-label="$i18n{internetToggleTetherLabel}"
+          aria-describedby="tetherSecondary"
+          checked="[[deviceIsEnabled_(tetherDeviceState)]]"
+          disabled="[[!tetherToggleIsEnabled_(deviceState,
+                      tetherDeviceState)]]"
+          on-change="onTetherEnabledChange_">
+      </cr-toggle>
+    </div>
+  </template>
+</template>
+
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 db3d40c..33ed049 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js
@@ -7,19 +7,51 @@
  * Cellular, or virtual networks.
  */
 
-(function() {
+import '//resources/cr_components/chromeos/network/network_list.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_link_row/cr_link_row.js';
+import '//resources/cr_elements/cr_toggle/cr_toggle.m.js';
+import '//resources/cr_elements/policy/cr_policy_indicator.m.js';
+import '//resources/cr_elements/md_select_css.m.js';
+import '//resources/cr_elements/shared_style_css.m.js';
+import '//resources/cr_elements/shared_vars_css.m.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../os_settings_icons_css.m.js';
+import '../../settings_shared_css.js';
+import '../localized_link/localized_link.js';
+import './cellular_networks_list.js';
+import './network_always_on_vpn.js';
+
+import {CrPolicyNetworkBehaviorMojo} from '//resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.m.js';
+import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from '//resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
+import {NetworkListenerBehavior} from '//resources/cr_components/chromeos/network/network_listener_behavior.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {assert, assertNotReached} from '//resources/js/assert.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {Route, RouteObserverBehavior, Router} from '../../router.js';
+import {DeepLinkingBehavior} from '../deep_linking_behavior.m.js';
+import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from '../metrics_recorder.m.js';
+import {routes} from '../os_route.m.js';
+import {RouteOriginBehavior, RouteOriginBehaviorImpl} from '../route_origin_behavior.m.js';
+
+import {InternetPageBrowserProxy, InternetPageBrowserProxyImpl} from './internet_page_browser_proxy.js';
+
 
 const mojom = chromeos.networkConfig.mojom;
 
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'settings-internet-subpage',
 
   behaviors: [
     NetworkListenerBehavior,
     CrPolicyNetworkBehaviorMojo,
     DeepLinkingBehavior,
-    settings.RouteObserverBehavior,
-    settings.RouteOriginBehavior,
+    RouteObserverBehavior,
+    RouteOriginBehavior,
     I18nBehavior,
   ],
 
@@ -195,8 +227,8 @@
     },
   },
 
-  /** settings.RouteOriginBehavior override */
-  route_: settings.routes.INTERNET_NETWORKS,
+  /** RouteOriginBehavior override */
+  route_: routes.INTERNET_NETWORKS,
 
   observers: [
     'deviceStateChanged_(deviceState)',
@@ -206,7 +238,7 @@
   /** @private {number|null} */
   scanIntervalId_: null,
 
-  /** @private  {settings.InternetPageBrowserProxy} */
+  /** @private  {InternetPageBrowserProxy} */
   browserProxy_: null,
 
   /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */
@@ -214,9 +246,9 @@
 
   /** @override */
   created() {
-    this.browserProxy_ = settings.InternetPageBrowserProxyImpl.getInstance();
-    this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
-                              .getMojoServiceRemote();
+    this.browserProxy_ = InternetPageBrowserProxyImpl.getInstance();
+    this.networkConfig_ =
+        MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote();
   },
 
   /** @override */
@@ -225,8 +257,7 @@
         this.onNotificationsDisabledDeviceNamesReceived_.bind(this));
     this.browserProxy_.requestGmsCoreNotificationsDisabledDeviceNames();
 
-    this.addFocusConfig_(
-        settings.routes.KNOWN_NETWORKS, '#knownNetworksSubpageButton');
+    this.addFocusConfig_(routes.KNOWN_NETWORKS, '#knownNetworksSubpageButton');
   },
 
   /** override */
@@ -241,7 +272,7 @@
    */
   beforeDeepLinkAttempt(settingId) {
     if (settingId === chromeos.settings.mojom.Setting.kAddESimNetwork) {
-      Polymer.RenderStatus.afterNextRender(this, () => {
+      afterNextRender(this, () => {
         const deepLinkElement =
             this.$$('cellular-networks-list').getAddEsimButton();
         if (!deepLinkElement || deepLinkElement.hidden) {
@@ -255,7 +286,7 @@
 
     if (settingId === chromeos.settings.mojom.Setting.kInstantTetheringOnOff) {
       // Wait for element to load.
-      Polymer.RenderStatus.afterNextRender(this, () => {
+      afterNextRender(this, () => {
         // If both Cellular and Instant Tethering are enabled, we show a special
         // toggle for Instant Tethering. If it exists, deep link to it.
         const tetherEnabled = this.$$('#tetherEnabledButton');
@@ -279,19 +310,18 @@
   },
 
   /**
-   * settings.RouteObserverBehavior
-   * @param {!settings.Route} newRoute
-   * @param {!settings.Route} oldRoute
+   * RouteObserverBehavior
+   * @param {!Route} newRoute
+   * @param {!Route} oldRoute
    * @protected
    */
   currentRouteChanged(newRoute, oldRoute) {
-    if (newRoute !== settings.routes.INTERNET_NETWORKS) {
+    if (newRoute !== routes.INTERNET_NETWORKS) {
       this.stopScanning_();
       return;
     }
     this.init();
-    settings.RouteOriginBehaviorImpl.currentRouteChanged.call(
-        this, newRoute, oldRoute);
+    RouteOriginBehaviorImpl.currentRouteChanged.call(this, newRoute, oldRoute);
 
     this.attemptDeepLink().then(result => {
       if (!result.deepLinkShown && result.pendingSettingId) {
@@ -364,8 +394,7 @@
     }
 
     // Scans should only be triggered by the "networks" subpage.
-    if (settings.Router.getInstance().getCurrentRoute() !==
-        settings.routes.INTERNET_NETWORKS) {
+    if (Router.getInstance().getCurrentRoute() !== routes.INTERNET_NETWORKS) {
       this.stopScanning_();
       return;
     }
@@ -708,7 +737,7 @@
   onAddThirdPartyVpnTap_(event) {
     const provider = event.model.item;
     this.browserProxy_.addThirdPartyVpn(provider.appId);
-    settings.recordSettingChange();
+    recordSettingChange();
   },
 
   /**
@@ -775,7 +804,7 @@
     e.target.blur();
     if (this.canAttemptConnection_(networkState)) {
       this.fire('network-connect', {networkState: networkState});
-      settings.recordSettingChange();
+      recordSettingChange();
       return;
     }
     this.fire('show-detail', networkState);
@@ -1085,4 +1114,3 @@
     this.networkConfig_.setAlwaysOnVpn(properties);
   },
 });
-})();
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.html b/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.html
index ecb00db..cc80b479 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.html
@@ -1,75 +1,63 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
-<link rel="import" href="chrome://resources/cr_elements/md_select_css.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_shared_css.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-
-<dom-module id="network-always-on-vpn">
-  <template>
-    <style include="settings-shared network-shared md-select">
-      #lockdown {
-        border-top: var(--cr-separator-line);
-      }
-    </style>
-    <!-- Always-on VPN enable/disable toggle -->
-    <div class="property-box">
-      <div class="start text-area" aria-hidden="true">
-        <div class="label" id="alwaysOnVpnEnableLabel">
-          $i18n{networkAlwaysOnVpnEnableLabel}
-        </div>
-        <div class="secondary" id="alwaysOnVpnEnableSublabel">
-          $i18n{networkAlwaysOnVpnEnableSublabel}
-        </div>
-      </div>
-      <cr-toggle id="alwaysOnVpnEnableToggle"
-          disabled="[[shouldDisableAlwaysOnVpn_(networks)]]"
-          checked="[[computeAlwaysOnVpnEnabled_(mode, networks)]]"
-          on-change="onAlwaysOnEnableChanged_"
-          aria-labelledby="alwaysOnVpnEnableLabel"
-          aria-describedby="alwaysOnVpnEnableSublabel">
-      </cr-toggle>
+<style include="settings-shared network-shared md-select">
+  #lockdown {
+    border-top: var(--cr-separator-line);
+  }
+</style>
+<!-- Always-on VPN enable/disable toggle -->
+<div class="property-box">
+  <div class="start text-area" aria-hidden="true">
+    <div class="label" id="alwaysOnVpnEnableLabel">
+      $i18n{networkAlwaysOnVpnEnableLabel}
     </div>
-    <!-- Always-on VPN options -->
-    <template is="dom-if" if="[[shouldShowAlwaysOnVpnOptions_(
-            mode, networks)]]">
-      <!-- Service selector -->
-      <div class="property-box indented two-line">
-        <div class="start text-area" aria-hidden="true">
-          <div class="label" id="alwaysOnVpnServiceLabel">
-            $i18n{networkAlwaysOnVpnService}
-          </div>
-        </div>
-        <select id="alwaysOnVpnServiceSelect"
-            class="md-select"
-            on-change="onAlwaysOnVpnServiceChanged_"
-            aria-labelledby="alwaysOnVpnServiceLabel">
-          <template is="dom-repeat" items="[[getAlwaysOnVpnListOptions_(
-                    service, networks)]]">
-            <option value="[[item.value]]" selected="[[item.selected]]">
-              [[item.name]]
-            </option>
-          </template>
-        </select>
+    <div class="secondary" id="alwaysOnVpnEnableSublabel">
+      $i18n{networkAlwaysOnVpnEnableSublabel}
+    </div>
+  </div>
+  <cr-toggle id="alwaysOnVpnEnableToggle"
+      disabled="[[shouldDisableAlwaysOnVpn_(networks)]]"
+      checked="[[computeAlwaysOnVpnEnabled_(mode, networks)]]"
+      on-change="onAlwaysOnEnableChanged_"
+      aria-labelledby="alwaysOnVpnEnableLabel"
+      aria-describedby="alwaysOnVpnEnableSublabel">
+  </cr-toggle>
+</div>
+<!-- Always-on VPN options -->
+<template is="dom-if" if="[[shouldShowAlwaysOnVpnOptions_(
+        mode, networks)]]">
+  <!-- Service selector -->
+  <div class="property-box indented two-line">
+    <div class="start text-area" aria-hidden="true">
+      <div class="label" id="alwaysOnVpnServiceLabel">
+        $i18n{networkAlwaysOnVpnService}
       </div>
-      <!-- Lockdown toggle -->
-      <div id="lockdown" class="property-box indented two-line">
-        <div class="start text-area" aria-hidden="true">
-          <div class="label" id="alwaysOnVpnLockdownLabel">
-            $i18n{networkAlwaysOnVpnLockdownLabel}
-          </div>
-          <div class="secondary" id="alwaysOnVpnLockdownSublabel">
-            $i18n{networkAlwaysOnVpnLockdownSublabel}
-          </div>
-        </div>
-        <cr-toggle id="alwaysOnVpnLockdownToggle"
-            checked="[[computeAlwaysOnVpnLockdown_(mode)]]"
-            on-change="onAlwaysOnVpnLockdownChanged_"
-            aria-labelledby="alwaysOnVpnLockdownLabel"
-            aria-describedby="alwaysOnVpnLockdownSublabel">
-        </cr-toggle>
+    </div>
+    <select id="alwaysOnVpnServiceSelect"
+        class="md-select"
+        on-change="onAlwaysOnVpnServiceChanged_"
+        aria-labelledby="alwaysOnVpnServiceLabel">
+      <template is="dom-repeat" items="[[getAlwaysOnVpnListOptions_(
+                service, networks)]]">
+        <option value="[[item.value]]" selected="[[item.selected]]">
+          [[item.name]]
+        </option>
+      </template>
+    </select>
+  </div>
+  <!-- Lockdown toggle -->
+  <div id="lockdown" class="property-box indented two-line">
+    <div class="start text-area" aria-hidden="true">
+      <div class="label" id="alwaysOnVpnLockdownLabel">
+        $i18n{networkAlwaysOnVpnLockdownLabel}
       </div>
-    </template>
-  </template>
-  <script src="network_always_on_vpn.js"></script>
-</dom-module>
+      <div class="secondary" id="alwaysOnVpnLockdownSublabel">
+        $i18n{networkAlwaysOnVpnLockdownSublabel}
+      </div>
+    </div>
+    <cr-toggle id="alwaysOnVpnLockdownToggle"
+        checked="[[computeAlwaysOnVpnLockdown_(mode)]]"
+        on-change="onAlwaysOnVpnLockdownChanged_"
+        aria-labelledby="alwaysOnVpnLockdownLabel"
+        aria-describedby="alwaysOnVpnLockdownSublabel">
+    </cr-toggle>
+  </div>
+</template>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.js b/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.js
index 83763620..3a75aa9 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.js
@@ -6,11 +6,18 @@
  * @fileoverview Polymer element for displaying and modifying always-on VPN
  * settings.
  */
-(function() {
+import '//resources/cr_elements/cr_toggle/cr_toggle.m.js';
+import '//resources/cr_elements/md_select_css.m.js';
+import '//resources/cr_components/chromeos/network/network_shared_css.m.js';
+
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
 
 const mojom = chromeos.networkConfig.mojom;
 
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'network-always-on-vpn',
 
   behaviors: [I18nBehavior],
@@ -162,4 +169,3 @@
   },
 
 });
-})();
\ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.html b/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.html
index 2a09bd78..6f9b6fb9 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.html
@@ -1,101 +1,78 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="internet-shared cr-hidden-style iron-flex
+    iron-flex-alignment">
+  cr-policy-network-indicator-mojo {
+    margin-inline-end: 10px;
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cr_policy_network_indicator_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_proxy.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
-<link rel="import" href="../../controls/extension_controlled_indicator.html">
-<link rel="import" href="../../controls/settings_toggle_button.html">
-<link rel="import" href="../../prefs/prefs_behavior.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../../settings_vars_css.html">
-<link rel="import" href="../os_route.html">
-<link rel="import" href="internet_shared_css.html">
+  extension-controlled-indicator {
+    margin-inline-start: 0;
+    width: 100%;
+  }
 
-<dom-module id="network-proxy-section">
-  <template>
-    <style include="internet-shared cr-hidden-style iron-flex
-        iron-flex-alignment">
-      cr-policy-network-indicator-mojo {
-        margin-inline-end: 10px;
-      }
+  .settings-box:first-of-type {
+    border-top: none;
+  }
+</style>
 
-      extension-controlled-indicator {
-        margin-inline-start: 0;
-        width: 100%;
-      }
-
-      .settings-box:first-of-type {
-        border-top: none;
-      }
-    </style>
-
-    <!-- Policy indicator. Only one dom-if below will be shown. -->
-    <template is="dom-if"
-        if="[[shouldShowNetworkPolicyIndicator_(managedProperties)]]">
-      <div class="settings-box">
-        <div class="layout horizontal center">
-          <cr-policy-network-indicator-mojo
-              property="[[managedProperties.proxySettings.type]]"
-              no-extension-indicator>
-          </cr-policy-network-indicator-mojo>
-          <div>$i18n{networkProxyEnforcedPolicy}</div>
-        </div>
-      </div>
-    </template>
-    <template is="dom-if"
-        if="[[shouldShowExtensionIndicator_(managedProperties)]]">
-      <div class="settings-box">
-        <extension-controlled-indicator
-            extension-id="[[prefs.proxy.extensionId]]"
-            extension-name="[[prefs.proxy.controlledByName]]"
-            extension-can-be-disabled="[[prefs.proxy.extensionCanBeDisabled]]">
-        </extension-controlled-indicator>
-      </div>
-    </template>
-
-    <!-- Allow shared proxies -->
-    <settings-toggle-button id="allowShared" class="indented"
-        hidden$="[[!shouldShowAllowShared_(managedProperties.source)]]"
-        pref="{{prefs.settings.use_shared_proxies}}"
-        label="$i18n{networkProxyAllowShared}"
-        on-settings-boolean-control-change="onAllowSharedProxiesChange_"
-        no-set-pref
-        disabled="[[disabled]]">
-    </settings-toggle-button>
-
-    <div class="settings-box single-column stretch continuation indented">
-      <network-proxy editable="[[!disabled]]"
-          managed-properties="[[managedProperties]]"
-          use-shared-proxies="[[useSharedProxies_]]">
-      </network-proxy>
+<!-- Policy indicator. Only one dom-if below will be shown. -->
+<template is="dom-if"
+    if="[[shouldShowNetworkPolicyIndicator_(managedProperties)]]">
+  <div class="settings-box">
+    <div class="layout horizontal center">
+      <cr-policy-network-indicator-mojo
+          property="[[managedProperties.proxySettings.type]]"
+          no-extension-indicator>
+      </cr-policy-network-indicator-mojo>
+      <div>$i18n{networkProxyEnforcedPolicy}</div>
     </div>
+  </div>
+</template>
+<template is="dom-if"
+    if="[[shouldShowExtensionIndicator_(managedProperties)]]">
+  <div class="settings-box">
+    <extension-controlled-indicator
+        extension-id="[[prefs.proxy.extensionId]]"
+        extension-name="[[prefs.proxy.controlledByName]]"
+        extension-can-be-disabled="[[prefs.proxy.extensionCanBeDisabled]]">
+    </extension-controlled-indicator>
+  </div>
+</template>
 
-    <!-- Confirm Allow shared proxies dialog -->
-    <cr-dialog id="confirmAllowSharedDialog"
-        close-text="$i18n{close}" on-cancel="onAllowSharedDialogCancel_"
-        on-close="onAllowSharedDialogClose_">
-      <div slot="title">
-        [[getAllowSharedDialogTitle_(prefs.settings.use_shared_proxies.value)]]
-      </div>
-      <div slot="body">
-        $i18n{networkProxyAllowSharedWarningMessage}
-      </div>
-      <div slot="button-container">
-        <cr-button class="cancel-button"
-            on-click="onAllowSharedDialogCancel_">
-          $i18n{cancel}
-        </cr-button>
-        <cr-button class="action-button"
-            on-click="onAllowSharedDialogConfirm_">
-          $i18n{confirm}
-        </cr-button>
-      </div>
-    </cr-dialog>
-  </template>
-  <script src="network_proxy_section.js"></script>
-</dom-module>
+<!-- Allow shared proxies -->
+<settings-toggle-button id="allowShared" class="indented"
+    hidden$="[[!shouldShowAllowShared_(managedProperties.source)]]"
+    pref="{{prefs.settings.use_shared_proxies}}"
+    label="$i18n{networkProxyAllowShared}"
+    on-settings-boolean-control-change="onAllowSharedProxiesChange_"
+    no-set-pref
+    disabled="[[disabled]]">
+</settings-toggle-button>
+
+<div class="settings-box single-column stretch continuation indented">
+  <network-proxy editable="[[!disabled]]"
+      managed-properties="[[managedProperties]]"
+      use-shared-proxies="[[useSharedProxies_]]">
+  </network-proxy>
+</div>
+
+<!-- Confirm Allow shared proxies dialog -->
+<cr-dialog id="confirmAllowSharedDialog"
+    close-text="$i18n{close}" on-cancel="onAllowSharedDialogCancel_"
+    on-close="onAllowSharedDialogClose_">
+  <div slot="title">
+    [[getAllowSharedDialogTitle_(prefs.settings.use_shared_proxies.value)]]
+  </div>
+  <div slot="body">
+    $i18n{networkProxyAllowSharedWarningMessage}
+  </div>
+  <div slot="button-container">
+    <cr-button class="cancel-button"
+        on-click="onAllowSharedDialogCancel_">
+      $i18n{cancel}
+    </cr-button>
+    <cr-button class="action-button"
+        on-click="onAllowSharedDialogConfirm_">
+      $i18n{confirm}
+    </cr-button>
+  </div>
+</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.js b/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.js
index 5d9a96dd..1e92388 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.js
@@ -8,14 +8,34 @@
  * shared networks'.
  */
 
+import '//resources/cr_components/chromeos/network/cr_policy_network_indicator_mojo.m.js';
+import '//resources/cr_components/chromeos/network/network_proxy.m.js';
+import '//resources/cr_elements/cr_button/cr_button.m.js';
+import '//resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import '//resources/cr_elements/hidden_style_css.m.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import '../../controls/extension_controlled_indicator.js';
+import '../../settings_vars_css.js';
+import './internet_shared_css.js';
+
+import {CrPolicyNetworkBehaviorMojo} from '//resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {SettingsToggleButtonElement} from '../../controls/settings_toggle_button.js';
+import {PrefsBehavior} from '../../prefs/prefs_behavior.js';
+import {Route, RouteObserverBehavior, Router} from '../../router.js';
+import {routes} from '../os_route.m.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'network-proxy-section',
 
   behaviors: [
     CrPolicyNetworkBehaviorMojo,
     I18nBehavior,
     PrefsBehavior,
-    settings.RouteObserverBehavior,
+    RouteObserverBehavior,
   ],
 
   properties: {
@@ -46,9 +66,9 @@
     return /** @type {?CrToggleElement} */ (this.$$('#allowShared'));
   },
 
-  /** @protected settings.RouteObserverBehavior */
+  /** @protected RouteObserverBehavior */
   currentRouteChanged(newRoute) {
-    if (newRoute === settings.routes.NETWORK_DETAIL) {
+    if (newRoute === routes.NETWORK_DETAIL) {
       /** @type {NetworkProxyElement} */ (this.$$('network-proxy')).reset();
     }
   },
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary.html b/chrome/browser/resources/settings/chromeos/internet_page/network_summary.html
index 0f5c8f85..bb3b099 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary.html
@@ -1,27 +1,15 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_listener_behavior.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="network_summary_item.html">
-
-<dom-module id="network-summary">
-  <template>
-    <style>
-      network-summary-item:first-child {
-        --cr-separator-line: 0;
-      }
-    </style>
-    <div id="summary">
-      <template is="dom-repeat" items="[[activeNetworkStates_]]">
-        <network-summary-item id="[[getTypeString_(item)]]"
-            active-network-state="[[item]]"
-            device-state="[[get(item.type, deviceStates)]]"
-            network-state-list="[[get(item.type, networkStateLists_)]]"
-            tether-device-state="[[getTetherDeviceState_(deviceStates)]]">
-        </network-summary-item>
-      </template>
-    </div>
+<style>
+  network-summary-item:first-child {
+    --cr-separator-line: 0;
+  }
+</style>
+<div id="summary">
+  <template is="dom-repeat" items="[[activeNetworkStates_]]">
+    <network-summary-item id="[[getTypeString_(item)]]"
+        active-network-state="[[item]]"
+        device-state="[[get(item.type, deviceStates)]]"
+        network-state-list="[[get(item.type, networkStateLists_)]]"
+        tether-device-state="[[getTetherDeviceState_(deviceStates)]]">
+    </network-summary-item>
   </template>
-  <script src="network_summary.js"></script>
-</dom-module>
+</div>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary.js b/chrome/browser/resources/settings/chromeos/internet_page/network_summary.js
index af3de0a..a51ee83 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary.js
@@ -7,11 +7,18 @@
  * by type: Ethernet, WiFi, Cellular, and VPN.
  */
 
-(function() {
+import './network_summary_item.js';
+
+import {MojoInterfaceProvider, MojoInterfaceProviderImpl} from '//resources/cr_components/chromeos/network/mojo_interface_provider.m.js';
+import {NetworkListenerBehavior} from '//resources/cr_components/chromeos/network/network_listener_behavior.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
 
 const mojom = chromeos.networkConfig.mojom;
 
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'network-summary',
 
   behaviors: [
@@ -86,8 +93,8 @@
 
   /** @override */
   created() {
-    this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance()
-                              .getMojoServiceRemote();
+    this.networkConfig_ =
+        MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote();
   },
 
   /** @override */
@@ -304,4 +311,3 @@
     return this.deviceStates[mojom.NetworkType.kTether];
   },
 });
-})();
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html
index f226563d..103b51cf 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html
@@ -1,107 +1,87 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
+<style include="internet-shared iron-flex">
+  network-siminfo {
+    padding-inline-start: var(--cr-section-padding);
+  }
 
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cellular_utils.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_icon.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_siminfo.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
+  #outerBox {
+    padding: 0 var(--cr-section-padding);
+  }
 
-<dom-module id="network-summary-item">
-  <template>
-    <style include="internet-shared iron-flex">
-      network-siminfo {
-        padding-inline-start: var(--cr-section-padding);
-      }
+  #details {
+    align-items: center;
+    display: flex;
+    flex: auto;
+  }
 
-      #outerBox {
-        padding: 0 var(--cr-section-padding);
-      }
+  .network-state {
+    color: var(--cr-secondary-text-color);
+    font-size: inherit;
+  }
 
-      #details {
-        align-items: center;
-        display: flex;
-        flex: auto;
-      }
-
-      .network-state {
-        color: var(--cr-secondary-text-color);
-        font-size: inherit;
-      }
-
-      .locked-warning-message {
-        color: var(--google-yellow-800);
-        font-size: inherit;
-      }
-    </style>
-    <div class="settings-box two-line no-padding">
-      <div actionable$="[[isItemActionable_(activeNetworkState,
-                            deviceState, networkStateList)]]"
-          class="flex layout horizontal center link-wrapper"
-          on-click="onShowDetailsTap_">
-        <div id="details" no-flex$="[[showSimInfo_(deviceState)]]"
-             aria-hidden="true">
-          <network-icon
-              id="networkIcon"
-              show-technology-badge="[[showTechnologyBadge_]]"
-              network-state="[[activeNetworkState]]"
-              device-state="[[deviceState]]">
-          </network-icon>
-          <div class="flex settings-box-text">
-            <div id="networkTitleText">
-              [[getTitleText_(activeNetworkState)]]
-            </div>
-            <div id="networkState"
-                class$="[[getNetworkStateClass_(deviceState, deviceState.*)]]">
-              [[getNetworkStateText_(activeNetworkState, deviceState.*)]]
-            </div>
-          </div>
+  .locked-warning-message {
+    color: var(--google-yellow-800);
+    font-size: inherit;
+  }
+</style>
+<div class="settings-box two-line no-padding">
+  <div actionable$="[[isItemActionable_(activeNetworkState,
+                        deviceState, networkStateList)]]"
+      class="flex layout horizontal center link-wrapper"
+      on-click="onShowDetailsTap_">
+    <div id="details" no-flex$="[[showSimInfo_(deviceState)]]"
+          aria-hidden="true">
+      <network-icon
+          id="networkIcon"
+          show-technology-badge="[[showTechnologyBadge_]]"
+          network-state="[[activeNetworkState]]"
+          device-state="[[deviceState]]">
+      </network-icon>
+      <div class="flex settings-box-text">
+        <div id="networkTitleText">
+          [[getTitleText_(activeNetworkState)]]
         </div>
-
-        <template is="dom-if" if="[[showSimInfo_(deviceState)]]" restamp>
-          <network-siminfo
-              on-click="doNothing_"
-              network-state="[[activeNetworkState]]"
-              device-state="[[deviceState]]">
-          </network-siminfo>
-        </template>
-
-        <template is="dom-if" if="[[showPolicyIndicator_(activeNetworkState)]]">
-          <cr-policy-indicator id="policyIndicator"
-              icon-aria-label="[[getTitleText_(activeNetworkState)]]"
-              indicator-type="[[getPolicyIndicatorType_(activeNetworkState)]]"
-              on-click="doNothing_">
-          </cr-policy-indicator>
-        </template>
-
-        <template is="dom-if" if="[[showArrowButton_(activeNetworkState,
-                                      deviceState, networkStateList)]]">
-          <cr-icon-button class="subpage-arrow"
-              aria-labelledby="networkTitleText"
-              aria-describedby="networkState networkIcon"
-              aria-roledescription="$i18n{subpageArrowRoleDescription}">
-          </cr-icon-button>
-        </template>
+        <div id="networkState"
+            class$="[[getNetworkStateClass_(deviceState, deviceState.*)]]">
+          [[getNetworkStateText_(activeNetworkState, deviceState.*)]]
+        </div>
       </div>
-
-      <template is="dom-if" if="[[enableToggleIsVisible_(deviceState)]]">
-        <div class="separator"></div>
-        <cr-toggle id="deviceEnabledButton"
-            class="margin-matches-padding"
-            aria-label$="[[getToggleA11yString_(deviceState)]]"
-            aria-describedby$="[[getToggleA11yDescribedBy_(deviceState)]]"
-            checked="[[deviceIsEnabled_(deviceState)]]"
-            disabled="[[!enableToggleIsEnabled_(deviceState)]]"
-            on-change="onDeviceEnabledChange_">
-        </cr-toggle>
-      </template>
     </div>
+
+    <template is="dom-if" if="[[showSimInfo_(deviceState)]]" restamp>
+      <network-siminfo
+          on-click="doNothing_"
+          network-state="[[activeNetworkState]]"
+          device-state="[[deviceState]]">
+      </network-siminfo>
+    </template>
+
+    <template is="dom-if" if="[[showPolicyIndicator_(activeNetworkState)]]">
+      <cr-policy-indicator id="policyIndicator"
+          icon-aria-label="[[getTitleText_(activeNetworkState)]]"
+          indicator-type="[[getPolicyIndicatorType_(activeNetworkState)]]"
+          on-click="doNothing_">
+      </cr-policy-indicator>
+    </template>
+
+    <template is="dom-if" if="[[showArrowButton_(activeNetworkState,
+                                  deviceState, networkStateList)]]">
+      <cr-icon-button class="subpage-arrow"
+          aria-labelledby="networkTitleText"
+          aria-describedby="networkState networkIcon"
+          aria-roledescription="$i18n{subpageArrowRoleDescription}">
+      </cr-icon-button>
+    </template>
+  </div>
+
+  <template is="dom-if" if="[[enableToggleIsVisible_(deviceState)]]">
+    <div class="separator"></div>
+    <cr-toggle id="deviceEnabledButton"
+        class="margin-matches-padding"
+        aria-label$="[[getToggleA11yString_(deviceState)]]"
+        aria-describedby$="[[getToggleA11yDescribedBy_(deviceState)]]"
+        checked="[[deviceIsEnabled_(deviceState)]]"
+        disabled="[[!enableToggleIsEnabled_(deviceState)]]"
+        on-change="onDeviceEnabledChange_">
+    </cr-toggle>
   </template>
-  <script src="network_summary_item.js"></script>
-</dom-module>
+</div>
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 6c13a2e..c9f2535 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
@@ -9,11 +9,26 @@
  * section. See crbug.com/726380.
  */
 
-(function() {
+import '//resources/cr_components/chromeos/network/network_icon.m.js';
+import '//resources/cr_components/chromeos/network/network_siminfo.m.js';
+import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
+import '//resources/cr_elements/cr_toggle/cr_toggle.m.js';
+import '//resources/cr_elements/shared_vars_css.m.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+
+import {getSimSlotCount, hasActiveCellularNetwork, isActiveSim, isConnectedToNonCellularNetwork} from '//resources/cr_components/chromeos/network/cellular_utils.m.js';
+import {CrPolicyNetworkBehaviorMojo} from '//resources/cr_components/chromeos/network/cr_policy_network_behavior_mojo.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import {CrPolicyIndicatorType} from '//resources/cr_elements/policy/cr_policy_indicator_behavior.m.js';
+import {assert, assertNotReached} from '//resources/js/assert.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
 
 const mojom = chromeos.networkConfig.mojom;
 
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'network-summary-item',
 
   behaviors: [
@@ -652,4 +667,3 @@
     return this.i18n('OncType' + OncMojo.getNetworkTypeString(type));
   },
 });
-})();
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.html b/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.html
index 3a34825..5099009 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.html
@@ -1,131 +1,111 @@
-<link rel="import" href="chrome://resources/html/polymer.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_icon.html">
-<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
-<link rel="import" href="chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/html/i18n_behavior.html">
-<link rel="import" href="chrome://resources/html/util.html">
-<link rel="import" href="../../chromeos/os_icons.html">
-<link rel="import" href="../../settings_shared_css.html">
-<link rel="import" href="../os_route.html">
+<style include="settings-shared iron-flex">
+  [slot=title] {
+    margin-top: 9px;
+  }
 
-<dom-module id="tether-connection-dialog">
-  <template>
-    <style include="settings-shared iron-flex">
-      [slot=title] {
-        margin-top: 9px;
-      }
+  [slot=body] {
+    border-top: solid 2px rgba(0, 0, 0, .14);
+  }
 
-      [slot=body] {
-        border-top: solid 2px rgba(0, 0, 0, .14);
-      }
+  [slot=body] > * {
+    margin-inline-start: 5px;
+  }
 
-      [slot=body] > * {
-        margin-inline-start: 5px;
-      }
+  iron-icon {
+    --iron-icon-fill-color: #4285F4;
+  }
 
-      iron-icon {
-        --iron-icon-fill-color: #4285F4;
-      }
+  #host-device-text-container {
+    display: flex;
+    flex-direction: column;
+    margin-inline-start: 18px;
+  }
 
-      #host-device-text-container {
-        display: flex;
-        flex-direction: column;
-        margin-inline-start: 18px;
-      }
+  #availability-title {
+    color: black;
+    margin-top: 5px;
+    opacity: 0.54;
+  }
 
-      #availability-title {
-        color: black;
-        margin-top: 5px;
-        opacity: 0.54;
-      }
+  #host-device-container {
+    align-items: center;
+    display: flex;
+    margin-top: 12px;
+    min-height: 46px;
+  }
 
-      #host-device-container {
-        align-items: center;
-        display: flex;
-        margin-top: 12px;
-        min-height: 46px;
-      }
+  #tether-explanation,
+  #tether-carrier-warning,
+  #tether-description-title {
+    margin-top: var(--cr-section-vertical-margin);
+  }
 
-      #tether-explanation,
-      #tether-carrier-warning,
-      #tether-description-title {
-        margin-top: var(--cr-section-vertical-margin);
-      }
+  #tether-carrier-warning {
+    font-weight: 600;
+  }
 
-      #tether-carrier-warning {
-        font-weight: 600;
-      }
+  #tether-description-list {
+    padding-inline-start: 16px;
+  }
 
-      #tether-description-list {
-        padding-inline-start: 16px;
-      }
-
-      #host-device-lost-container {
-        color: var(--google-red-500);
-        font-weight: 500;
-      }
-    </style>
-    <cr-dialog id="dialog" close-text="$i18n{close}">
-      <div slot="title">$i18n{tetherConnectionDialogTitle}</div>
-      <div slot="body">
-        <span id="availability-title">
-          $i18n{tetherConnectionAvailableDeviceTitle}
+  #host-device-lost-container {
+    color: var(--google-red-500);
+    font-weight: 500;
+  }
+</style>
+<cr-dialog id="dialog" close-text="$i18n{close}">
+  <div slot="title">$i18n{tetherConnectionDialogTitle}</div>
+  <div slot="body">
+    <span id="availability-title">
+      $i18n{tetherConnectionAvailableDeviceTitle}
+    </span>
+    <div id="host-device-container">
+      <iron-icon id="host-device-signal-strength-icon"
+          icon="[[getSignalStrengthIconName_(managedProperties)]]"
+          aria-label$="[[getSignalStrengthLabel_(managedProperties)]]">
+      </iron-icon>
+      <div id="host-device-text-container">
+        <span id="host-device-text-name"
+            aria-describedby="host-device-signal-strength-icon
+            hostDeviceTextBattery">
+          [[getDeviceName_(managedProperties)]]
         </span>
-        <div id="host-device-container">
-          <iron-icon id="host-device-signal-strength-icon"
-              icon="[[getSignalStrengthIconName_(managedProperties)]]"
-              aria-label$="[[getSignalStrengthLabel_(managedProperties)]]">
-          </iron-icon>
-          <div id="host-device-text-container">
-            <span id="host-device-text-name"
-                aria-describedby="host-device-signal-strength-icon
-                hostDeviceTextBattery">
-              [[getDeviceName_(managedProperties)]]
-            </span>
-            <span id="hostDeviceTextBattery" class="secondary"
-                aria-hidden="true">
-              [[getBatteryPercentageString_(managedProperties)]]
-            </span>
-          </div>
-          <div class="flex"></div>
-          <div id="host-device-lost-container" hidden$="[[!outOfRange]]">
-            <iron-icon icon="os-settings:alert-device-out-of-range">
-            </iron-icon>
-            $i18n{tetherPhoneOutOfRange}
-          </div>
-        </div>
-        <div id="tether-explanation">
-          [[getExplanation_(managedProperties)]]
-        </div>
-        <div id="tether-carrier-warning">
-          $i18n{tetherConnectionCarrierWarning}
-        </div>
-        <div id="tether-description-title">
-          [[getDescriptionTitle_(managedProperties)]]
-        </div>
-        <ul id="tether-description-list">
-          <li>$i18n{tetherConnectionDescriptionMobileData}</li>
-          <li>[[getBatteryDescription_(managedProperties)]]</li>
-          <li hidden$="[[!shouldShowDisconnectFromWifi_(managedProperties)]]">
-            $i18n{tetherConnectionDescriptionWiFi}
-          </li>
-        </ul>
+        <span id="hostDeviceTextBattery" class="secondary"
+            aria-hidden="true">
+          [[getBatteryPercentageString_(managedProperties)]]
+        </span>
       </div>
-      <div slot="button-container">
-        <cr-button class="cancel-button" on-click="onNotNowTap_">
-          $i18n{tetherConnectionNotNowButton}
-        </cr-button>
-        <cr-button id="connectButton" class="action-button"
-            on-click="onConnectTap_" disabled="[[outOfRange]]">
-          $i18n{tetherConnectionConnectButton}
-        </cr-button>
+      <div class="flex"></div>
+      <div id="host-device-lost-container" hidden$="[[!outOfRange]]">
+        <iron-icon icon="os-settings:alert-device-out-of-range">
+        </iron-icon>
+        $i18n{tetherPhoneOutOfRange}
       </div>
-    </cr-dialog>
-  </template>
-  <script src="tether_connection_dialog.js"></script>
-</dom-module>
+    </div>
+    <div id="tether-explanation">
+      [[getExplanation_(managedProperties)]]
+    </div>
+    <div id="tether-carrier-warning">
+      $i18n{tetherConnectionCarrierWarning}
+    </div>
+    <div id="tether-description-title">
+      [[getDescriptionTitle_(managedProperties)]]
+    </div>
+    <ul id="tether-description-list">
+      <li>$i18n{tetherConnectionDescriptionMobileData}</li>
+      <li>[[getBatteryDescription_(managedProperties)]]</li>
+      <li hidden$="[[!shouldShowDisconnectFromWifi_(managedProperties)]]">
+        $i18n{tetherConnectionDescriptionWiFi}
+      </li>
+    </ul>
+  </div>
+  <div slot="button-container">
+    <cr-button class="cancel-button" on-click="onNotNowTap_">
+      $i18n{tetherConnectionNotNowButton}
+    </cr-button>
+    <cr-button id="connectButton" class="action-button"
+        on-click="onConnectTap_" disabled="[[outOfRange]]">
+      $i18n{tetherConnectionConnectButton}
+    </cr-button>
+  </div>
+</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.js b/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.js
index b0c60cd8..a81e9fe 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.js
@@ -25,7 +25,23 @@
   return 0;
 }
 
+import {afterNextRender, Polymer, html, flush, Templatizer, TemplateInstanceBase} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import '//resources/cr_components/chromeos/network/network_icon.m.js';
+import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
+import '//resources/cr_elements/cr_button/cr_button.m.js';
+import '//resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import '//resources/cr_elements/shared_vars_css.m.js';
+import '//resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-lite.js';
+import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {HTMLEscape, listenOnce} from '//resources/js/util.m.js';
+import '../os_icons.m.js';
+import '../../settings_shared_css.js';
+import {routes} from '../os_route.m.js';
+
 Polymer({
+  _template: html`{__html_template__}`,
   is: 'tether-connection-dialog',
 
   behaviors: [I18nBehavior],
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni
index 9a61eebe..3f7e41c 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.gni
+++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -314,6 +314,26 @@
   "chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_page.html",
   "chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_paths.html",
   "chrome/browser/resources/settings/chromeos/guest_os/guest_os_shared_usb_devices.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/esim_install_error_dialog.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/esim_remove_profile_dialog.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/esim_rename_dialog.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/cellular_roaming_toggle_button.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_dialog.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/cellular_setup_settings_delegate.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/internet_page_browser_proxy.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/internet_config.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/internet_detail_menu.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/internet_detail_page.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/internet_page.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/internet_shared_css.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/network_always_on_vpn.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/network_proxy_section.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/network_summary.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/network_summary_item.html",
+  "chrome/browser/resources/settings/chromeos/internet_page/tether_connection_dialog.html",
   "chrome/browser/resources/settings/chromeos/localized_link/localized_link.html",
   "chrome/browser/resources/settings/chromeos/on_startup_page/on_startup_page.html",
   "chrome/browser/resources/settings/chromeos/os_apps_page/app_notifications_page/app_notifications_subpage.html",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js
index 9dfcce2..e985f7c 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.js
+++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -19,19 +19,19 @@
 import './device_page/storage_external_entry.m.js';
 import './device_page/stylus.m.js';
 import './google_assistant_page/google_assistant_page.js';
-import './internet_page/cellular_roaming_toggle_button.m.js';
-import './internet_page/cellular_setup_dialog.m.js';
-import './internet_page/esim_remove_profile_dialog.m.js';
-import './internet_page/internet_config.m.js';
-import './internet_page/internet_detail_page.m.js';
-import './internet_page/internet_known_networks_page.m.js';
-import './internet_page/internet_page.m.js';
-import './internet_page/internet_subpage.m.js';
-import './internet_page/network_always_on_vpn.m.js';
-import './internet_page/network_proxy_section.m.js';
-import './internet_page/network_summary.m.js';
-import './internet_page/network_summary_item.m.js';
-import './internet_page/tether_connection_dialog.m.js';
+import './internet_page/cellular_roaming_toggle_button.js';
+import './internet_page/cellular_setup_dialog.js';
+import './internet_page/esim_remove_profile_dialog.js';
+import './internet_page/internet_config.js';
+import './internet_page/internet_detail_page.js';
+import './internet_page/internet_known_networks_page.js';
+import './internet_page/internet_page.js';
+import './internet_page/internet_subpage.js';
+import './internet_page/network_always_on_vpn.js';
+import './internet_page/network_proxy_section.js';
+import './internet_page/network_summary.js';
+import './internet_page/network_summary_item.js';
+import './internet_page/tether_connection_dialog.js';
 import './kerberos_page/kerberos_accounts.m.js';
 import './kerberos_page/kerberos_page.m.js';
 import './localized_link/localized_link.js';
@@ -104,7 +104,7 @@
 export {DevicePageBrowserProxy, DevicePageBrowserProxyImpl, IdleBehavior, LidClosedBehavior, NoteAppLockScreenSupport, setDisplayApiForTesting, StorageSpaceState} from './device_page/device_page_browser_proxy.m.js';
 export {GoogleAssistantBrowserProxyImpl} from './google_assistant_page/google_assistant_browser_proxy.js';
 export {ConsentStatus, DspHotwordState} from './google_assistant_page/google_assistant_page.js';
-export {InternetPageBrowserProxy, InternetPageBrowserProxyImpl} from './internet_page/internet_page_browser_proxy.m.js';
+export {InternetPageBrowserProxy, InternetPageBrowserProxyImpl} from './internet_page/internet_page_browser_proxy.js';
 export {KerberosAccountsBrowserProxyImpl, KerberosConfigErrorCode, KerberosErrorType} from './kerberos_page/kerberos_accounts_browser_proxy.m.js';
 export {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from './metrics_recorder.m.js';
 export {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_page/multidevice_browser_proxy.m.js';
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html
index a6f77d4..9e7f2ed 100644
--- a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html
+++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html
@@ -105,6 +105,7 @@
         background-color: var(--google-grey-50);
         border: 1px solid var(--google-grey-200);
         border-radius: 4px;
+        display: flex;
         margin-top: 12px;
         padding: 12px;
       }
@@ -116,6 +117,16 @@
           border-color: transparent;
         }
       }
+
+      .search-history-box-icon {
+        --iron-icon-fill-color: var(--cr-link-row-start-icon-color,
+            var(--google-grey-refresh-700));
+        display: flex;
+        flex-shrink: 0;
+        padding: 12px 0;
+        padding-inline-end: var(--cr-icon-button-margin-start);
+        width: var(--cr-link-row-icon-width, var(--cr-icon-size));
+      }
     </style>
 
     <cr-dialog id="clearBrowsingDataDialog"
@@ -178,15 +189,23 @@
                 sub-label="[[counters_.cache_basic]]"
                 disabled="[[clearingInProgress_]]" no-set-pref>
             </settings-checkbox>
-            <div id="googleSearchHistoryLabel"
-                class="search-history-box"
-                hidden="[[!shouldShowGoogleSearchHistoryLabel_(isSignedIn_)]]"
-                inner-h-t-m-l="[[googleSearchHistoryString_]]">
+            <div class="search-history-box"
+                hidden="[[!shouldShowGoogleSearchHistoryLabel_(isSignedIn_)]]">
+              <iron-icon class="search-history-box-icon" aria-hidden="true"
+                  icon="settings20:safety-check">
+              </iron-icon>
+              <div id="googleSearchHistoryLabel"
+                  inner-h-t-m-l="[[googleSearchHistoryString_]]">
+              </div>
             </div>
-            <div id="nonGoogleSearchHistoryLabel"
-                class="search-history-box"
-                hidden="[[!shouldShowNonGoogleSearchHistoryLabel_(isNonGoogleDse_)]]"
-                inner-h-t-m-l="[[nonGoogleSearchHistoryString_]]">
+            <div class="search-history-box"
+                hidden="[[!shouldShowNonGoogleSearchHistoryLabel_(isNonGoogleDse_)]]">
+              <iron-icon class="search-history-box-icon" aria-hidden="true"
+                  icon="settings20:safety-check">
+              </iron-icon>
+              <div id="nonGoogleSearchHistoryLabel"
+                  inner-h-t-m-l="[[nonGoogleSearchHistoryString_]]">
+              </div>
             </div>
           </div>
           <div id="advanced-tab">
diff --git a/chrome/browser/resources/settings/people_page/BUILD.gn b/chrome/browser/resources/settings/people_page/BUILD.gn
index 3b699d6e7..1f72c85a 100644
--- a/chrome/browser/resources/settings/people_page/BUILD.gn
+++ b/chrome/browser/resources/settings/people_page/BUILD.gn
@@ -61,7 +61,6 @@
       "..:route",
       "..:router",
       "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-      "//ui/webui/resources/cr_components/customize_themes",
     ]
   }
 
diff --git a/chrome/browser/resources/settings/settings_page/BUILD.gn b/chrome/browser/resources/settings/settings_page/BUILD.gn
index b6a3a53..0f2895c 100644
--- a/chrome/browser/resources/settings/settings_page/BUILD.gn
+++ b/chrome/browser/resources/settings/settings_page/BUILD.gn
@@ -10,14 +10,14 @@
   is_polymer3 = true
   closure_flags = settings_closure_flags
   deps = [
-    ":main_page_behavior",
+    ":main_page_mixin",
     ":settings_animated_pages",
     ":settings_section",
     ":settings_subpage",
   ]
 }
 
-js_library("main_page_behavior") {
+js_library("main_page_mixin") {
   deps = [
     ":settings_section",
     "..:route",
diff --git a/chrome/browser/resources/settings/settings_page/main_page_behavior.js b/chrome/browser/resources/settings/settings_page/main_page_mixin.js
similarity index 100%
rename from chrome/browser/resources/settings/settings_page/main_page_behavior.js
rename to chrome/browser/resources/settings/settings_page/main_page_mixin.js
diff --git a/chrome/browser/resources/signin/profile_customization/BUILD.gn b/chrome/browser/resources/signin/profile_customization/BUILD.gn
index 1f817ce9..f886849 100644
--- a/chrome/browser/resources/signin/profile_customization/BUILD.gn
+++ b/chrome/browser/resources/signin/profile_customization/BUILD.gn
@@ -19,7 +19,6 @@
     ":profile_customization_browser_proxy",
     "//third_party/polymer/v3_0/components-chromium/iron-icon",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_components/customize_themes",
     "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
     "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
     "//ui/webui/resources/js:load_time_data.m",
diff --git a/chrome/browser/resources/signin/profile_picker/BUILD.gn b/chrome/browser/resources/signin/profile_picker/BUILD.gn
index fc545fa..45ced0d 100644
--- a/chrome/browser/resources/signin/profile_picker/BUILD.gn
+++ b/chrome/browser/resources/signin/profile_picker/BUILD.gn
@@ -34,7 +34,8 @@
     deps = [
       ":preprocess",
       ":preprocess_generated",
-      "../../../../../ui/webui/resources:preprocess",
+      "//ui/webui/resources:preprocess",
+      "//ui/webui/resources/cr_components/customize_themes:build_ts",
     ]
     excludes = [
       "chrome://resources/js/cr.m.js",
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn
index b0b7b00..b13a264 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn
@@ -31,13 +31,14 @@
     "..:navigation_mixin",
     "..:policy_helper",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_components/customize_themes",
+    "//ui/webui/resources/cr_components/customize_themes:mojom_webui_js",
     "//ui/webui/resources/cr_elements/cr_button:cr_button.m",
     "//ui/webui/resources/cr_elements/cr_checkbox:cr_checkbox.m",
     "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m",
     "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
     "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
     "//ui/webui/resources/cr_elements/cr_profile_avatar_selector:cr_profile_avatar_selector",
+    "//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/usb_internals/descriptor_panel.js b/chrome/browser/resources/usb_internals/descriptor_panel.js
index 2b9bcc93..0a02ce7 100644
--- a/chrome/browser/resources/usb_internals/descriptor_panel.js
+++ b/chrome/browser/resources/usb_internals/descriptor_panel.js
@@ -480,7 +480,7 @@
       checkTransferSuccess(
           response.status, 'Failed to read the device descriptor.',
           this.rootElement_);
-      this.renderStandardDescriptor_(new Uint8Array(response.data));
+      this.renderStandardDescriptor_(new Uint8Array(response.data.buffer));
     } catch (e) {
       showError(e.message, this.rootElement_);
     } finally {
@@ -607,7 +607,8 @@
           'Failed to read the device configuration descriptor to determine ' +
               'the total descriptor length.',
           this.rootElement_);
-      const dataView = new DataView(new Uint8Array(response.data).buffer);
+      const dataView =
+          new DataView(new Uint8Array(response.data.buffer).buffer);
       const length = dataView.getUint16(
           CONFIGURATION_DESCRIPTOR_TOTAL_LENGTH_OFFSET, true);
       // Re-gets the data using the full length.
@@ -617,7 +618,7 @@
           response.status,
           'Failed to read the complete configuration descriptor.',
           this.rootElement_);
-      this.renderStandardDescriptor_(new Uint8Array(response.data));
+      this.renderStandardDescriptor_(new Uint8Array(response.data.buffer));
     } catch (e) {
       showError(e.message, this.rootElement_);
     } finally {
@@ -898,7 +899,7 @@
       await this.usbDeviceProxy_.close();
     }
 
-    const responseData = new Uint8Array(response.data);
+    const responseData = new Uint8Array(response.data.buffer);
     this.languageCodesListElement_.innerText = '';
 
     const optionAllElement = document.createElement('option');
@@ -953,7 +954,7 @@
 
       this.indexInput_.value = index;
       this.renderStandardDescriptor_(
-          new Uint8Array(response.data), languageCode, treeItem);
+          new Uint8Array(response.data.buffer), languageCode, treeItem);
     } catch (e) {
       showError(e.message, this.rootElement_);
     } finally {
@@ -1108,7 +1109,8 @@
           'Failed to read the device BOS descriptor to determine ' +
               'the total descriptor length.',
           this.rootElement_);
-      const dataView = new DataView(new Uint8Array(response.data).buffer);
+      const dataView =
+          new DataView(new Uint8Array(response.data.buffer).buffer);
       const length =
           dataView.getUint16(BOS_DESCRIPTOR_TOTAL_LENGTH_OFFSET, true);
       // Re-gets the data using the full length.
@@ -1117,7 +1119,8 @@
       checkTransferSuccess(
           response.status, 'Failed to read the complete BOS descriptor.',
           this.rootElement_);
-      await this.renderStandardDescriptor_(new Uint8Array(response.data));
+      await this.renderStandardDescriptor_(
+          new Uint8Array(response.data.buffer));
     } catch (e) {
       showError(e.message, this.rootElement_);
     } finally {
@@ -1476,7 +1479,7 @@
       let url;
       // URL Prefixes are defined by Chapter 4.3.1 of the WebUSB
       // specification: http://wicg.github.io/webusb/
-      switch (urlResponse.data[2]) {
+      switch (urlResponse.data.buffer[2]) {
         case 0:
           url = 'http://';
           break;
@@ -1489,7 +1492,7 @@
       }
       // The first three elements of urlResponse.data are length, descriptor
       // type and URL scheme prefix.
-      url += decodeUtf8Array(new Uint8Array(urlResponse.data.slice(3)));
+      url += decodeUtf8Array(new Uint8Array(urlResponse.data.buffer.slice(3)));
 
       const landingPageItem = customTreeItem(url, 'descriptor-url');
       landingPageItem.labelElement.addEventListener(
@@ -1545,7 +1548,7 @@
       await this.usbDeviceProxy_.close();
     }
 
-    return new Uint8Array(response.data);
+    return new Uint8Array(response.data.buffer);
   }
 
   /**
@@ -1572,7 +1575,7 @@
       // command. It doesn't need extra bytes to send the device in the body
       // of the request.
       const response = await this.usbDeviceProxy_.controlTransferOut(
-          usbControlTransferParams, [], CONTROL_TRANSFER_TIMEOUT_MS);
+          usbControlTransferParams, {buffer: []}, CONTROL_TRANSFER_TIMEOUT_MS);
 
       checkTransferSuccess(
           response.status,
@@ -2319,7 +2322,7 @@
             usbControlTransferParams, length, CONTROL_TRANSFER_TIMEOUT_MS);
         checkTransferSuccess(
             response.status, 'Failed to send request.', this.rootElement_);
-        this.renderTestingData_(new Uint8Array(response.data));
+        this.renderTestingData_(new Uint8Array(response.data.buffer));
       } else if (direction === 'Host-to-Device') {
         const dataString = this.rootElement_.querySelector('textarea').value;
 
@@ -2329,7 +2332,8 @@
         }
 
         const response = await this.usbDeviceProxy_.controlTransferOut(
-            usbControlTransferParams, data, CONTROL_TRANSFER_TIMEOUT_MS);
+            usbControlTransferParams, {buffer: data},
+            CONTROL_TRANSFER_TIMEOUT_MS);
         checkTransferSuccess(
             response.status, 'Failed to send request.', this.rootElement_);
       }
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn
index 8ccefad..9c571fb8 100644
--- a/chrome/browser/safe_browsing/BUILD.gn
+++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -112,10 +112,6 @@
       "delayed_warning_navigation_throttle.h",
       "safe_browsing_blocking_page.cc",
       "safe_browsing_blocking_page.h",
-      "safe_browsing_navigation_observer.cc",
-      "safe_browsing_navigation_observer.h",
-      "safe_browsing_navigation_observer_manager.cc",
-      "safe_browsing_navigation_observer_manager.h",
       "safe_browsing_navigation_observer_manager_factory.cc",
       "safe_browsing_navigation_observer_manager_factory.h",
       "safe_browsing_navigation_throttle.cc",
diff --git a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_factory.cc b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_factory.cc
index 16897a2..3b35fa1 100644
--- a/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_factory.cc
+++ b/chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_factory.cc
@@ -11,11 +11,11 @@
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
 #include "chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/user_population.h"
 #include "chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/core/browser/sync/sync_utils.h"
 #include "components/safe_browsing/core/browser/verdict_cache_manager.h"
 #include "components/safe_browsing/core/common/features.h"
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
index 947cc36e..2c285fd 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -30,7 +30,6 @@
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
@@ -54,6 +53,7 @@
 #include "components/safe_browsing/content/browser/password_protection/password_protection_navigation_throttle.h"
 #include "components/safe_browsing/content/browser/password_protection/password_protection_request_content.h"
 #include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_throttler.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc b/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc
index 3a51848..c65f5bff 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc
@@ -8,13 +8,13 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/client_side_detection_service_factory.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/user_interaction_observer.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/content/browser/client_side_detection_host.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h"
 #include "components/safe_browsing/core/browser/sync/sync_utils.h"
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_delegate.h b/chrome/browser/safe_browsing/client_side_detection_host_delegate.h
index beab309..d2580e30 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_delegate.h
+++ b/chrome/browser/safe_browsing/client_side_detection_host_delegate.h
@@ -5,8 +5,8 @@
 #ifndef CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_
 #define CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_DELEGATE_H_
 
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/client_side_detection_host.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 
 namespace safe_browsing {
 
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_delegate_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_delegate_unittest.cc
index e5f89c72d..b43dd6b 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_delegate_unittest.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host_delegate_unittest.cc
@@ -7,11 +7,11 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "content/public/test/navigation_simulator.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
index 5f3c9b1..f7ce5700 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
@@ -407,7 +407,7 @@
   ListPrefUpdate settings_list(prefs, ConnectorPref(connector));
   DCHECK(settings_list.Get());
   if (!settings_list->GetList().empty())
-    settings_list->Clear();
+    settings_list->ClearList();
 
   settings_list->Append(*base::JSONReader::Read(pref_value));
   prefs->SetInteger(
@@ -453,7 +453,7 @@
     enterprise_connectors::AnalysisConnector connector) {
   ListPrefUpdate settings_list(prefs, ConnectorPref(connector));
   DCHECK(settings_list.Get());
-  settings_list->Clear();
+  settings_list->ClearList();
   prefs->ClearPref(ConnectorScopePref(connector));
 }
 
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h
index 1474622..9e51847 100644
--- a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h
+++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.h
@@ -21,11 +21,11 @@
 #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
 #include "chrome/browser/safe_browsing/download_protection/download_request_maker.h"
 #include "chrome/browser/safe_browsing/download_protection/file_analyzer.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
 #include "chrome/services/file_util/public/cpp/sandboxed_rar_analyzer.h"
 #include "chrome/services/file_util/public/cpp/sandboxed_zip_analyzer.h"
 #include "components/history/core/browser/history_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h"
 #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
index e85006b..e5eb6e74 100644
--- a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
@@ -30,7 +30,6 @@
 #include "chrome/browser/safe_browsing/download_protection/download_request_maker.h"
 #include "chrome/browser/safe_browsing/download_protection/download_url_sb_client.h"
 #include "chrome/browser/safe_browsing/download_protection/ppapi_download_request.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/services_delegate.h"
 #include "chrome/common/safe_browsing/binary_feature_extractor.h"
@@ -39,6 +38,7 @@
 #include "components/download/public/common/download_item.h"
 #include "components/google/core/common/google_util.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.h b/chrome/browser/safe_browsing/download_protection/download_protection_service.h
index 68e91c5..00a0c18d 100644
--- a/chrome/browser/safe_browsing/download_protection/download_protection_service.h
+++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.h
@@ -29,9 +29,9 @@
 #include "chrome/browser/safe_browsing/download_protection/deep_scanning_request.h"
 #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
 #include "chrome/browser/safe_browsing/download_protection/download_reporter.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/services_delegate.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/sessions/core/session_id.h"
 #include "url/gurl.h"
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
index e20ad66b..0dce2cb 100644
--- a/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_protection_service_unittest.cc
@@ -54,7 +54,6 @@
 #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
 #include "chrome/browser/safe_browsing/download_protection/ppapi_download_request.h"
 #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/test_extension_event_observer.h"
@@ -79,6 +78,7 @@
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/content/common/file_type_policies_test_util.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
diff --git a/chrome/browser/safe_browsing/download_protection/download_request_maker.h b/chrome/browser/safe_browsing/download_protection/download_request_maker.h
index a995aee..cdbfd01 100644
--- a/chrome/browser/safe_browsing/download_protection/download_request_maker.h
+++ b/chrome/browser/safe_browsing/download_protection/download_request_maker.h
@@ -9,9 +9,9 @@
 
 #include "base/callback.h"
 #include "chrome/browser/safe_browsing/download_protection/file_analyzer.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "components/download/public/common/download_item.h"
 #include "components/history/core/browser/history_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/core/common/proto/csd.pb.h"
 #include "content/public/browser/file_system_access_write_item.h"
 
diff --git a/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc b/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc
index dfd2c9d..4ce5d3f7 100644
--- a/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_url_sb_client.cc
@@ -10,8 +10,8 @@
 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/download_item_utils.h"
 
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
index 74a7759..f37697a 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -17,11 +17,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/chrome_controller_client.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/threat_details.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
 #include "components/safe_browsing/core/common/features.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
index f629164..1f61185 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -13,8 +13,6 @@
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/download_protection/download_protection_service.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/browser/ui/browser.h"
@@ -24,6 +22,8 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/download/public/common/download_item.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "content/public/browser/browser_context.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc
index 8be24e6a..9493b3e 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.cc
@@ -6,9 +6,9 @@
 
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "content/public/browser/browser_context.h"
 
 namespace safe_browsing {
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index 95e4e3f..77aaccf 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -30,7 +30,6 @@
 #include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
 #include "chrome/browser/safe_browsing/chrome_password_protection_service_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/services_delegate.h"
 #include "chrome/browser/safe_browsing/ui_manager.h"
@@ -42,6 +41,7 @@
 #include "components/safe_browsing/buildflags.h"
 #include "components/safe_browsing/content/browser/client_side_phishing_model.h"
 #include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/safe_browsing_network_context.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
index 9e0ff84..d8ff0caf8 100644
--- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
+++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
@@ -18,11 +18,11 @@
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_key.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/ping_manager.h"
diff --git a/chrome/browser/safe_browsing/trigger_creator.cc b/chrome/browser/safe_browsing/trigger_creator.cc
index 27ae4c6..b7cb275 100644
--- a/chrome/browser/safe_browsing/trigger_creator.cc
+++ b/chrome/browser/safe_browsing/trigger_creator.cc
@@ -7,10 +7,10 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/content/browser/triggers/ad_sampler_trigger.h"
 #include "components/safe_browsing/content/browser/triggers/suspicious_site_trigger.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
diff --git a/chrome/browser/safe_browsing/url_lookup_service_factory.cc b/chrome/browser/safe_browsing/url_lookup_service_factory.cc
index 9c3efe0..d4279355 100644
--- a/chrome/browser/safe_browsing/url_lookup_service_factory.cc
+++ b/chrome/browser/safe_browsing/url_lookup_service_factory.cc
@@ -10,7 +10,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/user_population.h"
@@ -19,6 +18,7 @@
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/safe_browsing/buildflags.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/safe_browsing/core/browser/realtime/url_lookup_service.h"
 #include "components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher.h"
 #include "components/safe_browsing/core/browser/sync/sync_utils.h"
diff --git a/chrome/browser/sessions/tab_restore_service_browsertest.cc b/chrome/browser/sessions/tab_restore_service_browsertest.cc
index 07a003b..9e9ccb2 100644
--- a/chrome/browser/sessions/tab_restore_service_browsertest.cc
+++ b/chrome/browser/sessions/tab_restore_service_browsertest.cc
@@ -25,7 +25,11 @@
   TabRestoreServiceImplBrowserTest()
       : test_system_web_app_installation_(
             web_app::TestSystemWebAppInstallation::
-                SetUpTabbedMultiWindowApp()) {}
+                SetUpTabbedMultiWindowApp()) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+    web_app::WebAppProvider::EnableSystemWebAppsInLacrosForTesting();
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+  }
 
  protected:
   std::unique_ptr<web_app::TestSystemWebAppInstallation>
diff --git a/chrome/browser/sync/sync_error_notifier_ash.cc b/chrome/browser/sync/sync_error_notifier_ash.cc
index 37a16ca..97d5d0b 100644
--- a/chrome/browser/sync/sync_error_notifier_ash.cc
+++ b/chrome/browser/sync/sync_error_notifier_ash.cc
@@ -57,8 +57,9 @@
 
 void TriggerSyncKeyRetrieval(Profile* profile) {
   chrome::ScopedTabbedBrowserDisplayer displayer(profile);
-  OpenTabForSyncKeyRetrieval(displayer.browser(),
-                             syncer::KeyRetrievalTriggerForUMA::kNotification);
+  OpenTabForSyncKeyRetrieval(
+      displayer.browser(),
+      syncer::TrustedVaultUserActionTriggerForUMA::kNotification);
 }
 
 void TriggerSyncRecoverabilityDegradedFix(Profile* profile) {
diff --git a/chrome/browser/sync/sync_service_android_bridge.cc b/chrome/browser/sync/sync_service_android_bridge.cc
index 1efc49b0..e58b165 100644
--- a/chrome/browser/sync/sync_service_android_bridge.cc
+++ b/chrome/browser/sync/sync_service_android_bridge.cc
@@ -360,7 +360,7 @@
                                                          jint trigger) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   syncer::RecordKeyRetrievalTrigger(
-      static_cast<syncer::KeyRetrievalTriggerForUMA>(trigger));
+      static_cast<syncer::TrustedVaultUserActionTriggerForUMA>(trigger));
 }
 
 jboolean SyncServiceAndroidBridge::ShouldOfferTrustedVaultOptIn(JNIEnv* env) {
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc
index 13104e34..7f96aac 100644
--- a/chrome/browser/sync/sync_ui_util.cc
+++ b/chrome/browser/sync/sync_ui_util.cc
@@ -439,7 +439,7 @@
 
 void OpenTabForSyncKeyRetrieval(
     Browser* browser,
-    syncer::KeyRetrievalTriggerForUMA key_retrieval_trigger) {
+    syncer::TrustedVaultUserActionTriggerForUMA key_retrieval_trigger) {
   RecordKeyRetrievalTrigger(key_retrieval_trigger);
   const GURL continue_url =
       GURL(UIThreadSearchTermsData().GoogleBaseURLValue());
diff --git a/chrome/browser/sync/sync_ui_util.h b/chrome/browser/sync/sync_ui_util.h
index f0a0ec0..09b2ed5 100644
--- a/chrome/browser/sync/sync_ui_util.h
+++ b/chrome/browser/sync/sync_ui_util.h
@@ -142,7 +142,7 @@
 // usually requires a reauth.
 void OpenTabForSyncKeyRetrieval(
     Browser* browser,
-    syncer::KeyRetrievalTriggerForUMA key_retrieval_trigger);
+    syncer::TrustedVaultUserActionTriggerForUMA key_retrieval_trigger);
 
 // Opens a tab for the purpose of improving the recoverability of the trusted
 // vault keys, which usually requires a reauth.
diff --git a/chrome/browser/sync/test/integration/apps_helper.cc b/chrome/browser/sync/test/integration/apps_helper.cc
index 975c537..74ac7c2 100644
--- a/chrome/browser/sync/test/integration/apps_helper.cc
+++ b/chrome/browser/sync/test/integration/apps_helper.cc
@@ -246,7 +246,7 @@
           }));
   run_loop.Run();
 
-  const web_app::AppRegistrar& registrar = provider->registrar();
+  const web_app::WebAppRegistrar& registrar = provider->registrar();
   DCHECK_EQ(base::UTF8ToUTF16(registrar.GetAppShortName(app_id)), info.title);
   DCHECK_EQ(registrar.GetAppStartUrl(app_id), info.start_url);
 
diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc
index 3f15f8eb..bff8b66 100644
--- a/chrome/browser/sync/test/integration/enable_disable_test.cc
+++ b/chrome/browser/sync/test/integration/enable_disable_test.cc
@@ -18,6 +18,7 @@
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/user_selectable_type.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_service_impl.h"
 #include "components/sync/driver/sync_user_settings_impl.h"
 #include "components/sync/test/fake_server/bookmark_entity_builder.h"
diff --git a/chrome/browser/sync/test/integration/single_client_device_info_sync_test.cc b/chrome/browser/sync/test/integration/single_client_device_info_sync_test.cc
index 51db474..42bef1e2 100644
--- a/chrome/browser/sync/test/integration/single_client_device_info_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_device_info_sync_test.cc
@@ -14,8 +14,8 @@
 #include "chrome/browser/sync/test/integration/sync_service_impl_harness.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "components/sync/base/model_type.h"
-#include "components/sync/base/sync_prefs.h"
 #include "components/sync/base/time.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/engine/loopback_server/persistent_tombstone_entity.h"
 #include "components/sync/invalidations/switches.h"
diff --git a/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc b/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc
index 8ac766d..459ec61 100644
--- a/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_polling_sync_test.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h"
 #include "chrome/common/webui_url_constants.h"
-#include "components/sync/base/sync_prefs.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_service_impl.h"
 #include "components/sync/engine/polling_constants.h"
 #include "components/sync/protocol/client_commands.pb.h"
diff --git a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
index c983d4e..12b650e 100644
--- a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/common/chrome_paths.h"
 #include "components/sync/base/model_type.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/driver/sync_service_impl.h"
 #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc b/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc
index de3cab5..3b2ec34 100644
--- a/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/common/chrome_paths.h"
 #include "components/sync/base/model_type.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/driver/sync_service_impl.h"
 #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc b/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc
index b1de7e4..2afcae7c 100644
--- a/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_sync_invalidations_test.cc
@@ -12,6 +12,7 @@
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/time.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/invalidations/switches.h"
 #include "components/sync/invalidations/sync_invalidations_service.h"
 #include "components/sync/protocol/sync.pb.h"
diff --git a/chrome/browser/sync/test/integration/sync_service_impl_harness.cc b/chrome/browser/sync/test/integration/sync_service_impl_harness.cc
index afb18d6..25e88e7 100644
--- a/chrome/browser/sync/test/integration/sync_service_impl_harness.cc
+++ b/chrome/browser/sync/test/integration/sync_service_impl_harness.cc
@@ -25,6 +25,7 @@
 #include "chrome/common/channel_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/identity_test_utils.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_internals_util.h"
 #include "components/sync/engine/net/url_translator.h"
 #include "components/sync/engine/sync_string_conversions.h"
diff --git a/chrome/browser/sync/test/integration/two_client_polling_sync_test.cc b/chrome/browser/sync/test/integration/two_client_polling_sync_test.cc
index 3c642c3b..34a1fd39 100644
--- a/chrome/browser/sync/test/integration/two_client_polling_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_polling_sync_test.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/common/webui_url_constants.h"
 #include "components/autofill/core/common/autofill_prefs.h"
-#include "components/sync/base/sync_prefs.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_service_impl.h"
 #include "components/sync/engine/polling_constants.h"
 #include "components/sync/protocol/client_commands.pb.h"
diff --git a/chrome/browser/sync/test/integration/two_client_web_apps_bmo_sync_test.cc b/chrome/browser/sync/test/integration/two_client_web_apps_bmo_sync_test.cc
index 19ff975..b603456 100644
--- a/chrome/browser/sync/test/integration/two_client_web_apps_bmo_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_web_apps_bmo_sync_test.cc
@@ -152,7 +152,7 @@
             }));
     run_loop.Run();
 
-    const AppRegistrar& registrar = GetRegistrar(profile);
+    const WebAppRegistrar& registrar = GetRegistrar(profile);
     EXPECT_EQ(base::UTF8ToUTF16(registrar.GetAppShortName(app_id)), info.title);
     EXPECT_EQ(registrar.GetAppStartUrl(app_id), info.start_url);
 
diff --git a/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc b/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc
index d6e73a7..b03038f 100644
--- a/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/test/browser_test.h"
@@ -50,7 +51,7 @@
         OsIntegrationManager::ScopedSuppressOsHooksForTesting();
   }
 
-  const AppRegistrar& GetRegistrar(Profile* profile) {
+  const WebAppRegistrar& GetRegistrar(Profile* profile) {
     return WebAppProvider::Get(profile)->registrar();
   }
 
@@ -84,7 +85,7 @@
   AppId app_id = apps_helper::InstallWebApp(GetProfile(0), info);
 
   EXPECT_EQ(WebAppInstallObserver(GetProfile(1)).AwaitNextInstall(), app_id);
-  const AppRegistrar& registrar = GetRegistrar(GetProfile(1));
+  const WebAppRegistrar& registrar = GetRegistrar(GetProfile(1));
   EXPECT_EQ(base::UTF8ToUTF16(registrar.GetAppShortName(app_id)), info.title);
   EXPECT_EQ(registrar.GetAppStartUrl(app_id), info.start_url);
   EXPECT_EQ(registrar.GetAppScope(app_id), info.scope);
@@ -99,7 +100,7 @@
   AppId app_id = apps_helper::InstallWebApp(GetProfile(0), info);
 
   EXPECT_EQ(WebAppInstallObserver(GetProfile(1)).AwaitNextInstall(), app_id);
-  const AppRegistrar& registrar = GetRegistrar(GetProfile(1));
+  const WebAppRegistrar& registrar = GetRegistrar(GetProfile(1));
   EXPECT_EQ(base::UTF8ToUTF16(registrar.GetAppShortName(app_id)), info.title);
   EXPECT_EQ(registrar.GetAppStartUrl(app_id), info.start_url);
 
@@ -116,7 +117,7 @@
             info.theme_color);
 
   EXPECT_EQ(WebAppInstallObserver(GetProfile(1)).AwaitNextInstall(), app_id);
-  const AppRegistrar& registrar = GetRegistrar(GetProfile(1));
+  const WebAppRegistrar& registrar = GetRegistrar(GetProfile(1));
   EXPECT_EQ(base::UTF8ToUTF16(registrar.GetAppShortName(app_id)), info.title);
   EXPECT_EQ(registrar.GetAppStartUrl(app_id), info.start_url);
   EXPECT_EQ(registrar.GetAppThemeColor(app_id), info.theme_color);
@@ -140,8 +141,8 @@
 }
 
 IN_PROC_BROWSER_TEST_F(TwoClientWebAppsSyncTest, AppFieldsChangeDoesNotSync) {
-  const AppRegistrar& registrar0 = GetRegistrar(GetProfile(0));
-  const AppRegistrar& registrar1 = GetRegistrar(GetProfile(1));
+  const WebAppRegistrar& registrar0 = GetRegistrar(GetProfile(0));
+  const WebAppRegistrar& registrar1 = GetRegistrar(GetProfile(1));
 
   WebApplicationInfo info_a;
   info_a.title = u"Test name A";
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index 7f6a6cc..b6d7b18 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -1246,44 +1246,56 @@
   // Parse the incoming data from |colors_value| into an intermediary structure.
   for (base::DictionaryValue::Iterator iter(*colors_value); !iter.IsAtEnd();
        iter.Advance()) {
-    const base::ListValue* color_list;
-    if (iter.value().GetAsList(&color_list) &&
-        ((color_list->GetSize() == 3) || (color_list->GetSize() == 4))) {
-      SkColor color = SK_ColorWHITE;
-      int r, g, b;
-      if (color_list->GetInteger(0, &r) && r >= 0 && r <= 255 &&
-          color_list->GetInteger(1, &g) && g >= 0 && g <= 255 &&
-          color_list->GetInteger(2, &b) && b >= 0 && b <= 255) {
-        if (color_list->GetSize() == 4) {
-          double alpha;
-          int alpha_int;
-          if (color_list->GetDouble(3, &alpha) && alpha >= 0 && alpha <= 1) {
-            color =
-                SkColorSetARGB(base::ClampRound<U8CPU>(alpha * 255), r, g, b);
-          } else if (color_list->GetInteger(3, &alpha_int) &&
-                     (alpha_int == 0 || alpha_int == 1)) {
-            color = SkColorSetARGB(alpha_int ? 255 : 0, r, g, b);
-          } else {
-            // Invalid entry for part 4.
-            continue;
-          }
-        } else {
-          color = SkColorSetRGB(r, g, b);
-        }
+    if (!iter.value().is_list())
+      continue;
+    base::Value::ConstListView color_list = iter.value().GetList();
+    if (!(color_list.size() == 3 || color_list.size() == 4))
+      continue;
 
-        if (iter.key() == "ntp_section") {
-          // We no longer use ntp_section, but to support legacy
-          // themes we still need to use it as a fallback for
-          // ntp_header.
-          if (!temp_colors->count(TP::COLOR_NTP_HEADER))
-            (*temp_colors)[TP::COLOR_NTP_HEADER] = color;
-        } else {
-          int id = GetIntForString(iter.key(), kOverwritableColorTable,
-                                   kOverwritableColorTableLength);
-          if (id != -1)
-            (*temp_colors)[id] = color;
+    SkColor color = SK_ColorWHITE;
+    absl::optional<int> r = color_list[0].GetIfInt();
+    absl::optional<int> g = color_list[1].GetIfInt();
+    absl::optional<int> b = color_list[2].GetIfInt();
+    if (!(r.has_value() && r.value() >= 0 && r.value() <= 255 &&
+          g.has_value() && g.value() >= 0 && g.value() <= 255 &&
+          b.has_value() && b.value() >= 0 && b.value() <= 255)) {
+      continue;
+    }
+
+    if (color_list.size() == 4) {
+      bool alpha_valid = false;
+      if (color_list[3].is_int()) {
+        int alpha_int = color_list[3].GetInt();
+        if (alpha_int == 0 || alpha_int == 1) {
+          color = SkColorSetARGB(alpha_int ? 255 : 0, *r, *g, *b);
+          alpha_valid = true;
+        }
+      } else if (color_list[3].is_double()) {
+        double alpha = color_list[3].GetDouble();
+        if (alpha >= 0 && alpha <= 1) {
+          color =
+              SkColorSetARGB(base::ClampRound<U8CPU>(alpha * 255), *r, *g, *b);
+          alpha_valid = true;
         }
       }
+
+      if (!alpha_valid)
+        continue;
+    } else {
+      color = SkColorSetRGB(*r, *g, *b);
+    }
+
+    if (iter.key() == "ntp_section") {
+      // We no longer use ntp_section, but to support legacy
+      // themes we still need to use it as a fallback for
+      // ntp_header.
+      if (!temp_colors->count(TP::COLOR_NTP_HEADER))
+        (*temp_colors)[TP::COLOR_NTP_HEADER] = color;
+    } else {
+      int id = GetIntForString(iter.key(), kOverwritableColorTable,
+                               kOverwritableColorTableLength);
+      if (id != -1)
+        (*temp_colors)[id] = color;
     }
   }
 }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 6c3abc8..0f932b33 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -504,6 +504,7 @@
     "//components/reading_list/features:flags",
     "//components/renderer_context_menu",
     "//components/resources",
+    "//components/safe_browsing/content/browser",
     "//components/safe_browsing/content/browser/password_protection",
     "//components/safe_browsing/content/browser/web_ui",
     "//components/safe_browsing/core/browser/db:database_manager",
@@ -4643,12 +4644,6 @@
       sources += [
         "views/accessibility/accessibility_focus_highlight.cc",
         "views/accessibility/accessibility_focus_highlight.h",
-        "views/frame/opaque_browser_frame_view.cc",
-        "views/frame/opaque_browser_frame_view.h",
-        "views/frame/opaque_browser_frame_view_layout.cc",
-        "views/frame/opaque_browser_frame_view_layout.h",
-        "views/frame/opaque_browser_frame_view_layout_delegate.cc",
-        "views/frame/opaque_browser_frame_view_layout_delegate.h",
         "views/outdated_upgrade_bubble_view.cc",
         "views/outdated_upgrade_bubble_view.h",
         "views/policy/enterprise_startup_dialog_view.cc",
@@ -4663,6 +4658,17 @@
         "views/relaunch_notification/relaunch_required_dialog_view.h",
         "views/screen_capture_notification_ui_views.cc",
       ]
+    }
+
+    if (!is_chromeos) {
+      sources += [
+        "views/frame/opaque_browser_frame_view.cc",
+        "views/frame/opaque_browser_frame_view.h",
+        "views/frame/opaque_browser_frame_view_layout.cc",
+        "views/frame/opaque_browser_frame_view_layout.h",
+        "views/frame/opaque_browser_frame_view_layout_delegate.cc",
+        "views/frame/opaque_browser_frame_view_layout_delegate.h",
+      ]
       deps += [ "//ui/views/window/vector_icons" ]
     }
 
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java
index 134860f..47aa6fa 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java
@@ -230,7 +230,8 @@
         if (!FeatureList.isInitialized()) return false;
         return AdaptiveToolbarFeatures.isSingleVariantModeEnabled()
                 && AdaptiveToolbarFeatures.getSingleVariantMode()
-                == AdaptiveToolbarButtonVariant.VOICE;
+                        == AdaptiveToolbarButtonVariant.VOICE
+                || AdaptiveToolbarFeatures.isCustomizationEnabled();
     }
 
     private void notifyObservers(boolean hint) {
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc
index 77802cb6..71c3c2b1 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -36,9 +36,9 @@
 #include "chrome/browser/ui/app_list/chrome_app_list_model_updater.h"
 #include "chrome/browser/ui/app_list/page_break_app_item.h"
 #include "chrome/browser/ui/app_list/page_break_constants.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_id_constants.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
@@ -1330,7 +1330,7 @@
   if (arc_prefs && arc_prefs->IsOem(id))
     return true;
 
-  auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile_);
+  auto* provider = web_app::WebAppProvider::GetForWebApps(profile_);
   if (provider && provider->registrar().WasInstalledByOem(id))
     return true;
 
diff --git a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
index 98a670a..6503113 100644
--- a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
@@ -36,8 +36,8 @@
 #include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h"
 #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h"
 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/dbus/cicerone/cicerone_client.h"
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc
index 943b9ffa..60162e0 100644
--- a/chrome/browser/ui/ash/chrome_new_window_client.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -53,12 +53,11 @@
 #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
 #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/common/webui_url_constants.h"
@@ -91,59 +90,23 @@
 constexpr std::pair<arc::mojom::ChromePage, const char*> kOSSettingsMapping[] =
     {{ChromePage::ACCOUNTS,
       chromeos::settings::mojom::kManageOtherPeopleSubpagePath},
-     {ChromePage::ACCOUNTMANAGER,
-      chromeos::settings::mojom::kMyAccountsSubpagePath},
-     {ChromePage::AMBIENTMODE,
-      chromeos::settings::mojom::kAmbientModeSubpagePath},
-     {ChromePage::ANDROIDAPPSDETAILS,
-      chromeos::settings::mojom::kGooglePlayStoreSubpagePath},
-     {ChromePage::ANDROIDAPPSDETAILSINBROWSERSETTINGS,
-      chromeos::settings::mojom::kGooglePlayStoreSubpagePath},
-     {ChromePage::APPMANAGEMENT,
-      chromeos::settings::mojom::kAppManagementSubpagePath},
-     {ChromePage::APPMANAGEMENTDETAILS,
-      chromeos::settings::mojom::kAppDetailsSubpagePath},
-     {ChromePage::ASSISTANT, chromeos::settings::mojom::kAssistantSubpagePath},
      {ChromePage::BLUETOOTH,
       chromeos::settings::mojom::kBluetoothDevicesSubpagePath},
      {ChromePage::BLUETOOTHDEVICES,
       chromeos::settings::mojom::kBluetoothDevicesSubpagePath},
-     {ChromePage::CELLULAR,
-      chromeos::settings::mojom::kMobileDataNetworksSubpagePath},
      {ChromePage::CHANGEPICTURE,
       chromeos::settings::mojom::kChangePictureSubpagePath},
-     {ChromePage::CONNECTEDDEVICES,
-      chromeos::settings::mojom::kMultiDeviceFeaturesSubpagePath},
-     {ChromePage::CROSTINISHAREDPATHS,
-      chromeos::settings::mojom::kCrostiniManageSharedFoldersSubpagePath},
-     {ChromePage::CROSTINISHAREDUSBDEVICES,
-      chromeos::settings::mojom::kCrostiniUsbPreferencesSubpagePath},
-     {ChromePage::CROSTINIEXPORTIMPORT,
-      chromeos::settings::mojom::kCrostiniBackupAndRestoreSubpagePath},
      {ChromePage::CUPSPRINTERS,
       chromeos::settings::mojom::kPrintingDetailsSubpagePath},
      {ChromePage::DATETIME, chromeos::settings::mojom::kDateAndTimeSectionPath},
      {ChromePage::DISPLAY, chromeos::settings::mojom::kDisplaySubpagePath},
-     {ChromePage::ETHERNET,
-      chromeos::settings::mojom::kEthernetDetailsSubpagePath},
-     {ChromePage::EXTERNALSTORAGE,
-      chromeos::settings::mojom::kExternalStorageSubpagePath},
      {ChromePage::HELP, chromeos::settings::mojom::kAboutChromeOsSectionPath},
-     {ChromePage::INTERNET, chromeos::settings::mojom::kNetworkSectionPath},
      {ChromePage::KEYBOARDOVERLAY,
       chromeos::settings::mojom::kKeyboardSubpagePath},
-     {ChromePage::KNOWNNETWORKS,
-      chromeos::settings::mojom::kKnownNetworksSubpagePath},
-     {ChromePage::OSLANGUAGES,
-      chromeos::settings::mojom::kLanguagesAndInputSectionPath},
-     {ChromePage::OSLANGUAGESEDITDICTIONARY,
-      chromeos::settings::mojom::kEditDictionarySubpagePath},
      {ChromePage::OSLANGUAGESINPUT,
       chromeos::settings::mojom::kInputSubpagePath},
      {ChromePage::OSLANGUAGESLANGUAGES,
       chromeos::settings::mojom::kLanguagesSubpagePath},
-     {ChromePage::OSLANGUAGESSMARTINPUTS,
-      chromeos::settings::mojom::kSmartInputsSubpagePath},
      {ChromePage::LOCKSCREEN,
       chromeos::settings::mojom::kSecurityAndSignInSubpagePath},
      {ChromePage::MAIN, ""},
@@ -155,37 +118,14 @@
       chromeos::settings::mojom::kMultiDeviceSectionPath},
      {ChromePage::NETWORKSTYPEVPN,
       chromeos::settings::mojom::kVpnDetailsSubpagePath},
-     {ChromePage::PLUGINVMSHAREDPATHS,
-      chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath},
-     {ChromePage::OSACCESSIBILITY,
-      chromeos::settings::mojom::kAccessibilitySectionPath},
-     {ChromePage::OSPEOPLE, chromeos::settings::mojom::kPeopleSectionPath},
-     {ChromePage::OSPRINTING, chromeos::settings::mojom::kPrintingSectionPath},
-     {ChromePage::OSPRIVACY,
-      chromeos::settings::mojom::kPrivacyAndSecuritySectionPath},
-     {ChromePage::OSRESET, chromeos::settings::mojom::kResetSectionPath},
-     {ChromePage::OSSEARCH,
-      chromeos::settings::mojom::kSearchAndAssistantSectionPath},
      {ChromePage::POINTEROVERLAY,
       chromeos::settings::mojom::kPointersSubpagePath},
      {ChromePage::POWER, chromeos::settings::mojom::kPowerSubpagePath},
-     {ChromePage::SEARCHSUBPAGE, chromeos::settings::mojom::kSearchSubpagePath},
-     {ChromePage::SMARTLOCKSETTINGS,
-      chromeos::settings::mojom::kSmartLockSubpagePath},
      {ChromePage::STORAGE, chromeos::settings::mojom::kStorageSubpagePath},
-     {ChromePage::STYLUS, chromeos::settings::mojom::kStylusSubpagePath},
-     {ChromePage::SWITCHACCESS,
-      chromeos::settings::mojom::kSwitchAccessOptionsSubpagePath},
-     {ChromePage::TETHERSETTINGS,
-      chromeos::settings::mojom::kMobileDataNetworksSubpagePath},
-     {ChromePage::WIFI, chromeos::settings::mojom::kWifiNetworksSubpagePath},
-     {ChromePage::KERBEROS, chromeos::settings::mojom::kKerberosSectionPath},
-     {ChromePage::KERBEROSACCOUNTSV2,
-      chromeos::settings::mojom::kKerberosAccountsV2SubpagePath}};
+     {ChromePage::WIFI, chromeos::settings::mojom::kWifiNetworksSubpagePath}};
 
 constexpr std::pair<arc::mojom::ChromePage, const char*>
     kBrowserSettingsMapping[] = {
-        {ChromePage::ACCESSIBILITY, chrome::kAccessibilitySubPage},
         {ChromePage::APPEARANCE, chrome::kAppearanceSubPage},
         {ChromePage::AUTOFILL, chrome::kAutofillSubPage},
         {ChromePage::CLEARBROWSERDATA, chrome::kClearBrowserDataSubPage},
@@ -195,7 +135,6 @@
         {ChromePage::PASSWORDS, chrome::kPasswordManagerSubPage},
         {ChromePage::PRIVACY, chrome::kPrivacySubPage},
         {ChromePage::RESET, chrome::kResetSubPage},
-        {ChromePage::PRINTING, chrome::kPrintingSettingsSubPage},
         {ChromePage::SEARCH, chrome::kSearchSubPage},
         {ChromePage::SYNCSETUP, chrome::kSyncSetupSubPage},
         {ChromePage::LANGUAGES, chrome::kLanguagesSubPage},
@@ -206,23 +145,6 @@
      {ChromePage::ABOUTDOWNLOADS, "chrome://downloads/"},
      {ChromePage::ABOUTHISTORY, "chrome://history/"}};
 
-constexpr arc::mojom::ChromePage kDeprecatedPages[] = {
-    ChromePage::DEPRECATED_CROSTINIDISKRESIZE,
-    ChromePage::DEPRECATED_DOWNLOADEDCONTENT,
-    ChromePage::DEPRECATED_KERBEROSACCOUNTS,
-    ChromePage::DEPRECATED_OSLANGUAGESDETAILS,
-    ChromePage::DEPRECATED_OSLANGUAGESINPUTMETHODS,
-    ChromePage::DEPRECATED_PLUGINVMDETAILS,
-};
-
-// mojom::ChromePage::LAST returns the amount of valid entries - 1.
-static_assert(base::size(kOSSettingsMapping) +
-                      base::size(kBrowserSettingsMapping) +
-                      base::size(kAboutPagesMapping) +
-                      base::size(kDeprecatedPages) ==
-                  static_cast<size_t>(arc::mojom::ChromePage::LAST) + 1,
-              "ChromePage mapping is out of sync");
-
 void RestoreTabUsingProfile(Profile* profile) {
   sessions::TabRestoreService* service =
       TabRestoreServiceFactory::GetForProfile(profile);
diff --git a/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc b/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc
index 9875b4ed..4be64fea 100644
--- a/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc
+++ b/chrome/browser/ui/ash/chrome_new_window_client_browsertest.cc
@@ -401,22 +401,12 @@
       ChromePage::KEYBOARDOVERLAY,
       base_url.Resolve(chromeos::settings::mojom::kKeyboardSubpagePath));
   TestOpenOSSettingsChromePage(
-      ChromePage::OSLANGUAGES,
-      base_url.Resolve(
-          chromeos::settings::mojom::kLanguagesAndInputSectionPath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::OSLANGUAGESEDITDICTIONARY,
-      base_url.Resolve(chromeos::settings::mojom::kEditDictionarySubpagePath));
-  TestOpenOSSettingsChromePage(
       ChromePage::OSLANGUAGESINPUT,
       base_url.Resolve(chromeos::settings::mojom::kInputSubpagePath));
   TestOpenOSSettingsChromePage(
       ChromePage::OSLANGUAGESLANGUAGES,
       base_url.Resolve(chromeos::settings::mojom::kLanguagesSubpagePath));
   TestOpenOSSettingsChromePage(
-      ChromePage::OSLANGUAGESSMARTINPUTS,
-      base_url.Resolve(chromeos::settings::mojom::kSmartInputsSubpagePath));
-  TestOpenOSSettingsChromePage(
       ChromePage::LOCKSCREEN,
       base_url.Resolve(
           chromeos::settings::mojom::kSecurityAndSignInSubpagePath));
@@ -428,120 +418,17 @@
       ChromePage::NETWORKSTYPEVPN,
       base_url.Resolve(chromeos::settings::mojom::kVpnDetailsSubpagePath));
   TestOpenOSSettingsChromePage(
-      ChromePage::OSPEOPLE,
-      base_url.Resolve(chromeos::settings::mojom::kPeopleSectionPath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::OSPRINTING,
-      base_url.Resolve(chromeos::settings::mojom::kPrintingSectionPath));
-  TestOpenOSSettingsChromePage(
       ChromePage::POINTEROVERLAY,
       base_url.Resolve(chromeos::settings::mojom::kPointersSubpagePath));
   TestOpenOSSettingsChromePage(
-      ChromePage::OSRESET,
-      base_url.Resolve(chromeos::settings::mojom::kResetSectionPath));
-  TestOpenOSSettingsChromePage(
       ChromePage::STORAGE,
       base_url.Resolve(chromeos::settings::mojom::kStorageSubpagePath));
   TestOpenOSSettingsChromePage(
-      ChromePage::OSACCESSIBILITY,
-      base_url.Resolve(chromeos::settings::mojom::kAccessibilitySectionPath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::ACCOUNTMANAGER,
-      base_url.Resolve(chromeos::settings::mojom::kMyAccountsSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::AMBIENTMODE,
-      base_url.Resolve(chromeos::settings::mojom::kAmbientModeSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::ANDROIDAPPSDETAILS,
-      base_url.Resolve(chromeos::settings::mojom::kGooglePlayStoreSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::ANDROIDAPPSDETAILSINBROWSERSETTINGS,
-      base_url.Resolve(chromeos::settings::mojom::kGooglePlayStoreSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::APPMANAGEMENTDETAILS,
-      base_url.Resolve(chromeos::settings::mojom::kAppDetailsSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::APPMANAGEMENT,
-      base_url.Resolve(chromeos::settings::mojom::kAppManagementSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::ASSISTANT,
-      base_url.Resolve(chromeos::settings::mojom::kAssistantSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::CONNECTEDDEVICES,
-      base_url.Resolve(
-          chromeos::settings::mojom::kMultiDeviceFeaturesSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::CROSTINISHAREDPATHS,
-      base_url.Resolve(
-          chromeos::settings::mojom::kCrostiniManageSharedFoldersSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::CROSTINISHAREDUSBDEVICES,
-      base_url.Resolve(
-          chromeos::settings::mojom::kCrostiniUsbPreferencesSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::CROSTINIEXPORTIMPORT,
-      base_url.Resolve(
-          chromeos::settings::mojom::kCrostiniBackupAndRestoreSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::EXTERNALSTORAGE,
-      base_url.Resolve(chromeos::settings::mojom::kExternalStorageSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::INTERNET,
-      base_url.Resolve(chromeos::settings::mojom::kNetworkSectionPath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::KNOWNNETWORKS,
-      base_url.Resolve(chromeos::settings::mojom::kKnownNetworksSubpagePath));
-  TestOpenOSSettingsChromePage(
       ChromePage::MANAGEACCESSIBILITYTTS,
       base_url.Resolve(chromeos::settings::mojom::kTextToSpeechSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::PLUGINVMSHAREDPATHS,
-      base_url.Resolve(
-          chromeos::settings::mojom::kPluginVmSharedPathsSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::OSSEARCH,
-      base_url.Resolve(
-          chromeos::settings::mojom::kSearchAndAssistantSectionPath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::OSPRIVACY,
-      base_url.Resolve(
-          chromeos::settings::mojom::kPrivacyAndSecuritySectionPath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::SMARTLOCKSETTINGS,
-      base_url.Resolve(chromeos::settings::mojom::kSmartLockSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::STYLUS,
-      base_url.Resolve(chromeos::settings::mojom::kStylusSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::SWITCHACCESS,
-      base_url.Resolve(
-          chromeos::settings::mojom::kSwitchAccessOptionsSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::TETHERSETTINGS,
-      base_url.Resolve(
-          chromeos::settings::mojom::kMobileDataNetworksSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::ETHERNET,
-      base_url.Resolve(chromeos::settings::mojom::kEthernetDetailsSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::CELLULAR,
-      base_url.Resolve(
-          chromeos::settings::mojom::kMobileDataNetworksSubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::KERBEROS,
-      base_url.Resolve(chromeos::settings::mojom::kKerberosSectionPath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::KERBEROSACCOUNTSV2,
-      base_url.Resolve(
-          chromeos::settings::mojom::kKerberosAccountsV2SubpagePath));
-  TestOpenOSSettingsChromePage(
-      ChromePage::SEARCHSUBPAGE,
-      base_url.Resolve(chromeos::settings::mojom::kSearchSubpagePath));
 }
 
 void TestAllBrowserSettingPages(const GURL& base_url) {
-  TestOpenChromePage(ChromePage::ACCESSIBILITY,
-                     base_url.Resolve(chrome::kAccessibilitySubPage));
   TestOpenChromePage(ChromePage::PRIVACY,
                      base_url.Resolve(chrome::kPrivacySubPage));
   TestOpenChromePage(ChromePage::APPEARANCE,
@@ -560,8 +447,6 @@
                      base_url.Resolve(chrome::kPasswordManagerSubPage));
   TestOpenChromePage(ChromePage::RESET,
                      base_url.Resolve(chrome::kResetSubPage));
-  TestOpenChromePage(ChromePage::PRINTING,
-                     base_url.Resolve(chrome::kPrintingSettingsSubPage));
   TestOpenChromePage(ChromePage::SEARCH,
                      base_url.Resolve(chrome::kSearchSubPage));
   TestOpenChromePage(ChromePage::SYNCSETUP,
diff --git a/chrome/browser/ui/ash/chrome_shelf_prefs.cc b/chrome/browser/ui/ash/chrome_shelf_prefs.cc
index 871f60de..31b9334d 100644
--- a/chrome/browser/ui/ash/chrome_shelf_prefs.cc
+++ b/chrome/browser/ui/ash/chrome_shelf_prefs.cc
@@ -27,9 +27,9 @@
 #include "chrome/browser/ui/ash/default_pinned_apps.h"
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller_util.h"
 #include "chrome/browser/ui/ash/shelf/shelf_controller_helper.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "components/crx_file/id_util.h"
diff --git a/chrome/browser/ui/ash/desk_template_app_launch_handler.cc b/chrome/browser/ui/ash/desk_template_app_launch_handler.cc
index b280ccb..5dc7145a 100644
--- a/chrome/browser/ui/ash/desk_template_app_launch_handler.cc
+++ b/chrome/browser/ui/ash/desk_template_app_launch_handler.cc
@@ -7,7 +7,11 @@
 #include <string>
 
 #include "base/notreached.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/browser/ui/browser_window.h"
 #include "components/full_restore/restore_data.h"
+#include "extensions/common/constants.h"
 
 DeskTemplateAppLaunchHandler::DeskTemplateAppLaunchHandler(Profile* profile)
     : chromeos::AppLaunchHandler(profile) {}
@@ -19,8 +23,10 @@
   // TODO(sammiequon) : Investigate if we can early return if a launch is
   // currently underway.
   restore_data_ = std::move(restore_data);
-  if (HasRestoreData())
+  if (HasRestoreData()) {
     LaunchApps();
+    LaunchBrowsers();
+  }
 }
 
 base::WeakPtr<chromeos::AppLaunchHandler>
@@ -28,9 +34,35 @@
   return weak_ptr_factory_.GetWeakPtr();
 }
 
-void DeskTemplateAppLaunchHandler::LaunchBrowser() {
-  // TODO: Launch browser with `restore_id`.
-  NOTIMPLEMENTED();
+void DeskTemplateAppLaunchHandler::LaunchBrowsers() {
+  DCHECK(restore_data_);
+
+  const auto& launch_list = restore_data_->app_id_to_launch_list();
+  for (const auto& iter : launch_list) {
+    if (iter.first != extension_misc::kChromeAppId)
+      continue;
+
+    for (const auto& window_iter : iter.second) {
+      absl::optional<std::vector<GURL>> urls = window_iter.second->urls;
+      if (!urls || urls->empty())
+        continue;
+
+      Browser::CreateParams create_params = Browser::CreateParams(
+          Browser::TYPE_NORMAL, profile_, /*user_gesture=*/false);
+      create_params.restore_id = window_iter.first;
+      Browser* browser = Browser::Create(create_params);
+
+      absl::optional<int32_t> active_tab_index =
+          window_iter.second->active_tab_index;
+      for (int i = 0; i < urls->size(); i++) {
+        chrome::AddTabAt(
+            browser, urls->at(i), /*index=*/-1,
+            /*foreground=*/(active_tab_index && i == *active_tab_index));
+      }
+
+      browser->window()->ShowInactive();
+    }
+  }
 }
 
 void DeskTemplateAppLaunchHandler::RecordRestoredAppLaunch(
diff --git a/chrome/browser/ui/ash/desk_template_app_launch_handler.h b/chrome/browser/ui/ash/desk_template_app_launch_handler.h
index eea3962..5e73827 100644
--- a/chrome/browser/ui/ash/desk_template_app_launch_handler.h
+++ b/chrome/browser/ui/ash/desk_template_app_launch_handler.h
@@ -39,8 +39,10 @@
       override;
 
  private:
+  // Go through the restore data launch list and launches the browser windows.
+  void LaunchBrowsers();
+
   // chromeos::AppLaunchHandler:
-  void LaunchBrowser() override;
   void RecordRestoredAppLaunch(apps::AppTypeName app_type_name) override;
 
   base::WeakPtrFactory<DeskTemplateAppLaunchHandler> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/ash/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks_client_browsertest.cc
index c020be8..685701e 100644
--- a/chrome/browser/ui/ash/desks_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks_client_browsertest.cc
@@ -48,18 +48,24 @@
 
 constexpr int32_t kSettingsWindowId = 100;
 
-constexpr char kExampleUrl1[] = "https://examples.com";
-constexpr char kExampleUrl2[] = "https://examples.com";
+constexpr char kExampleUrl1[] = "https://examples1.com";
+constexpr char kExampleUrl2[] = "https://examples2.com";
+constexpr char kExampleUrl3[] = "https://examples3.com";
 
-aura::Window* FindAppWindow(int32_t window_id) {
+Browser* FindBrowser(int32_t window_id) {
   for (auto* browser : *BrowserList::GetInstance()) {
     aura::Window* window = browser->window()->GetNativeWindow();
     if (window->GetProperty(full_restore::kRestoreWindowIdKey) == window_id)
-      return window;
+      return browser;
   }
   return nullptr;
 }
 
+aura::Window* FindAppWindow(int32_t window_id) {
+  Browser* browser = FindBrowser(window_id);
+  return browser ? browser->window()->GetNativeWindow() : nullptr;
+}
+
 std::vector<GURL> GetURLsForBrowserWindow(Browser* browser) {
   TabStripModel* tab_strip_model = browser->tab_strip_model();
   std::vector<GURL> urls;
@@ -547,3 +553,70 @@
                                          base::DoNothing());
   waiter.Wait();
 }
+
+// Tests that launching a template that contains a browser window works as
+// expected.
+IN_PROC_BROWSER_TEST_F(DesksClientTest, LaunchTemplateWithBrowserWindow) {
+  ASSERT_TRUE(DesksClient::Get());
+
+  // Create a new browser and add a few tabs to it.
+  Browser::CreateParams params(Browser::TYPE_NORMAL, browser()->profile(),
+                               /*user_gesture=*/false);
+  Browser* browser = Browser::Create(params);
+  chrome::AddTabAt(browser, GURL(kExampleUrl1), /*index=*/-1,
+                   /*foreground=*/false);
+  chrome::AddTabAt(browser, GURL(kExampleUrl2), /*index=*/-1,
+                   /*foreground=*/true);
+  chrome::AddTabAt(browser, GURL(kExampleUrl3), /*index=*/-1,
+                   /*foreground=*/false);
+  browser->window()->Show();
+  aura::Window* window = browser->window()->GetNativeWindow();
+
+  // Verify that the active tab is correct.
+  const int browser_active_index = browser->tab_strip_model()->active_index();
+  EXPECT_EQ(1, browser_active_index);
+
+  const int32_t browser_window_id =
+      window->GetProperty(full_restore::kWindowIdKey);
+  // Get current tabs from browser.
+  const std::vector<GURL> urls = GetURLsForBrowserWindow(browser);
+
+  base::RunLoop run_loop;
+  std::unique_ptr<ash::DeskTemplate> desk_template;
+  DesksClient::Get()->CaptureActiveDeskAndSaveTemplate(
+      base::BindLambdaForTesting(
+          [&](bool success,
+              std::unique_ptr<ash::DeskTemplate> captured_desk_template) {
+            run_loop.Quit();
+            ASSERT_TRUE(captured_desk_template);
+            desk_template = std::move(captured_desk_template);
+          }));
+  run_loop.Run();
+  ASSERT_TRUE(desk_template);
+
+  ash::DesksHelper* desks_helper = ash::DesksHelper::Get();
+  ASSERT_EQ(0, desks_helper->GetActiveDeskIndex());
+
+  // Set the template we created as the template we want to launch.
+  ash::DeskTemplate* desk_template_ptr = desk_template.get();
+  SetLaunchTemplate(std::move(desk_template));
+  ash::DeskSwitchAnimationWaiter waiter;
+  DesksClient::Get()->LaunchDeskTemplate(desk_template_ptr->uuid(),
+                                         base::DoNothing());
+  waiter.Wait();
+
+  // Verify that the browser was launched with the correct urls and active tab.
+  Browser* new_browser = FindBrowser(browser_window_id);
+  ASSERT_TRUE(new_browser);
+  EXPECT_EQ(urls, GetURLsForBrowserWindow(new_browser));
+  EXPECT_EQ(browser_active_index,
+            new_browser->tab_strip_model()->active_index());
+
+  // Verify that the browser window has been launched on the new desk (desk B).
+  EXPECT_EQ(1, desks_helper->GetActiveDeskIndex());
+  aura::Window* browser_window = new_browser->window()->GetNativeWindow();
+  ASSERT_TRUE(browser_window);
+  EXPECT_EQ(ash::Shell::GetContainer(browser_window->GetRootWindow(),
+                                     ash::kShellWindowId_DeskContainerB),
+            browser_window->parent());
+}
diff --git a/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller.cc b/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller.cc
index 77a10ea..4b6712b27 100644
--- a/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller.cc
+++ b/chrome/browser/ui/ash/shelf/app_shortcut_shelf_item_controller.cc
@@ -30,9 +30,9 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
@@ -120,8 +120,8 @@
              const URLPattern& refocus_pattern)
       : app_id_(app_id), refocus_pattern_(refocus_pattern) {
     DCHECK(profile);
-    if (web_app::WebAppProviderBase* provider =
-            web_app::WebAppProviderBase::GetProviderBase(profile)) {
+    if (web_app::WebAppProvider* provider =
+            web_app::WebAppProvider::GetForWebApps(profile)) {
       if (provider->registrar().IsLocallyInstalled(app_id)) {
         registrar_ = &provider->registrar();
       }
@@ -220,7 +220,7 @@
   // AppMatcher is stack allocated. Pointer members below are not owned.
 
   // registrar_ is set when app_id_ is a web app.
-  const web_app::AppRegistrar* registrar_ = nullptr;
+  const web_app::WebAppRegistrar* registrar_ = nullptr;
 
   // extension_ is set when app_id_ is a hosted app.
   const Extension* extension_ = nullptr;
@@ -563,10 +563,10 @@
 }
 
 bool AppShortcutShelfItemController::IsWindowedWebApp() {
-  if (web_app::WebAppProviderBase* provider =
-          web_app::WebAppProviderBase::GetProviderBase(
+  if (web_app::WebAppProvider* provider =
+          web_app::WebAppProvider::GetForWebApps(
               ChromeShelfController::instance()->profile())) {
-    web_app::AppRegistrar& registrar = provider->registrar();
+    web_app::WebAppRegistrar& registrar = provider->registrar();
     if (registrar.IsLocallyInstalled(app_id())) {
       return registrar.GetAppUserDisplayMode(app_id()) !=
              web_app::DisplayMode::kBrowser;
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
index 2ef177b7..49e0c29 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
@@ -83,7 +83,6 @@
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
@@ -134,7 +133,7 @@
 using ::content::WebContents;
 using ::extensions::AppWindow;
 using ::extensions::Extension;
-using ::web_app::WebAppProviderBase;
+using ::web_app::WebAppProvider;
 
 ash::ShelfAction SelectItem(
     const ash::ShelfID& id,
@@ -2386,8 +2385,8 @@
   // Set both apps to open in windows.
   extensions::SetLaunchType(browser()->profile(), hosted_app->id(),
                             extensions::LAUNCH_TYPE_WINDOW);
-  WebAppProviderBase* provider =
-      WebAppProviderBase::GetProviderBase(browser()->profile());
+  WebAppProvider* provider =
+      WebAppProvider::GetForWebApps(browser()->profile());
   DCHECK(provider);
   provider->registry_controller().SetAppUserDisplayMode(
       web_app_id, web_app::DisplayMode::kStandalone, /*is_user_action=*/false);
diff --git a/chrome/browser/ui/ash/shelf/shelf_context_menu_unittest.cc b/chrome/browser/ui/ash/shelf/shelf_context_menu_unittest.cc
index 797d3c3..e2750f3 100644
--- a/chrome/browser/ui/ash/shelf/shelf_context_menu_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/shelf_context_menu_unittest.cc
@@ -40,10 +40,10 @@
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h"
 #include "chrome/browser/ui/ash/shelf/extension_shelf_context_menu.h"
 #include "chrome/browser/ui/ash/shelf/shelf_controller_helper.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h"
 #include "chrome/browser/web_applications/test/test_web_app_provider.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/chrome_ash_test_base.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/ui/ash/shelf/shelf_controller_helper.cc b/chrome/browser/ui/ash/shelf/shelf_controller_helper.cc
index d486921..57501e05 100644
--- a/chrome/browser/ui/ash/shelf/shelf_controller_helper.cc
+++ b/chrome/browser/ui/ash/shelf/shelf_controller_helper.cc
@@ -31,11 +31,11 @@
 #include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "chrome/browser/ui/extensions/extension_enable_flow.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/extensions/bookmark_app_util.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "components/arc/arc_util.h"
 #include "components/arc/metrics/arc_metrics_constants.h"
@@ -79,8 +79,8 @@
 
 absl::optional<std::string> GetAppIdForTab(Profile* profile,
                                            content::WebContents* tab) {
-  if (web_app::WebAppProviderBase* provider =
-          web_app::WebAppProviderBase::GetProviderBase(profile)) {
+  if (web_app::WebAppProvider* provider =
+          web_app::WebAppProvider::GetForWebApps(profile)) {
     // Use the Browser's app name to determine the web app for app windows and
     // use the tab's url for app tabs.
 
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index c3302e57..927a9d6c 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -78,10 +78,10 @@
 #include "chrome/browser/ui/user_education/reopen_tab_in_product_help_factory.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/upgrade_detector/upgrade_detector.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/content_restriction.h"
@@ -661,7 +661,7 @@
 
     auto launch_container =
         apps::mojom::LaunchContainer::kLaunchContainerWindow;
-    if (web_app::WebAppProviderBase::GetProviderBase(profile)
+    if (web_app::WebAppProvider::GetForWebApps(profile)
             ->registrar()
             .GetAppEffectiveDisplayMode(app_id) ==
         blink::mojom::DisplayMode::kBrowser) {
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index f8a5367..f364f26 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -40,17 +40,17 @@
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_menu_model.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -306,8 +306,8 @@
     EXPECT_EQ(target_url, new_tab->GetLastCommittedURL());
   }
 
-  web_app::AppRegistrar& registrar() {
-    auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile());
+  web_app::WebAppRegistrar& registrar() {
+    auto* provider = web_app::WebAppProvider::GetForWebApps(profile());
     CHECK(provider);
     return provider->registrar();
   }
diff --git a/chrome/browser/ui/omnibox/omnibox_theme.cc b/chrome/browser/ui/omnibox/omnibox_theme.cc
index e2df47a..5909e782 100644
--- a/chrome/browser/ui/omnibox/omnibox_theme.cc
+++ b/chrome/browser/ui/omnibox/omnibox_theme.cc
@@ -20,8 +20,8 @@
   switch (part) {
     case OmniboxPart::LOCATION_BAR_BACKGROUND:
       return state == OmniboxPartState::HOVERED
-                 ? TP::COLOR_OMNIBOX_BACKGROUND_HOVERED
-                 : TP::COLOR_OMNIBOX_BACKGROUND;
+                 ? static_cast<int>(TP::COLOR_OMNIBOX_BACKGROUND_HOVERED)
+                 : static_cast<int>(TP::COLOR_OMNIBOX_BACKGROUND);
     case OmniboxPart::LOCATION_BAR_SELECTED_KEYWORD:
       return TP::COLOR_OMNIBOX_SELECTED_KEYWORD;
     case OmniboxPart::RESULTS_BACKGROUND:
@@ -40,8 +40,9 @@
     case OmniboxPart::LOCATION_BAR_TEXT_DEFAULT:
       return TP::COLOR_OMNIBOX_TEXT;
     case OmniboxPart::RESULTS_TEXT_DEFAULT:
-      return selected ? TP::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED
-                      : TP::COLOR_OMNIBOX_TEXT;
+      return selected
+                 ? static_cast<int>(TP::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED)
+                 : static_cast<int>(TP::COLOR_OMNIBOX_TEXT);
     case OmniboxPart::LOCATION_BAR_TEXT_DIMMED:
       return TP::COLOR_OMNIBOX_TEXT_DIMMED;
     case OmniboxPart::RESULTS_TEXT_DIMMED:
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index 85345ba..52ac050f7 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -112,7 +112,6 @@
 #include "components/policy/core/common/policy_types.h"
 
 #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
@@ -1500,8 +1499,8 @@
 
   // Install a web app that we will launch from the command line in
   // the PRE test.
-  web_app::WebAppProviderBase* const provider =
-      web_app::WebAppProviderBase::GetProviderBase(browser()->profile());
+  web_app::WebAppProvider* const provider =
+      web_app::WebAppProvider::GetForWebApps(browser()->profile());
   web_app::InstallFinalizer& web_app_finalizer = provider->install_finalizer();
 
   web_app::InstallFinalizer::FinalizeOptions options;
@@ -2173,8 +2172,8 @@
     InProcessBrowserTest::SetUpOnMainThread();
   }
 
-  web_app::WebAppProviderBase* provider() {
-    return web_app::WebAppProviderBase::GetProviderBase(browser()->profile());
+  web_app::WebAppProvider* provider() {
+    return web_app::WebAppProvider::GetForWebApps(browser()->profile());
   }
 
   // Install a web app with protocol_handlers then register it with the
@@ -2271,7 +2270,7 @@
 
   // Check that we added this protocol to web app's approved_launch_protocols
   // on accept.
-  web_app::AppRegistrar& registrar = provider()->registrar();
+  web_app::WebAppRegistrar& registrar = provider()->registrar();
   EXPECT_TRUE(registrar.IsApprovedLaunchProtocol(app_id, "web+test"));
 
   // Check for new app window.
@@ -2343,7 +2342,7 @@
 
   // Check that we added this protocol to web app's approved_launch_protocols
   // on accept.
-  web_app::AppRegistrar& registrar = provider()->registrar();
+  web_app::WebAppRegistrar& registrar = provider()->registrar();
   EXPECT_TRUE(registrar.IsApprovedLaunchProtocol(app_id, "web+test"));
 
   // Check the first app window is created.
diff --git a/chrome/browser/ui/startup/web_app_protocol_handling_startup_utils.cc b/chrome/browser/ui/startup/web_app_protocol_handling_startup_utils.cc
index 2d3a210..34f3734 100644
--- a/chrome/browser/ui/startup/web_app_protocol_handling_startup_utils.cc
+++ b/chrome/browser/ui/startup/web_app_protocol_handling_startup_utils.cc
@@ -24,7 +24,6 @@
 #include "chrome/browser/profiles/scoped_profile_keep_alive.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
@@ -86,8 +85,8 @@
          web_app::startup::FinalizeWebAppLaunchCallback callback,
          bool accepted) {
         if (accepted) {
-          web_app::WebAppProviderBase* provider =
-              web_app::WebAppProviderBase::GetProviderBase(profile);
+          web_app::WebAppProvider* provider =
+              web_app::WebAppProvider::GetForWebApps(profile);
           {
             web_app::ScopedRegistryUpdate update(
                 provider->registry_controller().AsWebAppSyncBridge());
@@ -109,7 +108,7 @@
       std::move(finalize_callback));
 
   // Check if we have permission to launch the app directly.
-  web_app::AppRegistrar& registrar = provider->registrar();
+  web_app::WebAppRegistrar& registrar = provider->registrar();
   if (registrar.IsApprovedLaunchProtocol(app_id, protocol_url.scheme())) {
     std::move(launch_callback).Run(true);
   } else {
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index f6bfdad..a20ddc8 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -56,7 +56,6 @@
 #include "chrome/browser/profiles/profile_key.h"
 #include "chrome/browser/reputation/reputation_web_contents_observer.h"
 #include "chrome/browser/resource_coordinator/tab_helper.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/safe_browsing_tab_observer.h"
@@ -111,6 +110,7 @@
 #include "components/performance_manager/public/performance_manager.h"
 #include "components/permissions/features.h"
 #include "components/permissions/permission_request_manager.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
 #include "components/site_engagement/content/site_engagement_service.h"
 #include "components/sync/engine/sync_engine_switches.h"
 #include "components/tracing/common/tracing_switches.h"
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index 9508f32..ff292c7 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -1016,6 +1016,11 @@
     group = GetTabGroupForTab(index);
   }
 
+  // Pinned tabs cannot be added to a group.
+  if (add_types & ADD_PINNED) {
+    group = absl::nullopt;
+  }
+
   if (ui::PageTransitionTypeIncludingQualifiersIs(transition,
                                                   ui::PAGE_TRANSITION_TYPED) &&
       index == count()) {
diff --git a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
index 0042862..ab4964b 100644
--- a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
@@ -263,7 +263,7 @@
     ListPrefUpdate update(TestingBrowserProcess::GetGlobal()->local_state(),
                           policy::policy_prefs::kSystemFeaturesDisableList);
     base::ListValue* list = update.Get();
-    list->Clear();
+    list->ClearList();
   }
   EXPECT_TRUE(model.IsEnabledAt(options_index));
 
diff --git a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view_browsertest.cc b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view_browsertest.cc
index 425d438..e72d80e 100644
--- a/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view_browsertest.cc
@@ -19,10 +19,10 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/arc/test/arc_util_test_support.h"
@@ -181,7 +181,7 @@
     navigation_observer.WaitForNavigationFinished();
 
     auto* provider =
-        web_app::WebAppProviderBase::GetProviderBase(browser()->profile());
+        web_app::WebAppProvider::GetForWebApps(browser()->profile());
     DCHECK(provider);
     app_name_ = provider->registrar().GetAppShortName(app_id_);
   }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
index 78decab..77bb5dd 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
@@ -6,7 +6,6 @@
 
 #include <algorithm>
 
-#include "base/containers/cxx20_erase.h"
 #include "base/metrics/user_metrics.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -425,24 +424,6 @@
   return !should_leave_to_top_container;
 }
 
-views::View::Views BrowserNonClientFrameViewChromeOS::GetChildrenInZOrder() {
-  views::View::Views paint_order =
-      BrowserNonClientFrameView::GetChildrenInZOrder();
-  views::ClientView* client_view =
-      GetWidget() ? GetWidget()->client_view() : nullptr;
-
-  // Move the client view in front of the frame animator view added by the frame
-  // header helper, if present. This allows the frame animator view to still be
-  // at the bottom of the z-order while also keeping the rest of the frame
-  // view's children on top of the client view.
-  if (frame()->ShouldDrawFrameHeader() && client_view &&
-      base::Erase(paint_order, client_view)) {
-    paint_order.insert(std::next(paint_order.begin(), 1), client_view);
-  }
-
-  return paint_order;
-}
-
 SkColor BrowserNonClientFrameViewChromeOS::GetTitleColor() {
   return browser_view()->GetRegularOrGuestSession()
              ? kNormalWindowTitleTextColor
@@ -603,20 +584,12 @@
 }
 
 void BrowserNonClientFrameViewChromeOS::OnImmersiveRevealEnded() {
-  AddChildViewAt(caption_button_container_, 0);
-
-  if (web_app_frame_toolbar()) {
-    views::ClientView* client_view =
-        GetWidget() ? GetWidget()->client_view() : nullptr;
-
-    // Add the web app frame toolbar at the end, but before the client view if
-    // it exists.
-    if (client_view && GetIndexOf(client_view) >= 0) {
-      AddChildViewAt(web_app_frame_toolbar(), GetIndexOf(client_view));
-    } else {
-      AddChildView(web_app_frame_toolbar());
-    }
-  }
+  // Ensure the WebAppFrameToolbarView and FrameCaptionButtonContainerView
+  // receive events before the BrowserView by appending instead of inserting
+  // the child views.
+  if (web_app_frame_toolbar())
+    AddChildView(web_app_frame_toolbar());
+  AddChildView(caption_button_container_);
   Layout();
 }
 
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
index b80e172..f7772e5 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
@@ -81,7 +81,6 @@
   void ChildPreferredSizeChanged(views::View* child) override;
   bool DoesIntersectRect(const views::View* target,
                          const gfx::Rect& rect) const override;
-  views::View::Views GetChildrenInZOrder() override;
 
   // BrowserFrameHeaderChromeOS::AppearanceProvider:
   SkColor GetTitleColor() override;
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc
index 1100e1cb..be5f6481 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -328,7 +328,7 @@
     case AvatarSyncErrorType::kTrustedVaultKeyMissingForEverythingError:
     case AvatarSyncErrorType::kTrustedVaultKeyMissingForPasswordsError:
       OpenTabForSyncKeyRetrieval(
-          browser(), syncer::KeyRetrievalTriggerForUMA::kProfileMenu);
+          browser(), syncer::TrustedVaultUserActionTriggerForUMA::kProfileMenu);
       break;
     case AvatarSyncErrorType::
         kTrustedVaultRecoverabilityDegradedForEverythingError:
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_navigation_button_container.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_navigation_button_container.cc
index c51f67a..63ceae1 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_navigation_button_container.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_navigation_button_container.cc
@@ -34,7 +34,7 @@
 
 constexpr int kPaddingBetweenNavigationButtons = 5;
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 constexpr int kWebAppFrameLeftMargin = 2;
 #else
 constexpr int kWebAppFrameLeftMargin = 7;
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc
index db47134..97527ee 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.cc
@@ -35,7 +35,6 @@
 #include "chrome/browser/web_applications/components/policy/web_app_policy_constants.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/manifest_update_manager.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
@@ -639,7 +638,7 @@
       << "No app installed for scope: " << action_param;
   auto app_id = app_state->id;
   auto* web_app_provider = GetProvider();
-  AppRegistrar& app_registrar = web_app_provider->registrar();
+  WebAppRegistrar& app_registrar = web_app_provider->registrar();
   DisplayMode display_mode = app_registrar.GetAppEffectiveDisplayMode(app_id);
   if (display_mode == blink::mojom::DisplayMode::kBrowser) {
     ui_test_utils::UrlLoadObserver url_observer(
@@ -760,8 +759,7 @@
   ASSERT_TRUE(app_state.has_value())
       << "No app installed for scope: " << action_param;
   auto app_id = app_state->id;
-  WebAppProviderBase* const provider =
-      WebAppProviderBase::GetProviderBase(profile());
+  WebAppProvider* const provider = WebAppProvider::GetForWebApps(profile());
   base::RunLoop run_loop;
 
   DCHECK(provider->install_finalizer().CanUserUninstallWebApp(app_id));
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.h b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.h
index 2804f42..96e6bb1 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.h
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_base.h
@@ -217,12 +217,13 @@
   WebAppProvider* GetProviderForProfile(Profile* profile);
 
   // Allow test-driving classes to reset the ScopedObservation of the
-  // AppRegistrar at the end of each test, but before the tear down sequence
+  // WebAppRegistrar at the end of each test, but before the tear down sequence
   // begins.
   void ResetRegistrarObserver();
 
  private:
-  base::ScopedObservation<web_app::AppRegistrar, web_app::AppRegistrarObserver>
+  base::ScopedObservation<web_app::WebAppRegistrar,
+                          web_app::AppRegistrarObserver>
       observation_{this};
 
   StateSnapshot ConstructStateSnapshot();
diff --git a/chrome/browser/ui/views/web_apps/web_app_protocol_handler_intent_picker_dialog_view.cc b/chrome/browser/ui/views/web_apps/web_app_protocol_handler_intent_picker_dialog_view.cc
index 8af6889..43e05f5 100644
--- a/chrome/browser/ui/views/web_apps/web_app_protocol_handler_intent_picker_dialog_view.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_protocol_handler_intent_picker_dialog_view.cc
@@ -19,10 +19,10 @@
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/web_apps/web_app_hover_button.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/keep_alive_registry/scoped_keep_alive.h"
@@ -153,7 +153,7 @@
       views::BoxLayout::Orientation::kVertical));
 
   web_app::WebAppProvider* provider = web_app::WebAppProvider::Get(profile_);
-  web_app::AppRegistrar& registrar = provider->registrar();
+  web_app::WebAppRegistrar& registrar = provider->registrar();
   auto app_button = std::make_unique<WebAppHoverButton>(
       views::Button::PressedCallback(), app_id_, provider,
       base::UTF8ToUTF16(registrar.GetAppShortName(app_id_)),
diff --git a/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc
index 6ca87b36..ac4755ee 100644
--- a/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_tab_strip_browsertest.cc
@@ -15,13 +15,12 @@
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/web_contents.h"
@@ -83,7 +82,7 @@
         TabActive::kActive, BrowserFrameActiveState::kActive);
   }
 
-  AppRegistrar& registrar() {
+  WebAppRegistrar& registrar() {
     return WebAppProvider::Get(browser()->profile())->registrar();
   }
 
diff --git a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.h b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.h
index 3014d07..4517e98 100644
--- a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.h
+++ b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.h
@@ -13,9 +13,9 @@
 #include "base/scoped_observation.h"
 #include "base/threading/thread_checker.h"
 #include "chrome/browser/ui/web_applications/web_app_uninstall_dialog.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/gfx/image/image_skia.h"
@@ -130,7 +130,8 @@
   // Tracks whether |parent_| got destroyed.
   std::unique_ptr<NativeWindowTracker> parent_window_tracker_;
 
-  base::ScopedObservation<web_app::AppRegistrar, web_app::AppRegistrarObserver>
+  base::ScopedObservation<web_app::WebAppRegistrar,
+                          web_app::AppRegistrarObserver>
       registrar_observation_{this};
 
   WebAppUninstallDialogDelegateView* view_ = nullptr;
diff --git a/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.cc b/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.cc
index 5d99dad0..b7b60ef 100644
--- a/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_url_handler_intent_picker_dialog_view.cc
@@ -30,10 +30,10 @@
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/web_apps/web_app_url_handler_hover_button.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/url_handler_launch_params.h"
 #include "chrome/browser/web_applications/components/url_handler_prefs.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/keep_alive_registry/scoped_keep_alive.h"
@@ -266,7 +266,7 @@
     Profile* profile = g_browser_process->profile_manager()->GetProfileByPath(
         launch_params.profile_path);
     provider = web_app::WebAppProvider::Get(profile);
-    web_app::AppRegistrar& registrar = provider->registrar();
+    web_app::WebAppRegistrar& registrar = provider->registrar();
 
     const std::u16string& profile_name =
         profiles::GetAvatarNameForProfile(launch_params.profile_path);
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc
index 2e3dab1..d86324b 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.cc
+++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -22,10 +22,10 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_browser_controller.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/themes/autogenerated_theme_util.h"
 #include "chrome/grit/generated_resources.h"
@@ -163,20 +163,20 @@
       browser_(browser),
       theme_provider_(
           ThemeService::CreateBoundThemeProvider(browser_->profile(), this)),
-      system_app_type_(HasAppId() ? WebAppProvider::Get(browser->profile())
-                                        ->system_web_app_manager()
-                                        .GetSystemAppTypeForAppId(GetAppId())
-                                  : absl::nullopt),
+      system_app_type_(
+          HasAppId()
+              ? GetSystemWebAppTypeForAppId(browser_->profile(), GetAppId())
+              : absl::nullopt),
+      provider_(system_app_type_
+                    ? WebAppProvider::GetForSystemWebApps(browser_->profile())
+                    : WebAppProvider::GetForWebApps(browser_->profile())),
       has_tab_strip_(
-          (system_app_type_.has_value() &&
-           WebAppProvider::Get(browser->profile())
-               ->system_web_app_manager()
-               .ShouldHaveTabStrip(system_app_type_.value())) ||
+          (system_app_type_ &&
+           provider_->system_web_app_manager().ShouldHaveTabStrip(
+               system_app_type_.value())) ||
           (base::FeatureList::IsEnabled(features::kDesktopPWAsTabStrip) &&
            HasAppId() &&
-           WebAppProvider::Get(browser->profile())
-               ->registrar()
-               .IsTabbedWindowModeEnabled(GetAppId()))) {
+           provider_->registrar().IsTabbedWindowModeEnabled(GetAppId()))) {
   browser->tab_strip_model()->AddObserver(this);
 }
 
@@ -332,9 +332,8 @@
   if (!system_app_type_)
     return true;
 
-  return WebAppProvider::Get(browser()->profile())
-      ->system_web_app_manager()
-      .ShouldHaveReloadButtonInMinimalUi(system_app_type_.value());
+  return provider_->system_web_app_manager().ShouldHaveReloadButtonInMinimalUi(
+      system_app_type_.value());
 }
 
 std::u16string AppBrowserController::GetLaunchFlashText() const {
@@ -370,9 +369,8 @@
 
 gfx::Rect AppBrowserController::GetDefaultBounds() const {
   if (system_app_type_.has_value()) {
-    return WebAppProvider::Get(browser()->profile())
-        ->system_web_app_manager()
-        .GetDefaultBounds(system_app_type_.value(), browser());
+    return provider_->system_web_app_manager().GetDefaultBounds(
+        system_app_type_.value(), browser());
   }
 
   return gfx::Rect();
@@ -468,9 +466,7 @@
     return raw_title;
 
   std::u16string app_name =
-      base::UTF8ToUTF16(WebAppProvider::Get(browser()->profile())
-                            ->registrar()
-                            .GetAppShortName(GetAppId()));
+      base::UTF8ToUTF16(provider_->registrar().GetAppShortName(GetAppId()));
   if (base::StartsWith(raw_title, app_name)) {
     return raw_title;
   } else if (raw_title.empty()) {
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.h b/chrome/browser/ui/web_applications/app_browser_controller.h
index db50a9f..bf415c18 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.h
+++ b/chrome/browser/ui/web_applications/app_browser_controller.h
@@ -36,6 +36,7 @@
 namespace web_app {
 
 class WebAppBrowserController;
+class WebAppProvider;
 enum class SystemAppType;
 
 // Returns true if |app_url| and |page_url| are the same origin. To avoid
@@ -245,6 +246,7 @@
   absl::optional<SkColor> last_background_color_;
 
   absl::optional<SystemAppType> system_app_type_;
+  WebAppProvider* provider_;
 
   const bool has_tab_strip_;
 
diff --git a/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc b/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc
index 817ba82..6668d122 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc
+++ b/chrome/browser/ui/web_applications/app_browser_controller_browsertest.cc
@@ -92,7 +92,11 @@
  public:
   AppBrowserControllerBrowserTest()
       : test_system_web_app_installation_(
-            TestSystemWebAppInstallation::SetUpTabbedMultiWindowApp()) {}
+            TestSystemWebAppInstallation::SetUpTabbedMultiWindowApp()) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+    WebAppProvider::EnableSystemWebAppsInLacrosForTesting();
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+  }
   AppBrowserControllerBrowserTest(const AppBrowserControllerBrowserTest&) =
       delete;
   AppBrowserControllerBrowserTest& operator=(
diff --git a/chrome/browser/ui/web_applications/create_shortcut_browsertest.cc b/chrome/browser/ui/web_applications/create_shortcut_browsertest.cc
index 3108c6d..9ce20c6a 100644
--- a/chrome/browser/ui/web_applications/create_shortcut_browsertest.cc
+++ b/chrome/browser/ui/web_applications/create_shortcut_browsertest.cc
@@ -17,13 +17,13 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/components/web_app_prefs_utils.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_paths.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
 #include "content/public/test/browser_test.h"
@@ -56,14 +56,14 @@
     return app_id;
   }
 
-  AppRegistrar& registrar() {
-    auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  WebAppRegistrar& registrar() {
+    auto* provider = WebAppProvider::GetForWebApps(profile());
     CHECK(provider);
     return provider->registrar();
   }
 
   AppRegistryController& registry_controller() {
-    auto* provider = WebAppProviderBase::GetProviderBase(profile());
+    auto* provider = WebAppProvider::GetForWebApps(profile());
     CHECK(provider);
     return provider->registry_controller();
   }
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
index 17a14948..ce2b05f5 100644
--- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
+++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
@@ -27,11 +27,11 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_launch/web_launch_files_helper.h"
 #include "chrome/common/webui_url_constants.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
index 9e56725..e61ae08 100644
--- a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
+++ b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
@@ -28,17 +28,16 @@
 #include "chrome/browser/ui/toolbar/app_menu_model.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/externally_managed_app_manager.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/service_worker_registration_waiter.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
@@ -185,7 +184,7 @@
 // Launches the app, waits for the app url to load.
 Browser* LaunchWebAppBrowserAndWait(Profile* profile, const AppId& app_id) {
   ui_test_utils::UrlLoadObserver url_observer(
-      WebAppProviderBase::GetProviderBase(profile)->registrar().GetAppLaunchUrl(
+      WebAppProvider::GetForWebApps(profile)->registrar().GetAppLaunchUrl(
           app_id),
       content::NotificationService::AllSources());
   Browser* const app_browser = LaunchWebAppBrowser(profile, app_id);
@@ -336,7 +335,7 @@
 }
 
 void UninstallWebApp(Profile* profile, const AppId& app_id) {
-  auto* provider = WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = WebAppProvider::GetForWebApps(profile);
   DCHECK(provider);
   DCHECK(provider->install_finalizer().CanUserUninstallWebApp(app_id));
   provider->install_finalizer().UninstallWebApp(
@@ -346,7 +345,7 @@
 void UninstallWebAppWithCallback(Profile* profile,
                                  const AppId& app_id,
                                  UninstallWebAppCallback callback) {
-  auto* provider = WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = WebAppProvider::GetForWebApps(profile);
   DCHECK(provider);
   DCHECK(provider->install_finalizer().CanUserUninstallWebApp(app_id));
   provider->install_finalizer().UninstallWebApp(
@@ -360,7 +359,7 @@
                          int y) {
   SkColor result;
   base::RunLoop run_loop;
-  WebAppProviderBase::GetProviderBase(profile)->icon_manager().ReadIcons(
+  WebAppProvider::GetForWebApps(profile)->icon_manager().ReadIcons(
       app_id, IconPurpose::ANY, {size},
       base::BindLambdaForTesting(
           [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) {
diff --git a/chrome/browser/ui/web_applications/web_app_badging_browsertest.cc b/chrome/browser/ui/web_applications/web_app_badging_browsertest.cc
index 98177adc..123ac2e 100644
--- a/chrome/browser/ui/web_applications/web_app_badging_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_badging_browsertest.cc
@@ -9,8 +9,8 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.cc b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
index 748f7b7..9f5e92d3 100644
--- a/chrome/browser/ui/web_applications/web_app_browser_controller.cc
+++ b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
@@ -253,7 +253,7 @@
   web_app::ClearAppPrefsForWebContents(contents);
 }
 
-const AppRegistrar& WebAppBrowserController::registrar() const {
+const WebAppRegistrar& WebAppBrowserController::registrar() const {
   return provider_.registrar();
 }
 
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.h b/chrome/browser/ui/web_applications/web_app_browser_controller.h
index e25cc93..81f83cbe 100644
--- a/chrome/browser/ui/web_applications/web_app_browser_controller.h
+++ b/chrome/browser/ui/web_applications/web_app_browser_controller.h
@@ -13,9 +13,9 @@
 #include "base/scoped_observation.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/services/app_service/public/mojom/types.mojom-forward.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -34,12 +34,12 @@
 
 namespace web_app {
 
-class AppRegistrar;
+class WebAppRegistrar;
 class WebAppProvider;
 
 // Class to encapsulate logic to control the browser UI for
 // web apps.
-// App information is obtained from the AppRegistrar.
+// App information is obtained from the WebAppRegistrar.
 // Icon information is obtained from the AppIconManager.
 // Note: Much of the functionality in HostedAppBrowserController
 // will move to this class.
@@ -88,7 +88,7 @@
   void OnTabRemoved(content::WebContents* contents) override;
 
  private:
-  const AppRegistrar& registrar() const;
+  const WebAppRegistrar& registrar() const;
 
   // Helper function to call AppServiceProxy to load icon.
   void LoadAppIcon(bool allow_placeholder_icon) const;
@@ -115,7 +115,7 @@
       asset_link_handler_;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-  base::ScopedObservation<AppRegistrar, AppRegistrarObserver>
+  base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver>
       registrar_observation_{this};
 
   base::OnceClosure callback_for_testing_;
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc
index 5f47d4e..35772230 100644
--- a/chrome/browser/ui/web_applications/web_app_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -49,14 +49,12 @@
 #include "chrome/browser/ui/web_applications/web_app_launch_manager.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_menu_model.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
 #include "chrome/browser/web_applications/web_app.h"
@@ -253,7 +251,7 @@
                                         web_app_info.get());
   AppId app_id = InstallWebApp(std::move(web_app_info));
 
-  auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  auto* provider = WebAppProvider::GetForWebApps(profile());
   EXPECT_EQ(provider->registrar().GetAppBackgroundColor(app_id), SK_ColorBLUE);
 }
 
@@ -361,7 +359,7 @@
 IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, AppLastLaunchTime) {
   const GURL app_url(kExampleURL);
   const AppId app_id = InstallPWA(app_url);
-  auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  auto* provider = WebAppProvider::GetForWebApps(profile());
 
   // last_launch_time is not set before launch
   EXPECT_TRUE(provider->registrar().GetAppLastLaunchTime(app_id).is_null());
@@ -735,7 +733,7 @@
   int index = -1;
   const bool found = app_menu_model->GetModelAndIndexForCommandId(
       WebAppMenuModel::kUninstallAppCommandId, &model, &index);
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
   EXPECT_FALSE(found);
 #else
   EXPECT_TRUE(found);
@@ -748,7 +746,7 @@
                             MENU_ACTION_UNINSTALL_APP, 1);
   tester.ExpectUniqueSample("WrenchMenu.MenuAction", MENU_ACTION_UNINSTALL_APP,
                             1);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // defined(OS_CHROMEOS)
 }
 
 // Tests that both installing a PWA and creating a shortcut app are disabled for
@@ -835,7 +833,7 @@
   NavigateToURLAndWait(browser(), GetInstallableAppURL());
 
   const AppId app_id = InstallPwaForCurrentUrl();
-  auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  auto* provider = WebAppProvider::GetForWebApps(profile());
   EXPECT_EQ(provider->registrar().GetAppShortName(app_id),
             GetInstallableAppName());
 
@@ -861,7 +859,7 @@
   const AppId app_id = InstallPwaForCurrentUrl();
 
   // Change display mode to open in tab.
-  auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  auto* provider = WebAppProvider::GetForWebApps(profile());
   provider->registry_controller().SetAppUserDisplayMode(
       app_id, blink::mojom::DisplayMode::kBrowser, /*is_user_action=*/false);
 
@@ -970,7 +968,7 @@
 #endif
   SetShortcutOverrideForTesting(shortcut_override);
 
-  auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  auto* provider = WebAppProvider::GetForWebApps(profile());
 
   NavigateToURLAndWait(browser(), GetInstallableAppURL());
 
@@ -1303,7 +1301,7 @@
   EXPECT_TRUE(new_browser->is_type_app());
   EXPECT_EQ(new_browser->app_controller()->GetAppId(), app_id);
 
-  WebAppProviderBase::GetProviderBase(profile())
+  WebAppProvider::GetForWebApps(profile())
       ->registry_controller()
       .SetAppUserDisplayMode(app_id, DisplayMode::kBrowser,
                              /*is_user_action=*/false);
@@ -1467,7 +1465,7 @@
   NavigateToURLAndWait(browser(), GetInstallableAppURL());
 
   const AppId app_id = InstallPwaForCurrentUrl();
-  auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  auto* provider = WebAppProvider::GetForWebApps(profile());
   auto* app = provider->registrar().AsWebAppRegistrar()->GetAppById(app_id);
 
   EXPECT_EQ(
@@ -1486,7 +1484,7 @@
           "/banners/manifest_test_page.html?manifest=manifest_with_id.json"));
 
   const AppId app_id = InstallPwaForCurrentUrl();
-  auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  auto* provider = WebAppProvider::GetForWebApps(profile());
   auto* app = provider->registrar().AsWebAppRegistrar()->GetAppById(app_id);
 
   EXPECT_EQ(web_app::GenerateAppId(app->manifest_id(), app->start_url()),
diff --git a/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc b/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc
index 3813b88a..3de789c 100644
--- a/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_controller_browsertest.cc
@@ -35,8 +35,8 @@
 
 WebAppControllerBrowserTestBase::~WebAppControllerBrowserTestBase() = default;
 
-WebAppProviderBase& WebAppControllerBrowserTestBase::provider() {
-  auto* provider = WebAppProviderBase::GetProviderBase(profile());
+WebAppProvider& WebAppControllerBrowserTestBase::provider() {
+  auto* provider = WebAppProvider::GetForWebApps(profile());
   DCHECK(provider);
   return *provider;
 }
diff --git a/chrome/browser/ui/web_applications/web_app_controller_browsertest.h b/chrome/browser/ui/web_applications/web_app_controller_browsertest.h
index d28f95c..8e3353d 100644
--- a/chrome/browser/ui/web_applications/web_app_controller_browsertest.h
+++ b/chrome/browser/ui/web_applications/web_app_controller_browsertest.h
@@ -27,7 +27,7 @@
 
 namespace web_app {
 
-class WebAppProviderBase;
+class WebAppProvider;
 
 // Base class for tests of user interface support for web applications.
 class WebAppControllerBrowserTestBase : public InProcessBrowserTest {
@@ -39,7 +39,7 @@
       const WebAppControllerBrowserTestBase&) = delete;
   ~WebAppControllerBrowserTestBase() override = 0;
 
-  WebAppProviderBase& provider();
+  WebAppProvider& provider();
 
   Profile* profile();
 
diff --git a/chrome/browser/ui/web_applications/web_app_file_handling_browsertest.cc b/chrome/browser/ui/web_applications/web_app_file_handling_browsertest.cc
index 17936ac1..3c0a158 100644
--- a/chrome/browser/ui/web_applications/web_app_file_handling_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_file_handling_browsertest.cc
@@ -30,7 +30,6 @@
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_prefs_utils.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
@@ -107,8 +106,8 @@
 
 class WebAppFileHandlingTestBase : public WebAppControllerBrowserTest {
  public:
-  WebAppProviderBase* provider() {
-    return WebAppProviderBase::GetProviderBase(profile());
+  WebAppProvider* provider() {
+    return WebAppProvider::GetForWebApps(profile());
   }
 
   FileHandlerManager& file_handler_manager() {
@@ -117,7 +116,7 @@
         .file_handler_manager_for_testing();
   }
 
-  AppRegistrar& registrar() { return provider()->registrar(); }
+  WebAppRegistrar& registrar() { return provider()->registrar(); }
 
   GURL GetSecureAppURL() {
     return https_server()->GetURL("app.com", "/ssl/google.html");
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.h b/chrome/browser/ui/web_applications/web_app_launch_manager.h
index 2cc81c3..a23ab7e 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_manager.h
+++ b/chrome/browser/ui/web_applications/web_app_launch_manager.h
@@ -44,7 +44,6 @@
   WebAppLaunchManager& operator=(const WebAppLaunchManager&) = delete;
   virtual ~WebAppLaunchManager();
 
-  // apps::LaunchManager:
   content::WebContents* OpenApplication(apps::AppLaunchParams&& params);
 
   // |browser| may be nullptr if the navigation fails.
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.cc b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
index fa58b6e..cd602f9c 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_utils.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
@@ -18,10 +18,9 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "components/omnibox/browser/location_bar_model.h"
 #include "content/public/browser/navigation_controller.h"
@@ -133,8 +132,8 @@
   // entered the app's scope. The minimal-ui Back button will be initially
   // disabled if the previous page was outside scope. Packaged apps are not
   // affected.
-  AppRegistrar& registrar =
-      WebAppProviderBase::GetProviderBase(profile)->registrar();
+  WebAppRegistrar& registrar =
+      WebAppProvider::GetForWebApps(profile)->registrar();
   if (registrar.IsInstalled(app_id)) {
     absl::optional<GURL> app_scope = registrar.GetAppScope(app_id);
     if (!app_scope)
diff --git a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
index 1a4da1a..bd173dc 100644
--- a/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_link_capturing_browsertest.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/manifest_update_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
@@ -115,8 +114,8 @@
     chrome::CloseWindow(app_browser);
   }
 
-  WebAppProviderBase& provider() {
-    auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  WebAppProvider& provider() {
+    auto* provider = WebAppProvider::GetForWebApps(profile());
     DCHECK(provider);
     return *provider;
   }
@@ -611,8 +610,8 @@
      private:
       base::RunLoop run_loop_;
     } update_awaiter;
-    base::ScopedObservation<AppRegistrar, AppRegistrarObserver> observer_scope(
-        &update_awaiter);
+    base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver>
+        observer_scope(&update_awaiter);
     observer_scope.Observe(&provider.registrar());
 
     serve_token = false;
diff --git a/chrome/browser/ui/web_applications/web_app_menu_model.cc b/chrome/browser/ui/web_applications/web_app_menu_model.cc
index 128a910..4532392 100644
--- a/chrome/browser/ui/web_applications/web_app_menu_model.cc
+++ b/chrome/browser/ui/web_applications/web_app_menu_model.cc
@@ -7,6 +7,7 @@
 #include "base/feature_list.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/media/router/media_router_feature.h"
@@ -122,7 +123,7 @@
 
 // Chrome OS's app list is prominent enough to not need a separate uninstall
 // option in the app menu.
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
+#if !defined(OS_CHROMEOS)
   DCHECK(browser()->app_controller());
   if (browser()->app_controller()->IsInstalled()) {
     AddSeparator(ui::NORMAL_SEPARATOR);
@@ -132,7 +133,7 @@
                 ui::EscapeMenuLabelAmpersands(
                     browser()->app_controller()->GetAppShortName())));
   }
-#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // !defined(OS_CHROMEOS)
   AddSeparator(ui::LOWER_SEPARATOR);
 
   CreateZoomMenu();
diff --git a/chrome/browser/ui/web_applications/web_app_profile_deletion_browsertest.cc b/chrome/browser/ui/web_applications/web_app_profile_deletion_browsertest.cc
index bbae920..bc8e2ee 100644
--- a/chrome/browser/ui/web_applications/web_app_profile_deletion_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_profile_deletion_browsertest.cc
@@ -8,10 +8,9 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "content/public/test/browser_test.h"
 #include "url/gurl.h"
@@ -20,8 +19,8 @@
 
 class WebAppProfileDeletionBrowserTest : public WebAppControllerBrowserTest {
  public:
-  AppRegistrar& registrar() {
-    auto* provider = WebAppProviderBase::GetProviderBase(profile());
+  WebAppRegistrar& registrar() {
+    auto* provider = WebAppProvider::GetForWebApps(profile());
     CHECK(provider);
     return provider->registrar();
   }
diff --git a/chrome/browser/ui/web_applications/web_app_protocol_handling_browsertest.cc b/chrome/browser/ui/web_applications/web_app_protocol_handling_browsertest.cc
index 2019714..16f2a3c 100644
--- a/chrome/browser/ui/web_applications/web_app_protocol_handling_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_protocol_handling_browsertest.cc
@@ -62,8 +62,8 @@
     return app_id;
   }
 
-  web_app::WebAppProviderBase* provider() {
-    return WebAppProviderBase::GetProviderBase(browser()->profile());
+  web_app::WebAppProvider* provider() {
+    return WebAppProvider::GetForWebApps(browser()->profile());
   }
 
   web_app::ProtocolHandlerManager& protocol_handler_manager() {
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc b/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc
index 48f1a094..c775b7d 100644
--- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl_browsertest.cc
@@ -64,7 +64,7 @@
   }
 
   WebAppUiManager& ui_manager() {
-    return WebAppProviderBase::GetProviderBase(profile())->ui_manager();
+    return WebAppProvider::GetForWebApps(profile())->ui_manager();
   }
 
   TestShortcutManager* shortcut_manager_;
diff --git a/chrome/browser/ui/web_applications/web_app_uninstall_browsertest.cc b/chrome/browser/ui/web_applications/web_app_uninstall_browsertest.cc
index b082a025..271ab30 100644
--- a/chrome/browser/ui/web_applications/web_app_uninstall_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_uninstall_browsertest.cc
@@ -18,9 +18,9 @@
 #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/isolation_prefs_utils.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "components/sessions/core/tab_restore_service.h"
@@ -40,8 +40,7 @@
   }
 
   void UninstallWebApp(const AppId& app_id) {
-    WebAppProviderBase* const provider =
-        WebAppProviderBase::GetProviderBase(profile());
+    WebAppProvider* const provider = WebAppProvider::GetForWebApps(profile());
     base::RunLoop run_loop;
 
     DCHECK(provider->install_finalizer().CanUserUninstallWebApp(app_id));
@@ -155,8 +154,7 @@
   bool quit_run_loop = false;
 
   // Trigger app uninstall without waiting for result.
-  WebAppProviderBase* const provider =
-      WebAppProviderBase::GetProviderBase(profile());
+  WebAppProvider* const provider = WebAppProvider::GetForWebApps(profile());
   EXPECT_TRUE(provider->registrar().IsInstalled(app_id));
   DCHECK(provider->install_finalizer().CanUserUninstallWebApp(app_id));
   provider->install_finalizer().UninstallWebApp(
diff --git a/chrome/browser/ui/web_applications/web_app_url_handling_browsertest.cc b/chrome/browser/ui/web_applications/web_app_url_handling_browsertest.cc
index 32e09a8..50b5d1d 100644
--- a/chrome/browser/ui/web_applications/web_app_url_handling_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_url_handling_browsertest.cc
@@ -57,8 +57,8 @@
     return app_id;
   }
 
-  WebAppProviderBase& provider() {
-    auto* provider = WebAppProviderBase::GetProviderBase(browser()->profile());
+  WebAppProvider& provider() {
+    auto* provider = WebAppProvider::GetForWebApps(browser()->profile());
     DCHECK(provider);
     return *provider;
   }
diff --git a/chrome/browser/ui/web_applications/web_app_window_controls_overlay_browsertest.cc b/chrome/browser/ui/web_applications/web_app_window_controls_overlay_browsertest.cc
index c09f48f..7b20ce5 100644
--- a/chrome/browser/ui/web_applications/web_app_window_controls_overlay_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_window_controls_overlay_browsertest.cc
@@ -57,8 +57,8 @@
     return app_id;
   }
 
-  WebAppProviderBase& provider() {
-    auto* provider = WebAppProviderBase::GetProviderBase(browser()->profile());
+  WebAppProvider& provider() {
+    auto* provider = WebAppProvider::GetForWebApps(browser()->profile());
     DCHECK(provider);
     return *provider;
   }
diff --git a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
index bb09f5a..0b47f323 100644
--- a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
@@ -27,8 +27,8 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/services/app_service/public/cpp/share_target.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc b/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc
index cec210a5..2009c2b6 100644
--- a/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc
+++ b/chrome/browser/ui/webui/bookmarks/bookmarks_ui.cc
@@ -72,6 +72,8 @@
       {"emptyList", IDS_BOOKMARK_MANAGER_EMPTY_LIST},
       {"emptyUnmodifiableList", IDS_BOOKMARK_MANAGER_EMPTY_UNMODIFIABLE_LIST},
       {"folderLabel", IDS_BOOKMARK_MANAGER_FOLDER_LABEL},
+      {"importBegan", IDS_BOOKMARK_MANAGER_MENU_IMPORT_BEGAN},
+      {"importEnded", IDS_BOOKMARK_MANAGER_MENU_IMPORT_ENDED},
       {"itemsSelected", IDS_BOOKMARK_MANAGER_ITEMS_SELECTED},
       {"itemsUnselected", IDS_BOOKMARK_MANAGER_ITEMS_UNSELECTED},
       {"listAxLabel", IDS_BOOKMARK_MANAGER_LIST_AX_LABEL},
diff --git a/chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.cc
index 198ee612..5b299124 100644
--- a/chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/fingerprint_setup_screen_handler.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/ash/login/screens/fingerprint_setup_screen.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/login/localized_values_builder.h"
+#include "components/user_manager/user_manager.h"
 #include "ui/chromeos/devicetype_utils.h"
 
 namespace chromeos {
@@ -27,6 +28,8 @@
     ::login::LocalizedValuesBuilder* builder) {
   builder->Add("setupFingerprintScreenTitle",
                IDS_OOBE_FINGERPINT_SETUP_SCREEN_TITLE);
+  builder->Add("setupFingerprintScreenTitleForChild",
+               IDS_OOBE_FINGERPINT_SETUP_SCREEN_TITLE_CHILD);
   builder->Add("skipFingerprintSetup",
                IDS_OOBE_FINGERPINT_SETUP_SCREEN_BUTTON_SKIP);
   builder->Add("fingerprintSetupDone",
@@ -39,41 +42,56 @@
                IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_SUCCESS_TITLE);
   builder->Add("setupFingerprintEnrollmentSuccessDescription",
                IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_SUCCESS_DESCRIPTION);
+  builder->Add(
+      "setupFingerprintEnrollmentSuccessDescriptionForChild",
+      IDS_OOBE_FINGERPINT_SETUP_SCREEN_ENROLLMENT_SUCCESS_DESCRIPTION_CHILD);
   builder->Add("setupFingerprintScanMoveFinger",
                IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_MOVE_FINGER);
+  builder->Add("setupFingerprintScanMoveFingerForChild",
+               IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_MOVE_FINGER_CHILD);
   builder->Add("setupFingerprintScanTryAgain",
                IDS_OOBE_FINGERPINT_SETUP_SCREEN_INSTRUCTION_TRY_AGAIN);
 
-  int description_id, aria_label_id;
+  int description_id, aria_label_id, description_id_for_child;
   bool aria_label_includes_device = false;
   switch (quick_unlock::GetFingerprintLocation()) {
     case quick_unlock::FingerprintLocation::TABLET_POWER_BUTTON:
       description_id =
           IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION;
+      description_id_for_child =
+          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_POWER_BUTTON_DESCRIPTION_CHILD;
       aria_label_id =
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON_ARIA_LABEL;
       break;
     case quick_unlock::FingerprintLocation::KEYBOARD_BOTTOM_LEFT:
       description_id =
           IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
+      description_id_for_child =
+          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
       aria_label_id =
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_LEFT_ARIA_LABEL;
       break;
     case quick_unlock::FingerprintLocation::KEYBOARD_BOTTOM_RIGHT:
       description_id =
           IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
+      description_id_for_child =
+          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
       aria_label_id =
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_RIGHT_ARIA_LABEL;
       break;
     case quick_unlock::FingerprintLocation::KEYBOARD_TOP_RIGHT:
       description_id =
           IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
+      description_id_for_child =
+          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
       aria_label_id =
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL;
       break;
     case quick_unlock::FingerprintLocation::RIGHT_SIDE:
       description_id =
           IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
+      description_id_for_child =
+          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
       aria_label_id =
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_RIGHT_SIDE_ARIA_LABEL;
       aria_label_includes_device = true;
@@ -81,6 +99,8 @@
     case quick_unlock::FingerprintLocation::LEFT_SIDE:
       description_id =
           IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
+      description_id_for_child =
+          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
       aria_label_id =
           IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_LEFT_SIDE_ARIA_LABEL;
       aria_label_includes_device = true;
@@ -88,6 +108,8 @@
     case quick_unlock::FingerprintLocation::UNKNOWN:
       description_id =
           IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
+      description_id_for_child =
+          IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION_CHILD;
       aria_label_id =
           IDS_OOBE_FINGERPINT_SETUP_SCREEN_SENSOR_GENERAL_DESCRIPTION;
       aria_label_includes_device = true;
@@ -95,6 +117,8 @@
   }
   builder->AddF("setupFingerprintScreenDescription", description_id,
                 ui::GetChromeOSDeviceName());
+  builder->AddF("setupFingerprintScreenDescriptionForChild",
+                description_id_for_child, ui::GetChromeOSDeviceName());
   if (aria_label_includes_device) {
     builder->AddF("setupFingerprintScreenAriaLabel", aria_label_id,
                   ui::GetChromeOSDeviceName());
@@ -113,7 +137,10 @@
 }
 
 void FingerprintSetupScreenHandler::Show() {
-  ShowScreen(kScreenId);
+  auto* user_manager = user_manager::UserManager::Get();
+  base::DictionaryValue data;
+  data.SetBoolean("isChildAccount", user_manager->IsLoggedInAsChildUser());
+  ShowScreenWithData(kScreenId, &data);
 }
 
 void FingerprintSetupScreenHandler::Hide() {}
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
index 512e1cd..991f4146 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -53,11 +53,11 @@
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/extensions/bookmark_app_util.h"
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
@@ -148,7 +148,7 @@
 }
 
 void GetWebAppBasicInfo(const web_app::AppId& app_id,
-                        const web_app::AppRegistrar& app_registrar,
+                        const web_app::WebAppRegistrar& app_registrar,
                         base::DictionaryValue* info) {
   info->SetString(kInfoIdKey, app_id);
   info->SetString(kInfoNameKey, app_registrar.GetAppShortName(app_id));
@@ -610,7 +610,7 @@
   PrefService* prefs = profile->GetPrefs();
 
   std::set<web_app::AppId> web_app_ids;
-  web_app::AppRegistrar& registrar = web_app_provider_->registrar();
+  web_app::WebAppRegistrar& registrar = web_app_provider_->registrar();
   for (const web_app::AppId& web_app_id : registrar.GetAppIds()) {
     // The Youtube app is harded to be a 'bookmark app', however it is not, it
     // is a platform app.
@@ -757,7 +757,7 @@
   GURL full_launch_url;
   apps::mojom::LaunchContainer launch_container;
 
-  web_app::AppRegistrar& registrar = web_app_provider_->registrar();
+  web_app::WebAppRegistrar& registrar = web_app_provider_->registrar();
   if (registrar.IsInstalled(extension_id) &&
       !IsYoutubeExtension(extension_id)) {
     type = extensions::Manifest::Type::TYPE_HOSTED_APP;
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.h b/chrome/browser/ui/webui/ntp/app_launcher_handler.h
index c9d5ded..1f371ea 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.h
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.h
@@ -14,12 +14,12 @@
 #include "base/task/cancelable_task_tracker.h"
 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
 #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager_observer.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "components/favicon/core/favicon_service.h"
 #include "components/prefs/pref_change_registrar.h"
@@ -228,7 +228,8 @@
   // it's owned by our containing profile.
   web_app::WebAppProvider* const web_app_provider_;
 
-  base::ScopedObservation<web_app::AppRegistrar, web_app::AppRegistrarObserver>
+  base::ScopedObservation<web_app::WebAppRegistrar,
+                          web_app::AppRegistrarObserver>
       web_apps_observation_{this};
 
   base::ScopedObservation<web_app::WebAppPolicyManager,
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index 6949b11..889af24 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -679,8 +679,8 @@
   if (!browser)
     return;
 
-  OpenTabForSyncKeyRetrieval(browser,
-                             syncer::KeyRetrievalTriggerForUMA::kSettings);
+  OpenTabForSyncKeyRetrieval(
+      browser, syncer::TrustedVaultUserActionTriggerForUMA::kSettings);
 }
 
 void PeopleHandler::HandleGetSyncStatus(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc
index 22288df..4330ca0b 100644
--- a/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -59,7 +59,6 @@
 #include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
 #include "chrome/browser/ui/webui/settings/site_settings_handler.h"
 #include "chrome/browser/ui/webui/webui_util.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
@@ -151,7 +150,7 @@
   registry->RegisterBooleanPref(prefs::kImportDialogSearchEngine, true);
 }
 
-web_app::AppRegistrar& GetRegistrarForProfile(Profile* profile) {
+web_app::WebAppRegistrar& GetRegistrarForProfile(Profile* profile) {
   return web_app::WebAppProvider::Get(profile)->registrar();
 }
 
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index c0aaa12..5053278 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -161,7 +161,7 @@
 
 base::flat_set<std::string> GetInstalledAppOrigins(
     Profile* profile,
-    const web_app::AppRegistrar& registrar) {
+    const web_app::WebAppRegistrar& registrar) {
   base::flat_set<std::string> origins;
   for (const web_app::AppId& app : registrar.GetAppIds())
     origins.insert(registrar.GetAppScope(app).GetOrigin().spec());
@@ -234,7 +234,7 @@
     const std::set<std::string>& origin_permission_set,
     base::Value* list_value,
     Profile* profile,
-    const web_app::AppRegistrar& registrar) {
+    const web_app::WebAppRegistrar& registrar) {
   DCHECK_EQ(base::Value::Type::LIST, list_value->type());
   DCHECK(profile);
   base::flat_set<std::string> installed_origins =
@@ -390,8 +390,9 @@
 
 }  // namespace
 
-SiteSettingsHandler::SiteSettingsHandler(Profile* profile,
-                                         web_app::AppRegistrar& app_registrar)
+SiteSettingsHandler::SiteSettingsHandler(
+    Profile* profile,
+    web_app::WebAppRegistrar& app_registrar)
     : profile_(profile), app_registrar_(app_registrar) {}
 
 SiteSettingsHandler::~SiteSettingsHandler() {
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.h b/chrome/browser/ui/webui/settings/site_settings_handler.h
index 9dd5158..2e94cd81 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.h
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -16,7 +16,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_observer.h"
 #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/content_settings/core/browser/content_settings_observer.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -43,7 +42,7 @@
       public CookiesTreeModel::Observer {
  public:
   explicit SiteSettingsHandler(Profile* profile,
-                               web_app::AppRegistrar& web_app_registrar);
+                               web_app::WebAppRegistrar& web_app_registrar);
   ~SiteSettingsHandler() override;
 
   // SettingsPageUIHandler:
@@ -266,7 +265,7 @@
   void SendCookieSettingDescription();
 
   Profile* profile_;
-  web_app::AppRegistrar& app_registrar_;
+  web_app::WebAppRegistrar& app_registrar_;
 
   base::ScopedMultiSourceObservation<Profile, ProfileObserver>
       observed_profiles_{this};
diff --git a/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc
index 1739d38..8198b2d 100644
--- a/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc
@@ -347,7 +347,7 @@
       map, std::move(extension_provider),
       HostContentSettingsMap::CUSTOM_EXTENSION_PROVIDER);
 
-  exceptions.Clear();
+  exceptions.ClearList();
   GetExceptionsForContentType(kContentType, &profile,
                               /*extension_registry=*/nullptr,
                               /*web_ui=*/nullptr,
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.h b/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
index ad4929a..2a9a788d 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
@@ -15,8 +15,8 @@
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/icon_key_util.h"
 #include "chrome/browser/apps/app_service/paused_apps.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/content_settings/core/browser/content_settings_observer.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings_types.h"
@@ -299,7 +299,7 @@
 
   WebAppProvider* const provider_;
 
-  base::ScopedObservation<AppRegistrar, AppRegistrarObserver>
+  base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver>
       registrar_observation_{this};
 
   base::ScopedObservation<HostContentSettingsMap, content_settings::Observer>
diff --git a/chrome/browser/web_applications/app_service/web_apps_base.cc b/chrome/browser/web_applications/app_service/web_apps_base.cc
index b2af133..384a512 100644
--- a/chrome/browser/web_applications/app_service/web_apps_base.cc
+++ b/chrome/browser/web_applications/app_service/web_apps_base.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/web_applications/web_app_dialog_manager.h"
 #include "chrome/browser/ui/web_applications/web_app_ui_manager_impl.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
diff --git a/chrome/browser/web_applications/app_service/web_apps_publisher_host.cc b/chrome/browser/web_applications/app_service/web_apps_publisher_host.cc
index a56c624..c040050 100644
--- a/chrome/browser/web_applications/app_service/web_apps_publisher_host.cc
+++ b/chrome/browser/web_applications/app_service/web_apps_publisher_host.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/apps/app_service/menu_item_constants.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
diff --git a/chrome/browser/web_applications/app_service/web_apps_publisher_host.h b/chrome/browser/web_applications/app_service/web_apps_publisher_host.h
index 715cf69..27733234 100644
--- a/chrome/browser/web_applications/app_service/web_apps_publisher_host.h
+++ b/chrome/browser/web_applications/app_service/web_apps_publisher_host.h
@@ -13,7 +13,6 @@
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "chrome/browser/web_applications/app_service/web_app_publisher_helper.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chromeos/crosapi/mojom/app_service.mojom.h"
diff --git a/chrome/browser/web_applications/app_shortcut_manager.cc b/chrome/browser/web_applications/app_shortcut_manager.cc
index ce41a72..7fc271cc 100644
--- a/chrome/browser/web_applications/app_shortcut_manager.cc
+++ b/chrome/browser/web_applications/app_shortcut_manager.cc
@@ -15,7 +15,7 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -49,7 +49,7 @@
 AppShortcutManager::~AppShortcutManager() = default;
 
 void AppShortcutManager::SetSubsystems(AppIconManager* icon_manager,
-                                       AppRegistrar* registrar) {
+                                       WebAppRegistrar* registrar) {
   icon_manager_ = icon_manager;
   registrar_ = registrar;
 }
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn
index 48193b6..261e3a9 100644
--- a/chrome/browser/web_applications/components/BUILD.gn
+++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -9,8 +9,6 @@
     "../system_web_apps/system_web_app_types.h",
     "app_icon_manager.cc",
     "app_icon_manager.h",
-    "app_registrar.cc",
-    "app_registrar.h",
     "app_registrar_observer.h",
     "app_registry_controller.cc",
     "app_registry_controller.h",
@@ -61,10 +59,6 @@
     "web_app_prefs_utils.h",
     "web_app_protocol_handler_registration.cc",
     "web_app_protocol_handler_registration.h",
-    "web_app_provider_base.cc",
-    "web_app_provider_base.h",
-    "web_app_provider_base_factory.cc",
-    "web_app_provider_base_factory.h",
     "web_app_run_on_os_login.cc",
     "web_app_run_on_os_login.h",
     "web_app_shortcut.cc",
diff --git a/chrome/browser/web_applications/components/app_registrar.cc b/chrome/browser/web_applications/components/app_registrar.cc
deleted file mode 100644
index 3ef6ae39..0000000
--- a/chrome/browser/web_applications/components/app_registrar.cc
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2019 The Chromium 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/web_applications/components/app_registrar.h"
-
-#include "base/containers/cxx20_erase.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar_observer.h"
-#include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
-#include "chrome/browser/web_applications/components/install_bounce_metric.h"
-#include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_prefs_utils.h"
-#include "chrome/common/chrome_features.h"
-#include "content/public/common/content_features.h"
-
-namespace web_app {
-
-AppRegistrar::AppRegistrar(Profile* profile) : profile_(profile) {}
-
-AppRegistrar::~AppRegistrar() {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnAppRegistrarDestroyed();
-}
-
-void AppRegistrar::SetSubsystems(OsIntegrationManager* os_integration_manager) {
-  os_integration_manager_ = os_integration_manager;
-}
-
-bool AppRegistrar::IsLocallyInstalled(const GURL& start_url) const {
-  return IsLocallyInstalled(
-      GenerateAppId(/*manifest_id=*/absl::nullopt, start_url));
-}
-
-bool AppRegistrar::IsPlaceholderApp(const AppId& app_id) const {
-  return ExternallyInstalledWebAppPrefs(profile_->GetPrefs())
-      .IsPlaceholderApp(app_id);
-}
-
-void AppRegistrar::AddObserver(AppRegistrarObserver* observer) {
-  observers_.AddObserver(observer);
-}
-
-void AppRegistrar::RemoveObserver(AppRegistrarObserver* observer) {
-  observers_.RemoveObserver(observer);
-}
-
-void AppRegistrar::NotifyWebAppInstalled(const AppId& app_id) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppInstalled(app_id);
-  // TODO(alancutter): Call RecordWebAppInstallation here when we get access to
-  // the webapps::WebappInstallSource in this event.
-}
-
-void AppRegistrar::NotifyWebAppManifestUpdated(const AppId& app_id,
-                                               base::StringPiece old_name) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppManifestUpdated(app_id, old_name);
-}
-
-void AppRegistrar::NotifyWebAppsWillBeUpdatedFromSync(
-    const std::vector<const WebApp*>& new_apps_state) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppsWillBeUpdatedFromSync(new_apps_state);
-}
-
-void AppRegistrar::NotifyWebAppUninstalled(const AppId& app_id) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppUninstalled(app_id);
-}
-
-void AppRegistrar::NotifyWebAppWillBeUninstalled(const AppId& app_id) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppWillBeUninstalled(app_id);
-  RecordWebAppUninstallation(profile()->GetPrefs(), app_id);
-}
-
-void AppRegistrar::NotifyWebAppLocallyInstalledStateChanged(
-    const AppId& app_id,
-    bool is_locally_installed) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppLocallyInstalledStateChanged(app_id, is_locally_installed);
-}
-
-void AppRegistrar::NotifyWebAppDisabledStateChanged(const AppId& app_id,
-                                                    bool is_disabled) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppDisabledStateChanged(app_id, is_disabled);
-}
-
-void AppRegistrar::NotifyWebAppsDisabledModeChanged() {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppsDisabledModeChanged();
-}
-
-void AppRegistrar::NotifyWebAppLastLaunchTimeChanged(const AppId& app_id,
-                                                     const base::Time& time) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppLastLaunchTimeChanged(app_id, time);
-}
-
-void AppRegistrar::NotifyWebAppInstallTimeChanged(const AppId& app_id,
-                                                  const base::Time& time) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppInstallTimeChanged(app_id, time);
-}
-
-void AppRegistrar::NotifyWebAppProfileWillBeDeleted(const AppId& app_id) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppProfileWillBeDeleted(app_id);
-}
-
-void AppRegistrar::NotifyWebAppInstalledWithOsHooks(const AppId& app_id) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppInstalledWithOsHooks(app_id);
-}
-
-void AppRegistrar::NotifyWebAppUserDisplayModeChanged(
-    const AppId& app_id,
-    DisplayMode user_display_mode) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppUserDisplayModeChanged(app_id, user_display_mode);
-}
-
-void AppRegistrar::NotifyWebAppExperimentalTabbedWindowModeChanged(
-    const AppId& app_id,
-    bool enabled) {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnWebAppExperimentalTabbedWindowModeChanged(app_id, enabled);
-}
-
-void AppRegistrar::NotifyAppRegistrarShutdown() {
-  for (AppRegistrarObserver& observer : observers_)
-    observer.OnAppRegistrarShutdown();
-}
-
-std::map<AppId, GURL> AppRegistrar::GetExternallyInstalledApps(
-    ExternalInstallSource install_source) const {
-  std::map<AppId, GURL> installed_apps =
-      ExternallyInstalledWebAppPrefs::BuildAppIdsMap(profile()->GetPrefs(),
-                                                     install_source);
-  base::EraseIf(installed_apps, [this](const std::pair<AppId, GURL>& app) {
-    return !IsInstalled(app.first);
-  });
-
-  return installed_apps;
-}
-
-absl::optional<AppId> AppRegistrar::LookupExternalAppId(
-    const GURL& install_url) const {
-  return ExternallyInstalledWebAppPrefs(profile()->GetPrefs())
-      .LookupAppId(install_url);
-}
-
-bool AppRegistrar::HasExternalApp(const AppId& app_id) const {
-  return ExternallyInstalledWebAppPrefs::HasAppId(profile()->GetPrefs(),
-                                                  app_id);
-}
-
-bool AppRegistrar::HasExternalAppWithInstallSource(
-    const AppId& app_id,
-    ExternalInstallSource install_source) const {
-  return ExternallyInstalledWebAppPrefs::HasAppIdWithInstallSource(
-      profile()->GetPrefs(), app_id, install_source);
-}
-
-GURL AppRegistrar::GetAppLaunchUrl(const AppId& app_id) const {
-  const GURL& start_url = GetAppStartUrl(app_id);
-  const std::string* launch_query_params = GetAppLaunchQueryParams(app_id);
-  if (!start_url.is_valid() || !launch_query_params)
-    return start_url;
-
-  GURL::Replacements replacements;
-  if (start_url.query_piece().empty()) {
-    replacements.SetQueryStr(*launch_query_params);
-    return start_url.ReplaceComponents(replacements);
-  }
-
-  if (start_url.query_piece().find(*launch_query_params) !=
-      base::StringPiece::npos) {
-    return start_url;
-  }
-
-  std::string query_params = start_url.query() + "&" + *launch_query_params;
-  replacements.SetQueryStr(query_params);
-  return start_url.ReplaceComponents(replacements);
-}
-
-GURL AppRegistrar::GetAppScope(const AppId& app_id) const {
-  absl::optional<GURL> scope = GetAppScopeInternal(app_id);
-  if (scope)
-    return *scope;
-  if (base::FeatureList::IsEnabled(
-          features::kDesktopPWAsTabStripLinkCapturing) &&
-      IsTabbedWindowModeEnabled(app_id)) {
-    return GetAppStartUrl(app_id).GetOrigin();
-  }
-  return GetAppStartUrl(app_id).GetWithoutFilename();
-}
-
-absl::optional<AppId> AppRegistrar::FindAppWithUrlInScope(
-    const GURL& url) const {
-  const std::string url_path = url.spec();
-
-  absl::optional<AppId> best_app_id;
-  size_t best_app_path_length = 0U;
-  bool best_app_is_shortcut = true;
-
-  for (const AppId& app_id : GetAppIds()) {
-    // TODO(crbug.com/910016): Treat shortcuts as PWAs.
-    bool app_is_shortcut = IsShortcutApp(app_id);
-    if (app_is_shortcut && !best_app_is_shortcut)
-      continue;
-
-    const std::string app_path = GetAppScope(app_id).spec();
-
-    if ((app_path.size() > best_app_path_length ||
-         (best_app_is_shortcut && !app_is_shortcut)) &&
-        base::StartsWith(url_path, app_path, base::CompareCase::SENSITIVE)) {
-      best_app_id = app_id;
-      best_app_path_length = app_path.size();
-      best_app_is_shortcut = app_is_shortcut;
-    }
-  }
-
-  return best_app_id;
-}
-
-bool AppRegistrar::DoesScopeContainAnyApp(const GURL& scope) const {
-  std::string scope_str = scope.spec();
-
-  for (const auto& app_id : GetAppIds()) {
-    if (!IsLocallyInstalled(app_id))
-      continue;
-
-    std::string app_scope = GetAppScope(app_id).spec();
-    DCHECK(!app_scope.empty());
-
-    if (base::StartsWith(app_scope, scope_str, base::CompareCase::SENSITIVE))
-      return true;
-  }
-
-  return false;
-}
-
-std::vector<AppId> AppRegistrar::FindAppsInScope(const GURL& scope) const {
-  std::string scope_str = scope.spec();
-
-  std::vector<AppId> in_scope;
-  for (const auto& app_id : GetAppIds()) {
-    if (!IsLocallyInstalled(app_id))
-      continue;
-
-    std::string app_scope = GetAppScope(app_id).spec();
-    DCHECK(!app_scope.empty());
-
-    if (!base::StartsWith(app_scope, scope_str, base::CompareCase::SENSITIVE))
-      continue;
-
-    in_scope.push_back(app_id);
-  }
-
-  return in_scope;
-}
-
-absl::optional<AppId> AppRegistrar::FindInstalledAppWithUrlInScope(
-    const GURL& url,
-    bool window_only) const {
-  const std::string url_path = url.spec();
-
-  absl::optional<AppId> best_app_id;
-  size_t best_app_path_length = 0U;
-  bool best_app_is_shortcut = true;
-
-  for (const AppId& app_id : GetAppIds()) {
-    // TODO(crbug.com/910016): Treat shortcuts as PWAs.
-    bool app_is_shortcut = IsShortcutApp(app_id);
-    if (app_is_shortcut && !best_app_is_shortcut)
-      continue;
-
-    if (!IsLocallyInstalled(app_id))
-      continue;
-
-    if (window_only &&
-        GetAppEffectiveDisplayMode(app_id) == DisplayMode::kBrowser) {
-      continue;
-    }
-
-    const std::string app_path = GetAppScope(app_id).spec();
-
-    if ((app_path.size() > best_app_path_length ||
-         (best_app_is_shortcut && !app_is_shortcut)) &&
-        base::StartsWith(url_path, app_path, base::CompareCase::SENSITIVE)) {
-      best_app_id = app_id;
-      best_app_path_length = app_path.size();
-      best_app_is_shortcut = app_is_shortcut;
-    }
-  }
-
-  return best_app_id;
-}
-
-bool AppRegistrar::IsShortcutApp(const AppId& app_id) const {
-  // TODO (crbug/910016): Make app scope always return a value and record this
-  //  distinction in some other way.
-  return !GetAppScopeInternal(app_id).has_value();
-}
-
-DisplayMode AppRegistrar::GetAppEffectiveDisplayMode(
-    const AppId& app_id) const {
-  if (!IsLocallyInstalled(app_id))
-    return DisplayMode::kBrowser;
-
-  auto app_display_mode = GetAppDisplayMode(app_id);
-  auto user_display_mode = GetAppUserDisplayMode(app_id);
-  if (app_display_mode == DisplayMode::kUndefined ||
-      user_display_mode == DisplayMode::kUndefined) {
-    return DisplayMode::kUndefined;
-  }
-
-  std::vector<DisplayMode> display_mode_overrides =
-      GetAppDisplayModeOverride(app_id);
-  return ResolveEffectiveDisplayMode(app_display_mode, display_mode_overrides,
-                                     user_display_mode);
-}
-
-DisplayMode AppRegistrar::GetEffectiveDisplayModeFromManifest(
-    const AppId& app_id) const {
-  std::vector<DisplayMode> display_mode_overrides =
-      GetAppDisplayModeOverride(app_id);
-
-  if (!display_mode_overrides.empty())
-    return display_mode_overrides[0];
-
-  return GetAppDisplayMode(app_id);
-}
-
-bool AppRegistrar::IsInExperimentalTabbedWindowMode(const AppId& app_id) const {
-  return base::FeatureList::IsEnabled(features::kDesktopPWAsTabStrip) &&
-         base::FeatureList::IsEnabled(features::kDesktopPWAsTabStripSettings) &&
-         GetBoolWebAppPref(profile()->GetPrefs(), app_id,
-                           kExperimentalTabbedWindowMode);
-}
-
-bool AppRegistrar::IsTabbedWindowModeEnabled(const AppId& app_id) const {
-  if (!base::FeatureList::IsEnabled(features::kDesktopPWAsTabStrip))
-    return false;
-
-  DisplayMode display = GetAppEffectiveDisplayMode(app_id);
-
-  return IsInExperimentalTabbedWindowMode(app_id) ||
-         display == DisplayMode::kTabbed;
-}
-
-}  // namespace web_app
diff --git a/chrome/browser/web_applications/components/app_registrar.h b/chrome/browser/web_applications/components/app_registrar.h
deleted file mode 100644
index b5cdc6e..0000000
--- a/chrome/browser/web_applications/components/app_registrar.h
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2019 The Chromium 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_WEB_APPLICATIONS_COMPONENTS_APP_REGISTRAR_H_
-#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_APP_REGISTRAR_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/observer_list.h"
-#include "chrome/browser/web_applications/components/web_app_constants.h"
-#include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_application_info.h"
-#include "components/services/app_service/public/cpp/file_handler.h"
-#include "components/services/app_service/public/cpp/protocol_handler_info.h"
-#include "components/services/app_service/public/cpp/url_handler_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-class GURL;
-class Profile;
-namespace apps {
-struct ShareTarget;
-}
-namespace base {
-class Time;
-}
-
-namespace web_app {
-
-class AppRegistrarObserver;
-class WebAppRegistrar;
-class WebApp;
-class OsIntegrationManager;
-
-enum class ExternalInstallSource;
-
-class AppRegistrar {
- public:
-  explicit AppRegistrar(Profile* profile);
-  virtual ~AppRegistrar();
-
-  virtual void Start() {}
-  virtual void Shutdown() {}
-
-  // Returns whether the app with |app_id| is currently listed in the registry.
-  // ie. we have data for web app manifest and icons, and this |app_id| can be
-  // used in other registrar methods.
-  virtual bool IsInstalled(const AppId& app_id) const = 0;
-
-  // Returns whether the app is currently being uninstalled. This will be true
-  // after uninstall has begun but before the OS integration hooks for uninstall
-  // have completed. It will return false after uninstallation has completed.
-  // Note that the underlying field this checks is not yet persisted to the
-  // database; see https://crbug.com/1162477
-  virtual bool IsUninstalling(const AppId& app_id) const = 0;
-
-  // Returns whether the app with |app_id| is currently fully locally installed.
-  // ie. app is not grey in chrome://apps UI surface and may have OS integration
-  // like shortcuts. |IsLocallyInstalled| apps is a subset of |IsInstalled|
-  // apps. On Chrome OS all apps are always locally installed.
-  virtual bool IsLocallyInstalled(const AppId& app_id) const = 0;
-
-  // Returns true if the app was installed by user, false if default installed.
-  virtual bool WasInstalledByUser(const AppId& app_id) const = 0;
-
-  // Returns true if the app was installed by the device OEM. Always false on
-  // on non-Chrome OS.
-  virtual bool WasInstalledByOem(const AppId& app_id) const = 0;
-
-  // Returns the AppIds and URLs of apps externally installed from
-  // |install_source|.
-  virtual std::map<AppId, GURL> GetExternallyInstalledApps(
-      ExternalInstallSource install_source) const;
-
-  // Returns the app id for |install_url| if the AppRegistrar is aware of an
-  // externally installed app for it. Note that the |install_url| is the URL
-  // that the app was installed from, which may not necessarily match the app's
-  // current start URL.
-  virtual absl::optional<AppId> LookupExternalAppId(
-      const GURL& install_url) const;
-
-  // Returns whether the AppRegistrar has an externally installed app with
-  // |app_id| from any |install_source|.
-  virtual bool HasExternalApp(const AppId& app_id) const;
-
-  // Returns whether the AppRegistrar has an externally installed app with
-  // |app_id| from |install_source|.
-  virtual bool HasExternalAppWithInstallSource(
-      const AppId& app_id,
-      ExternalInstallSource install_source) const;
-
-  // Returns true if the web app with the |app_id| contains |protocol_scheme|
-  // as one of its approved launch protocols.
-  virtual bool IsApprovedLaunchProtocol(const AppId& app_id,
-                                        std::string protocol_scheme) const = 0;
-
-  // Count a number of all apps which are installed by user (non-default).
-  // Requires app registry to be in a ready state.
-  virtual int CountUserInstalledApps() const = 0;
-
-  // All names are UTF8 encoded.
-  virtual std::string GetAppShortName(const AppId& app_id) const = 0;
-  virtual std::string GetAppDescription(const AppId& app_id) const = 0;
-  virtual absl::optional<SkColor> GetAppThemeColor(
-      const AppId& app_id) const = 0;
-  virtual absl::optional<SkColor> GetAppBackgroundColor(
-      const AppId& app_id) const = 0;
-  virtual const GURL& GetAppStartUrl(const AppId& app_id) const = 0;
-  virtual absl::optional<std::string> GetAppManifestId(
-      const AppId& app_id) const = 0;
-  virtual const std::string* GetAppLaunchQueryParams(
-      const AppId& app_id) const = 0;
-  virtual const apps::ShareTarget* GetAppShareTarget(
-      const AppId& app_id) const = 0;
-  virtual blink::mojom::CaptureLinks GetAppCaptureLinks(
-      const AppId& app_id) const = 0;
-  virtual const apps::FileHandlers* GetAppFileHandlers(
-      const AppId& app_id) const = 0;
-  virtual const apps::ProtocolHandlers* GetAppProtocolHandlers(
-      const AppId& app_id) const = 0;
-  virtual bool IsAppFileHandlerPermissionBlocked(const AppId& app_id) const = 0;
-
-  // Returns the start_url with launch_query_params appended to the end if any.
-  GURL GetAppLaunchUrl(const AppId& app_id) const;
-
-  // TODO(crbug.com/910016): Replace uses of this with GetAppScope().
-  virtual absl::optional<GURL> GetAppScopeInternal(
-      const AppId& app_id) const = 0;
-
-  virtual DisplayMode GetAppDisplayMode(const AppId& app_id) const = 0;
-  virtual DisplayMode GetAppUserDisplayMode(const AppId& app_id) const = 0;
-  virtual std::vector<DisplayMode> GetAppDisplayModeOverride(
-      const AppId& app_id) const = 0;
-
-  // Returns the "url_handlers" field from the app manifest.
-  virtual apps::UrlHandlers GetAppUrlHandlers(const AppId& app_id) const = 0;
-
-  virtual GURL GetAppManifestUrl(const AppId& app_id) const = 0;
-
-  virtual base::Time GetAppLastBadgingTime(const AppId& app_id) const = 0;
-  virtual base::Time GetAppLastLaunchTime(const AppId& app_id) const = 0;
-  virtual base::Time GetAppInstallTime(const AppId& app_id) const = 0;
-
-  // Returns the "icons" field from the app manifest, use |AppIconManager| to
-  // load icon bitmap data.
-  virtual std::vector<WebApplicationIconInfo> GetAppIconInfos(
-      const AppId& app_id) const = 0;
-
-  // Represents which icon sizes we successfully downloaded from the IconInfos.
-  virtual SortedSizesPx GetAppDownloadedIconSizesAny(
-      const AppId& app_id) const = 0;
-
-  // Returns the "shortcuts" field from the app manifest, use |AppIconManager|
-  // to load shortcuts menu icons bitmaps data.
-  virtual std::vector<WebApplicationShortcutsMenuItemInfo>
-  GetAppShortcutsMenuItemInfos(const AppId& app_id) const = 0;
-
-  // Returns the Run on OS Login mode.
-  virtual RunOnOsLoginMode GetAppRunOnOsLoginMode(
-      const AppId& app_id) const = 0;
-
-  // Represents which icon sizes we successfully downloaded from the
-  // ShortcutsMenuItemInfos.
-  virtual std::vector<IconSizes> GetAppDownloadedShortcutsMenuIconsSizes(
-      const AppId& app_id) const = 0;
-
-  virtual bool GetWindowControlsOverlayEnabled(const AppId& app_id) const = 0;
-
-  virtual std::vector<AppId> GetAppIds() const = 0;
-
-  // Safe downcast.
-  virtual WebAppRegistrar* AsWebAppRegistrar() = 0;
-  virtual const WebAppRegistrar* AsWebAppRegistrar() const = 0;
-
-  void SetSubsystems(OsIntegrationManager* os_integration_manager);
-
-  // Returns the "scope" field from the app manifest, or infers a scope from the
-  // "start_url" field if unavailable. Returns an invalid GURL iff the |app_id|
-  // does not refer to an installed web app.
-  GURL GetAppScope(const AppId& app_id) const;
-
-  // Returns the app id of an app in the registry with the longest scope that is
-  // a prefix of |url|, if any.
-  absl::optional<AppId> FindAppWithUrlInScope(const GURL& url) const;
-
-  // Returns true if there exists at least one app installed under |scope|.
-  bool DoesScopeContainAnyApp(const GURL& scope) const;
-
-  // Finds all apps that are installed under |scope|.
-  std::vector<AppId> FindAppsInScope(const GURL& scope) const;
-
-  // Returns the app id of an installed app in the registry with the longest
-  // scope that is a prefix of |url|, if any. If |window_only| is specified,
-  // only apps that open in app windows will be considered.
-  absl::optional<AppId> FindInstalledAppWithUrlInScope(
-      const GURL& url,
-      bool window_only = false) const;
-
-  // Returns whether the app is a shortcut app (as opposed to a PWA).
-  bool IsShortcutApp(const AppId& app_id) const;
-
-  // Returns true if the app with the specified |start_url| is currently fully
-  // locally installed. The provided |start_url| must exactly match the launch
-  // URL for the app; this method does not consult the app scope or match URLs
-  // that fall within the scope.
-  bool IsLocallyInstalled(const GURL& start_url) const;
-
-  // Returns whether the app is pending successful navigation in order to
-  // complete installation via the ExternallyManagedAppManager.
-  bool IsPlaceholderApp(const AppId& app_id) const;
-
-  // Computes and returns the DisplayMode, accounting for user preference
-  // to launch in a browser window and entries in the web app manifest.
-  DisplayMode GetAppEffectiveDisplayMode(const AppId& app_id) const;
-
-  // Computes and returns the DisplayMode only accounting for
-  // entries in the web app manifest.
-  DisplayMode GetEffectiveDisplayModeFromManifest(const AppId& app_id) const;
-
-  // Returns whether the app should be opened in tabbed window mode.
-  bool IsTabbedWindowModeEnabled(const AppId& app_id) const;
-
-  // TODO(crbug.com/897314): This can be removed once feature has launched.
-  bool IsInExperimentalTabbedWindowMode(const AppId& app_id) const;
-
-  void AddObserver(AppRegistrarObserver* observer);
-  void RemoveObserver(AppRegistrarObserver* observer);
-
-  void NotifyWebAppInstalled(const AppId& app_id);
-  void NotifyWebAppManifestUpdated(const AppId& app_id,
-                                   base::StringPiece old_name);
-  void NotifyWebAppsWillBeUpdatedFromSync(
-      const std::vector<const WebApp*>& new_apps_state);
-  void NotifyWebAppUninstalled(const AppId& app_id);
-  void NotifyWebAppWillBeUninstalled(const AppId& app_id);
-  void NotifyWebAppLocallyInstalledStateChanged(const AppId& app_id,
-                                                bool is_locally_installed);
-  void NotifyWebAppDisabledStateChanged(const AppId& app_id, bool is_disabled);
-  void NotifyWebAppsDisabledModeChanged();
-  void NotifyWebAppLastLaunchTimeChanged(const AppId& app_id,
-                                         const base::Time& time);
-  void NotifyWebAppInstallTimeChanged(const AppId& app_id,
-                                      const base::Time& time);
-
-  // Notify when OS hooks installation is finished during Web App installation.
-  void NotifyWebAppInstalledWithOsHooks(const AppId& app_id);
-  void NotifyWebAppUserDisplayModeChanged(const AppId& app_id,
-                                          DisplayMode user_display_mode);
-  void NotifyWebAppExperimentalTabbedWindowModeChanged(const AppId& app_id,
-                                                       bool enabled);
-
- protected:
-  Profile* profile() const { return profile_; }
-  OsIntegrationManager& os_integration_manager() {
-    return *os_integration_manager_;
-  }
-
-  void NotifyWebAppProfileWillBeDeleted(const AppId& app_id);
-  void NotifyAppRegistrarShutdown();
-
- private:
-  Profile* const profile_;
-
-  base::ObserverList<AppRegistrarObserver, /*check_empty=*/true> observers_;
-  OsIntegrationManager* os_integration_manager_ = nullptr;
-};
-
-}  // namespace web_app
-
-#endif  // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_APP_REGISTRAR_H_
diff --git a/chrome/browser/web_applications/components/app_registrar_observer.h b/chrome/browser/web_applications/components/app_registrar_observer.h
index 9307fa99..b8968f4f 100644
--- a/chrome/browser/web_applications/components/app_registrar_observer.h
+++ b/chrome/browser/web_applications/components/app_registrar_observer.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_APP_REGISTRAR_OBSERVER_H_
 
 #include "base/observer_list_types.h"
+#include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 
 namespace base {
@@ -36,12 +37,12 @@
       const std::vector<const WebApp*>& new_apps_state) {}
 
   // Called before a web app is uninstalled, before the uninstallation process
-  // begins. |app_id| is still registered in the AppRegistrar, and OS hooks have
-  // not yet been uninstalled.
+  // begins. |app_id| is still registered in the WebAppRegistrar, and OS hooks
+  // have not yet been uninstalled.
   virtual void OnWebAppWillBeUninstalled(const AppId& app_id) {}
 
   // Called after a web app is uninstalled. |app_id| is no longer registered in
-  // the AppRegistrar, all OS hooks are uninstalled, and icons have been
+  // the WebAppRegistrar, all OS hooks are uninstalled, and icons have been
   // deleted.
   virtual void OnWebAppUninstalled(const AppId& app_id) {}
 
diff --git a/chrome/browser/web_applications/components/app_registry_controller.h b/chrome/browser/web_applications/components/app_registry_controller.h
index f2a4117..f0eacae 100644
--- a/chrome/browser/web_applications/components/app_registry_controller.h
+++ b/chrome/browser/web_applications/components/app_registry_controller.h
@@ -22,7 +22,7 @@
 
 // A unified sync and storage controller.
 //
-// While AppRegistrar is a read-only model, AppRegistryController is a
+// While WebAppRegistrar is a read-only model, AppRegistryController is a
 // controller for that model. AppRegistryController is responsible for:
 // - Registry initialization (reading model from a persistent storage like
 // LevelDb or prefs).
diff --git a/chrome/browser/web_applications/components/app_shortcut_manager.h b/chrome/browser/web_applications/components/app_shortcut_manager.h
index 5f4410e..10c10311 100644
--- a/chrome/browser/web_applications/components/app_shortcut_manager.h
+++ b/chrome/browser/web_applications/components/app_shortcut_manager.h
@@ -20,7 +20,7 @@
 namespace web_app {
 
 class AppIconManager;
-class AppRegistrar;
+class WebAppRegistrar;
 struct ShortcutInfo;
 
 using ShortcutLocationCallback =
@@ -40,7 +40,7 @@
   AppShortcutManager& operator=(const AppShortcutManager&) = delete;
   virtual ~AppShortcutManager();
 
-  void SetSubsystems(AppIconManager* icon_manager, AppRegistrar* registrar);
+  void SetSubsystems(AppIconManager* icon_manager, WebAppRegistrar* registrar);
 
   void Start();
   void Shutdown();
@@ -115,7 +115,7 @@
                           DeleteShortcutsCallback callback,
                           bool success);
 
-  AppRegistrar* registrar() { return registrar_; }
+  WebAppRegistrar* registrar() { return registrar_; }
   Profile* profile() { return profile_; }
   bool suppress_shortcuts_for_testing() const {
     return suppress_shortcuts_for_testing_;
@@ -138,7 +138,7 @@
 
   bool suppress_shortcuts_for_testing_ = false;
 
-  AppRegistrar* registrar_ = nullptr;
+  WebAppRegistrar* registrar_ = nullptr;
   AppIconManager* icon_manager_ = nullptr;
   Profile* const profile_;
 
diff --git a/chrome/browser/web_applications/components/externally_managed_app_manager.h b/chrome/browser/web_applications/components/externally_managed_app_manager.h
index ce09b75f..eab3aba 100644
--- a/chrome/browser/web_applications/components/externally_managed_app_manager.h
+++ b/chrome/browser/web_applications/components/externally_managed_app_manager.h
@@ -21,7 +21,7 @@
 
 enum class InstallResultCode;
 
-class AppRegistrar;
+class WebAppRegistrar;
 class OsIntegrationManager;
 class InstallFinalizer;
 class InstallManager;
@@ -76,7 +76,7 @@
       delete;
   virtual ~ExternallyManagedAppManager();
 
-  void SetSubsystems(AppRegistrar* registrar,
+  void SetSubsystems(WebAppRegistrar* registrar,
                      OsIntegrationManager* os_integration_manager,
                      WebAppUiManager* ui_manager,
                      InstallFinalizer* finalizer,
@@ -146,7 +146,7 @@
   virtual void Shutdown() = 0;
 
  protected:
-  AppRegistrar* registrar() { return registrar_; }
+  WebAppRegistrar* registrar() { return registrar_; }
   OsIntegrationManager* os_integration_manager() {
     return os_integration_manager_;
   }
@@ -184,7 +184,7 @@
                                        bool succeeded);
   void OnAppSynchronized(ExternalInstallSource source, const GURL& app_url);
 
-  AppRegistrar* registrar_ = nullptr;
+  WebAppRegistrar* registrar_ = nullptr;
   OsIntegrationManager* os_integration_manager_ = nullptr;
   WebAppUiManager* ui_manager_ = nullptr;
   InstallFinalizer* finalizer_ = nullptr;
diff --git a/chrome/browser/web_applications/components/file_handler_manager.h b/chrome/browser/web_applications/components/file_handler_manager.h
index f4795a9..22249fe 100644
--- a/chrome/browser/web_applications/components/file_handler_manager.h
+++ b/chrome/browser/web_applications/components/file_handler_manager.h
@@ -23,7 +23,7 @@
 
 namespace web_app {
 
-class AppRegistrar;
+class WebAppRegistrar;
 
 class FileHandlerManager {
  public:
@@ -33,7 +33,7 @@
   virtual ~FileHandlerManager();
 
   // |registrar| is used to observe OnWebAppInstalled/Uninstalled events.
-  void SetSubsystems(AppRegistrar* registrar);
+  void SetSubsystems(WebAppRegistrar* registrar);
   void Start();
 
   // Disables OS integrations, such as shortcut creation on Linux or modifying
@@ -108,7 +108,7 @@
 
  protected:
   Profile* profile() const { return profile_; }
-  AppRegistrar* registrar() { return registrar_; }
+  WebAppRegistrar* registrar() { return registrar_; }
 
   // Gets all file handlers for |app_id|. |nullptr| if the app has no file
   // handlers or if app_id was uninstalled.
@@ -121,7 +121,7 @@
   base::RepeatingCallback<void()> on_file_handling_expiry_updated_for_testing_;
 
   Profile* const profile_;
-  AppRegistrar* registrar_ = nullptr;
+  WebAppRegistrar* registrar_ = nullptr;
 
   void OnOriginTrialExpiryTimeReceived(
       mojo::AssociatedRemote<blink::mojom::FileHandlingExpiry> /*interface*/,
diff --git a/chrome/browser/web_applications/components/install_finalizer.h b/chrome/browser/web_applications/components/install_finalizer.h
index 5ea721c9..3733d408 100644
--- a/chrome/browser/web_applications/components/install_finalizer.h
+++ b/chrome/browser/web_applications/components/install_finalizer.h
@@ -27,7 +27,7 @@
 
 enum class ExternalInstallSource;
 enum class InstallResultCode;
-class AppRegistrar;
+class WebAppRegistrar;
 class AppRegistryController;
 class WebAppUiManager;
 class OsIntegrationManager;
@@ -108,7 +108,7 @@
   virtual void Start() {}
   virtual void Shutdown() {}
 
-  void SetSubsystems(AppRegistrar* registrar,
+  void SetSubsystems(WebAppRegistrar* registrar,
                      WebAppUiManager* ui_manager,
                      AppRegistryController* registry_controller,
                      OsIntegrationManager* os_integration_manager);
@@ -117,7 +117,7 @@
 
  protected:
   bool is_legacy_finalizer() const { return registrar_ == nullptr; }
-  AppRegistrar& registrar() const;
+  WebAppRegistrar& registrar() const;
 
   WebAppUiManager& ui_manager() const { return *ui_manager_; }
   AppRegistryController& registry_controller() { return *registry_controller_; }
@@ -128,7 +128,7 @@
  private:
   // If these pointers are nullptr then this is legacy install finalizer
   // operating in standalone mode.
-  AppRegistrar* registrar_ = nullptr;
+  WebAppRegistrar* registrar_ = nullptr;
   AppRegistryController* registry_controller_ = nullptr;
   WebAppUiManager* ui_manager_ = nullptr;
   OsIntegrationManager* os_integration_manager_ = nullptr;
diff --git a/chrome/browser/web_applications/components/install_manager.h b/chrome/browser/web_applications/components/install_manager.h
index ee4cbb8..5972136e 100644
--- a/chrome/browser/web_applications/components/install_manager.h
+++ b/chrome/browser/web_applications/components/install_manager.h
@@ -33,7 +33,7 @@
 
 enum class InstallResultCode;
 class InstallFinalizer;
-class AppRegistrar;
+class WebAppRegistrar;
 class OsIntegrationManager;
 
 // TODO(loyso): Rework this interface. Unify the API and merge similar
@@ -174,7 +174,7 @@
   explicit InstallManager(Profile* profile);
   virtual ~InstallManager();
 
-  void SetSubsystems(AppRegistrar* registrar,
+  void SetSubsystems(WebAppRegistrar* registrar,
                      OsIntegrationManager* os_integration_manager,
                      InstallFinalizer* finalizer);
 
@@ -192,7 +192,7 @@
 
  protected:
   Profile* profile() { return profile_; }
-  AppRegistrar* registrar() { return registrar_; }
+  WebAppRegistrar* registrar() { return registrar_; }
   OsIntegrationManager* os_integration_manager() {
     return os_integration_manager_;
   }
@@ -206,7 +206,7 @@
   Profile* const profile_;
   WebAppUrlLoader url_loader_;
 
-  AppRegistrar* registrar_ = nullptr;
+  WebAppRegistrar* registrar_ = nullptr;
   OsIntegrationManager* os_integration_manager_ = nullptr;
   InstallFinalizer* finalizer_ = nullptr;
 
diff --git a/chrome/browser/web_applications/components/os_integration_manager.h b/chrome/browser/web_applications/components/os_integration_manager.h
index 2aeede4..3e49677 100644
--- a/chrome/browser/web_applications/components/os_integration_manager.h
+++ b/chrome/browser/web_applications/components/os_integration_manager.h
@@ -32,7 +32,7 @@
 
 namespace web_app {
 
-class AppRegistrar;
+class WebAppRegistrar;
 class AppIconManager;
 class TestOsIntegrationManager;
 class WebAppUiManager;
@@ -79,7 +79,7 @@
       std::unique_ptr<UrlHandlerManager> url_handler_manager);
   virtual ~OsIntegrationManager();
 
-  void SetSubsystems(AppRegistrar* registrar,
+  void SetSubsystems(WebAppRegistrar* registrar,
                      WebAppUiManager* ui_manager,
                      AppIconManager* icon_manager);
 
@@ -277,7 +277,7 @@
       std::unique_ptr<ShortcutInfo> info);
 
   Profile* const profile_;
-  AppRegistrar* registrar_ = nullptr;
+  WebAppRegistrar* registrar_ = nullptr;
   WebAppUiManager* ui_manager_ = nullptr;
 
   std::unique_ptr<AppShortcutManager> shortcut_manager_;
diff --git a/chrome/browser/web_applications/components/protocol_handler_manager.h b/chrome/browser/web_applications/components/protocol_handler_manager.h
index a0559b1..678fb633 100644
--- a/chrome/browser/web_applications/components/protocol_handler_manager.h
+++ b/chrome/browser/web_applications/components/protocol_handler_manager.h
@@ -19,7 +19,7 @@
 // TODO(crbug.com/1225132): Clean this up and include web_app_id.h.
 using AppId = std::string;
 
-class AppRegistrar;
+class WebAppRegistrar;
 
 class ProtocolHandlerManager {
  public:
@@ -29,7 +29,7 @@
   virtual ~ProtocolHandlerManager();
 
   // |registrar| is used to observe OnWebAppInstalled/Uninstalled events.
-  void SetSubsystems(AppRegistrar* registrar);
+  void SetSubsystems(WebAppRegistrar* registrar);
   void Start();
 
   // If a protocol handler matching the scheme of |protocol_url| is installed
@@ -67,7 +67,7 @@
   void UnregisterOsProtocolHandlers(const AppId& app_id,
                                     base::OnceCallback<void(bool)> callback);
 
-  AppRegistrar* app_registrar_;
+  WebAppRegistrar* app_registrar_;
 
  private:
   Profile* const profile_;
diff --git a/chrome/browser/web_applications/components/url_handler_manager.h b/chrome/browser/web_applications/components/url_handler_manager.h
index 8f4cd4e..345f86e4 100644
--- a/chrome/browser/web_applications/components/url_handler_manager.h
+++ b/chrome/browser/web_applications/components/url_handler_manager.h
@@ -15,7 +15,7 @@
 
 namespace web_app {
 
-class AppRegistrar;
+class WebAppRegistrar;
 
 // UrlHandlerManager allows different manager implementations: local state
 // prefs, App Service, and OS-specific implementations to enable integration
@@ -29,7 +29,7 @@
   UrlHandlerManager(const UrlHandlerManager&) = delete;
   UrlHandlerManager& operator=(const UrlHandlerManager&) = delete;
 
-  void SetSubsystems(AppRegistrar* const registrar);
+  void SetSubsystems(WebAppRegistrar* const registrar);
 
   // Returns true if registration succeeds, false otherwise.
   virtual void RegisterUrlHandlers(
@@ -47,14 +47,14 @@
 
  protected:
   Profile* profile() const { return profile_; }
-  AppRegistrar* registrar() const { return registrar_; }
+  WebAppRegistrar* registrar() const { return registrar_; }
   WebAppOriginAssociationManager& association_manager() {
     return *association_manager_;
   }
 
  private:
   Profile* const profile_;
-  AppRegistrar* registrar_;
+  WebAppRegistrar* registrar_;
   std::unique_ptr<WebAppOriginAssociationManager> association_manager_;
 };
 
diff --git a/chrome/browser/web_applications/components/web_app_file_handler_registration_linux_browsertest.cc b/chrome/browser/web_applications/components/web_app_file_handler_registration_linux_browsertest.cc
index ae6851d..f9e5620 100644
--- a/chrome/browser/web_applications/components/web_app_file_handler_registration_linux_browsertest.cc
+++ b/chrome/browser/web_applications/components/web_app_file_handler_registration_linux_browsertest.cc
@@ -15,11 +15,11 @@
 #include "chrome/browser/shell_integration_linux.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/services/app_service/public/cpp/file_handler.h"
 #include "content/public/test/browser_test.h"
@@ -57,9 +57,8 @@
         blink::features::kFileHandlingAPI);
   }
 
-  AppRegistrar& registrar() {
-    return WebAppProviderBase::GetProviderBase(browser()->profile())
-        ->registrar();
+  WebAppRegistrar& registrar() {
+    return WebAppProvider::GetForWebApps(browser()->profile())->registrar();
   }
 
   void InstallApp(ExternalInstallOptions install_options) {
diff --git a/chrome/browser/web_applications/components/web_app_provider_base.cc b/chrome/browser/web_applications/components/web_app_provider_base.cc
deleted file mode 100644
index 6e4eb6c..0000000
--- a/chrome/browser/web_applications/components/web_app_provider_base.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
-
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base_factory.h"
-
-namespace web_app {
-
-// static
-WebAppProviderBase* WebAppProviderBase::GetProviderBase(Profile* profile) {
-  return WebAppProviderBaseFactory::GetForProfile(profile);
-}
-
-WebAppProviderBase::WebAppProviderBase() = default;
-
-WebAppProviderBase::~WebAppProviderBase() = default;
-
-}  // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_provider_base.h b/chrome/browser/web_applications/components/web_app_provider_base.h
deleted file mode 100644
index de6338b..0000000
--- a/chrome/browser/web_applications/components/web_app_provider_base.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_H_
-#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_H_
-
-#include "components/keyed_service/core/keyed_service.h"
-
-class Profile;
-
-namespace web_app {
-
-// Forward declarations of generalized interfaces.
-class AppIconManager;
-class AppRegistrar;
-class AppRegistryController;
-class InstallFinalizer;
-class InstallManager;
-class ManifestUpdateManager;
-class ExternallyManagedAppManager;
-class SystemWebAppManager;
-class WebAppAudioFocusIdMap;
-class WebAppPolicyManager;
-class WebAppUiManager;
-class SystemWebAppManager;
-class OsIntegrationManager;
-
-class WebAppProviderBase : public KeyedService {
- public:
-  static WebAppProviderBase* GetProviderBase(Profile* profile);
-
-  WebAppProviderBase();
-  WebAppProviderBase(const WebAppProviderBase&) = delete;
-  WebAppProviderBase& operator=(const WebAppProviderBase&) = delete;
-  ~WebAppProviderBase() override;
-
-  // The app registry model.
-  virtual AppRegistrar& registrar() = 0;
-  // The app registry controller.
-  virtual AppRegistryController& registry_controller() = 0;
-  // UIs can use InstallManager for user-initiated Web Apps install.
-  virtual InstallManager& install_manager() = 0;
-  // Implements persistence for Web Apps install.
-  virtual InstallFinalizer& install_finalizer() = 0;
-  // Keeps app metadata up to date with site manifests.
-  virtual ManifestUpdateManager& manifest_update_manager() = 0;
-  // Clients can use ExternallyManagedAppManager to install, uninstall, and
-  // update Web Apps.
-  virtual ExternallyManagedAppManager& externally_managed_app_manager() = 0;
-  // Clients can use WebAppPolicyManager to request updates of policy installed
-  // Web Apps.
-  virtual WebAppPolicyManager& policy_manager() = 0;
-
-  virtual WebAppUiManager& ui_manager() = 0;
-
-  virtual WebAppAudioFocusIdMap& audio_focus_id_map() = 0;
-
-  // Implements fetching of app icons.
-  virtual AppIconManager& icon_manager() = 0;
-
-  virtual SystemWebAppManager& system_web_app_manager() = 0;
-
-  // Manage all OS hooks that need to be deployed during Web Apps install
-  virtual OsIntegrationManager& os_integration_manager() = 0;
-
-};
-
-}  // namespace web_app
-
-#endif  // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_H_
diff --git a/chrome/browser/web_applications/components/web_app_provider_base_factory.cc b/chrome/browser/web_applications/components/web_app_provider_base_factory.cc
deleted file mode 100644
index 0c4eb01..0000000
--- a/chrome/browser/web_applications/components/web_app_provider_base_factory.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/web_applications/components/web_app_provider_base_factory.h"
-
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
-
-namespace web_app {
-
-namespace {
-WebAppProviderBaseFactory* g_factory = nullptr;
-}  // namespace
-
-// static
-WebAppProviderBase* WebAppProviderBaseFactory::GetForProfile(Profile* profile) {
-  return static_cast<WebAppProviderBase*>(
-      GetInstance()->GetServiceForBrowserContext(profile, /* create=*/true));
-}
-
-// static
-WebAppProviderBaseFactory* WebAppProviderBaseFactory::GetInstance() {
-  DCHECK(g_factory);
-  return g_factory;
-}
-
-// static
-void WebAppProviderBaseFactory::SetInstance(
-    WebAppProviderBaseFactory* factory) {
-  g_factory = factory;
-}
-
-WebAppProviderBaseFactory::WebAppProviderBaseFactory(
-    const char* service_name,
-    BrowserContextDependencyManager* dependency_manager)
-    : BrowserContextKeyedServiceFactory(service_name, dependency_manager) {}
-
-WebAppProviderBaseFactory::~WebAppProviderBaseFactory() = default;
-
-}  //  namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_provider_base_factory.h b/chrome/browser/web_applications/components/web_app_provider_base_factory.h
deleted file mode 100644
index 2deecff..0000000
--- a/chrome/browser/web_applications/components/web_app_provider_base_factory.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_FACTORY_H_
-#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_FACTORY_H_
-
-#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
-
-class BrowserContextDependencyManager;
-class Profile;
-
-namespace web_app {
-
-class WebAppProviderBase;
-
-// Singleton that associates WebAppProviderBase with Profile.
-class WebAppProviderBaseFactory : public BrowserContextKeyedServiceFactory {
- public:
-  WebAppProviderBaseFactory(const WebAppProviderBaseFactory&) = delete;
-  WebAppProviderBaseFactory& operator=(const WebAppProviderBaseFactory&) =
-      delete;
-
-  static WebAppProviderBase* GetForProfile(Profile* profile);
-
-  static WebAppProviderBaseFactory* GetInstance();
-  static void SetInstance(WebAppProviderBaseFactory* factory);
-
- protected:
-  WebAppProviderBaseFactory(
-      const char* service_name,
-      BrowserContextDependencyManager* dependency_manager);
-  ~WebAppProviderBaseFactory() override;
-
-};
-
-}  // namespace web_app
-
-#endif  // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_PROVIDER_BASE_FACTORY_H_
diff --git a/chrome/browser/web_applications/docs/testing.md b/chrome/browser/web_applications/docs/testing.md
index cf4ac0e2..7475e1135 100644
--- a/chrome/browser/web_applications/docs/testing.md
+++ b/chrome/browser/web_applications/docs/testing.md
@@ -69,7 +69,7 @@
 
 The [`TestWebAppProvider`](../test/test_web_app_provider.h) is a nifty way to mock out pieces of the WebAppProvider system for a browser test. To use it, you put a [`TestWebAppProviderCreator`](../test/test_web_app_provider.h) in your test class, and give it a callback to create a `WebAppProvider` given a `Profile`. This allows you to create a [`TestWebAppProvider`](../test/test_web_app_provider.h) instead of the regular `WebAppProvider`, swapping out any part of the system.
 
-This means that all of the users of [`WebAppProvider::Get`](https://source.chromium.org/search?q=WebAppProvider::Get), [`WebAppProvider::GetForWebContents`](https://source.chromium.org/search?q=WebAppProvider::Get), and [`WebAppProviderBase::Get`](https://source.chromium.org/search?q=WebAppProviderBase::Get) (etc) will be talking to the `TestWebAppProvider` that the test created. This is perfect for a browsertest, as it runs the full browser.
+This means that all of the users of [`WebAppProvider::Get`](https://source.chromium.org/search?q=WebAppProvider::Get), [`WebAppProvider::GetForWebContents`](https://source.chromium.org/search?q=WebAppProvider::Get) (etc) will be talking to the `TestWebAppProvider` that the test created. This is perfect for a browsertest, as it runs the full browser.
 
 The other difference between this and the [`TestWebAppRegistryController`](#tool-testwebappregistrycontroller) above is that this, without any changes (and as long as the user calls `Start()`), will run the normal production `WebAppProvider` system. This means changes are written to disk, the OS integrations are triggered, etc.
 
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_util.cc b/chrome/browser/web_applications/extensions/bookmark_app_util.cc
index a340832..7a2ce9de 100644
--- a/chrome/browser/web_applications/extensions/bookmark_app_util.cc
+++ b/chrome/browser/web_applications/extensions/bookmark_app_util.cc
@@ -10,8 +10,8 @@
 
 #include "base/strings/string_piece.h"
 #include "base/values.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
diff --git a/chrome/browser/web_applications/extensions/externally_managed_app_install_task_unittest.cc b/chrome/browser/web_applications/extensions/externally_managed_app_install_task_unittest.cc
index acb134b..a675146 100644
--- a/chrome/browser/web_applications/extensions/externally_managed_app_install_task_unittest.cc
+++ b/chrome/browser/web_applications/extensions/externally_managed_app_install_task_unittest.cc
@@ -21,13 +21,11 @@
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_data_retriever.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/test_data_retriever.h"
 #include "chrome/browser/web_applications/test/test_install_finalizer.h"
@@ -37,6 +35,7 @@
 #include "chrome/browser/web_applications/test/test_web_app_url_loader.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_install_manager.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc b/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc
index f24eb2f8..10e4dc5 100644
--- a/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc
+++ b/chrome/browser/web_applications/extensions/web_app_extension_shortcut.cc
@@ -19,10 +19,10 @@
 #include "chrome/browser/extensions/extension_ui_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
@@ -114,7 +114,7 @@
     const extensions::Extension* extension = registry->GetExtensionById(
         shortcut_info->extension_id, extensions::ExtensionRegistry::EVERYTHING);
     bool is_app_installed = false;
-    auto* app_provider = WebAppProviderBase::GetProviderBase(profile);
+    auto* app_provider = WebAppProvider::GetForWebApps(profile);
     if (app_provider &&
         app_provider->registrar().IsInstalled(shortcut_info->extension_id)) {
       is_app_installed = true;
@@ -199,7 +199,7 @@
   if (app->from_bookmark()) {
     shortcut_info->is_multi_profile = true;
     OsIntegrationManager& os_integration_manager =
-        WebAppProviderBase::GetProviderBase(profile)->os_integration_manager();
+        WebAppProvider::GetForWebApps(profile)->os_integration_manager();
     if (const auto* file_handlers =
             os_integration_manager.GetEnabledFileHandlers(app->id())) {
       shortcut_info->file_handler_extensions =
@@ -264,7 +264,7 @@
                               CreateShortcutsCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  WebAppProviderBase::GetProviderBase(profile)
+  WebAppProvider::GetForWebApps(profile)
       ->os_integration_manager()
       .GetShortcutInfoForApp(
           app_id, base::BindOnce(&CreateShortcutsWithInfo, reason, locations,
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
index 57a0899..fce6156 100644
--- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
+++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/values.h"
 #include "chrome/browser/prefs/browser_prefs.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/externally_managed_app_manager.h"
 #include "chrome/browser/web_applications/components/policy/web_app_policy_constants.h"
@@ -827,7 +826,7 @@
 
   // There should be exactly 1 app remaining.
   std::map<AppId, GURL> apps =
-      WebAppProviderBase::GetProviderBase(profile())
+      WebAppProvider::GetForWebApps(profile())
           ->registrar()
           .GetExternallyInstalledApps(ExternalInstallSource::kExternalPolicy);
   EXPECT_EQ(1u, apps.size());
diff --git a/chrome/browser/web_applications/extensions/web_app_provider_unittest.cc b/chrome/browser/web_applications/extensions/web_app_provider_unittest.cc
index 4c99453..19aab352 100644
--- a/chrome/browser/web_applications/extensions/web_app_provider_unittest.cc
+++ b/chrome/browser/web_applications/extensions/web_app_provider_unittest.cc
@@ -29,7 +29,7 @@
 };
 
 TEST_F(WebAppProviderUnitTest, Registrar) {
-  AppRegistrar& registrar = provider()->registrar();
+  WebAppRegistrar& registrar = provider()->registrar();
   EXPECT_FALSE(registrar.IsInstalled("unknown"));
 }
 
diff --git a/chrome/browser/web_applications/externally_installed_web_app_prefs.cc b/chrome/browser/web_applications/externally_installed_web_app_prefs.cc
index 0ca3ea3..1fd2261 100644
--- a/chrome/browser/web_applications/externally_installed_web_app_prefs.cc
+++ b/chrome/browser/web_applications/externally_installed_web_app_prefs.cc
@@ -9,8 +9,8 @@
 #include <vector>
 
 #include "base/values.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/web_applications/externally_managed_app_install_task.cc b/chrome/browser/web_applications/externally_managed_app_install_task.cc
index 5ff9aed..7d69b743 100644
--- a/chrome/browser/web_applications/externally_managed_app_install_task.cc
+++ b/chrome/browser/web_applications/externally_managed_app_install_task.cc
@@ -40,7 +40,7 @@
 ExternallyManagedAppInstallTask::ExternallyManagedAppInstallTask(
     Profile* profile,
     WebAppUrlLoader* url_loader,
-    AppRegistrar* registrar,
+    WebAppRegistrar* registrar,
     OsIntegrationManager* os_integration_manager,
     WebAppUiManager* ui_manager,
     InstallFinalizer* install_finalizer,
diff --git a/chrome/browser/web_applications/externally_managed_app_install_task.h b/chrome/browser/web_applications/externally_managed_app_install_task.h
index 605f996..c25d176 100644
--- a/chrome/browser/web_applications/externally_managed_app_install_task.h
+++ b/chrome/browser/web_applications/externally_managed_app_install_task.h
@@ -8,7 +8,6 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
 #include "chrome/browser/web_applications/components/externally_managed_app_manager.h"
@@ -17,6 +16,7 @@
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
 #include "chrome/browser/web_applications/components/web_app_url_loader.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
@@ -52,7 +52,7 @@
   explicit ExternallyManagedAppInstallTask(
       Profile* profile,
       WebAppUrlLoader* url_loader,
-      AppRegistrar* registrar,
+      WebAppRegistrar* registrar,
       OsIntegrationManager* os_integration_manager,
       WebAppUiManager* ui_manager,
       InstallFinalizer* install_finalizer,
@@ -110,7 +110,7 @@
 
   Profile* const profile_;
   WebAppUrlLoader* const url_loader_;
-  AppRegistrar* const registrar_;
+  WebAppRegistrar* const registrar_;
   OsIntegrationManager* const os_integration_manager_;
   InstallFinalizer* const install_finalizer_;
   InstallManager* const install_manager_;
diff --git a/chrome/browser/web_applications/externally_managed_app_manager.cc b/chrome/browser/web_applications/externally_managed_app_manager.cc
index b296c579..ea5c224b 100644
--- a/chrome/browser/web_applications/externally_managed_app_manager.cc
+++ b/chrome/browser/web_applications/externally_managed_app_manager.cc
@@ -13,8 +13,8 @@
 #include "base/containers/contains.h"
 #include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 
 namespace web_app {
 
@@ -46,7 +46,7 @@
 }
 
 void ExternallyManagedAppManager::SetSubsystems(
-    AppRegistrar* registrar,
+    WebAppRegistrar* registrar,
     OsIntegrationManager* os_integration_manager,
     WebAppUiManager* ui_manager,
     InstallFinalizer* finalizer,
diff --git a/chrome/browser/web_applications/externally_managed_app_manager_impl.cc b/chrome/browser/web_applications/externally_managed_app_manager_impl.cc
index cdb9ca13..422722b 100644
--- a/chrome/browser/web_applications/externally_managed_app_manager_impl.cc
+++ b/chrome/browser/web_applications/externally_managed_app_manager_impl.cc
@@ -14,11 +14,11 @@
 #include "base/feature_list.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_ui_manager.h"
 #include "chrome/browser/web_applications/externally_managed_app_registration_task.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
diff --git a/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc b/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
index d85b5ad..d968fa1 100644
--- a/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
+++ b/chrome/browser/web_applications/externally_managed_app_manager_impl_browsertest.cc
@@ -12,14 +12,14 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/externally_managed_app_registration_task.h"
 #include "chrome/browser/web_applications/test/web_app_registration_waiter.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/service_worker_context.h"
 #include "content/public/browser/storage_partition.h"
@@ -41,13 +41,12 @@
         OsIntegrationManager::ScopedSuppressOsHooksForTesting();
   }
 
-  AppRegistrar& registrar() {
-    return WebAppProviderBase::GetProviderBase(browser()->profile())
-        ->registrar();
+  WebAppRegistrar& registrar() {
+    return WebAppProvider::GetForWebApps(browser()->profile())->registrar();
   }
 
   ExternallyManagedAppManager& externally_managed_app_manager() {
-    return WebAppProviderBase::GetProviderBase(browser()->profile())
+    return WebAppProvider::GetForWebApps(browser()->profile())
         ->externally_managed_app_manager();
   }
 
@@ -180,7 +179,7 @@
       embedded_test_server()->GetURL("/banners/manifest_test_page.html"));
 
   // Start an installation but don't wait for it to finish.
-  WebAppProviderBase::GetProviderBase(browser()->profile())
+  WebAppProvider::GetForWebApps(browser()->profile())
       ->externally_managed_app_manager()
       .Install(std::move(install_options), base::DoNothing());
 
diff --git a/chrome/browser/web_applications/file_handler_manager.cc b/chrome/browser/web_applications/file_handler_manager.cc
index 44f2002..8950f83 100644
--- a/chrome/browser/web_applications/file_handler_manager.cc
+++ b/chrome/browser/web_applications/file_handler_manager.cc
@@ -11,9 +11,9 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_file_handler_registration.h"
 #include "chrome/browser/web_applications/components/web_app_prefs_utils.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
@@ -45,7 +45,7 @@
 
 FileHandlerManager::~FileHandlerManager() = default;
 
-void FileHandlerManager::SetSubsystems(AppRegistrar* registrar) {
+void FileHandlerManager::SetSubsystems(WebAppRegistrar* registrar) {
   registrar_ = registrar;
 }
 
diff --git a/chrome/browser/web_applications/file_handlers_permission_helper.h b/chrome/browser/web_applications/file_handlers_permission_helper.h
index 93336ee..e8a17bf 100644
--- a/chrome/browser/web_applications/file_handlers_permission_helper.h
+++ b/chrome/browser/web_applications/file_handlers_permission_helper.h
@@ -6,9 +6,9 @@
 #define CHROME_BROWSER_WEB_APPLICATIONS_FILE_HANDLERS_PERMISSION_HELPER_H_
 
 #include "base/scoped_observation.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/content_settings/core/browser/content_settings_observer.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 
@@ -76,7 +76,7 @@
 
   base::ScopedObservation<HostContentSettingsMap, content_settings::Observer>
       content_settings_observer_{this};
-  base::ScopedObservation<AppRegistrar, AppRegistrarObserver>
+  base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver>
       app_registrar_observer_{this};
 };
 
diff --git a/chrome/browser/web_applications/install_finalizer.cc b/chrome/browser/web_applications/install_finalizer.cc
index ebaf40e..411687d 100644
--- a/chrome/browser/web_applications/install_finalizer.cc
+++ b/chrome/browser/web_applications/install_finalizer.cc
@@ -10,10 +10,10 @@
 #include "base/callback.h"
 #include "base/logging.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_ui_manager.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace web_app {
@@ -43,7 +43,7 @@
 }
 
 void InstallFinalizer::SetSubsystems(
-    AppRegistrar* registrar,
+    WebAppRegistrar* registrar,
     WebAppUiManager* ui_manager,
     AppRegistryController* registry_controller,
     OsIntegrationManager* os_integration_manager) {
@@ -72,7 +72,7 @@
                                              shortcut_created);
 }
 
-AppRegistrar& InstallFinalizer::registrar() const {
+WebAppRegistrar& InstallFinalizer::registrar() const {
   DCHECK(!is_legacy_finalizer());
   return *registrar_;
 }
diff --git a/chrome/browser/web_applications/install_manager.cc b/chrome/browser/web_applications/install_manager.cc
index 470d51a..ac600bce 100644
--- a/chrome/browser/web_applications/install_manager.cc
+++ b/chrome/browser/web_applications/install_manager.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/web_applications/components/install_manager.h"
 
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 
 namespace web_app {
 
@@ -19,7 +19,7 @@
 
 InstallManager::~InstallManager() = default;
 
-void InstallManager::SetSubsystems(AppRegistrar* registrar,
+void InstallManager::SetSubsystems(WebAppRegistrar* registrar,
                                    OsIntegrationManager* os_integration_manager,
                                    InstallFinalizer* finalizer) {
   registrar_ = registrar;
diff --git a/chrome/browser/web_applications/manifest_update_manager.cc b/chrome/browser/web_applications/manifest_update_manager.cc
index 17f61e3..8714601e 100644
--- a/chrome/browser/web_applications/manifest_update_manager.cc
+++ b/chrome/browser/web_applications/manifest_update_manager.cc
@@ -10,7 +10,6 @@
 #include "base/util/values/values_util.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
@@ -29,7 +28,7 @@
 ManifestUpdateManager::~ManifestUpdateManager() = default;
 
 void ManifestUpdateManager::SetSubsystems(
-    AppRegistrar* registrar,
+    WebAppRegistrar* registrar,
     AppIconManager* icon_manager,
     WebAppUiManager* ui_manager,
     InstallManager* install_manager,
diff --git a/chrome/browser/web_applications/manifest_update_manager.h b/chrome/browser/web_applications/manifest_update_manager.h
index 4d223aa..185f87b 100644
--- a/chrome/browser/web_applications/manifest_update_manager.h
+++ b/chrome/browser/web_applications/manifest_update_manager.h
@@ -11,10 +11,10 @@
 #include "base/containers/flat_map.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/manifest_update_task.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
@@ -44,7 +44,7 @@
   ManifestUpdateManager();
   ~ManifestUpdateManager() override;
 
-  void SetSubsystems(AppRegistrar* registrar,
+  void SetSubsystems(WebAppRegistrar* registrar,
                      AppIconManager* icon_manager,
                      WebAppUiManager* ui_manager,
                      InstallManager* install_manager,
@@ -85,14 +85,14 @@
                     const AppId& app_id,
                     ManifestUpdateResult result);
 
-  AppRegistrar* registrar_ = nullptr;
+  WebAppRegistrar* registrar_ = nullptr;
   AppIconManager* icon_manager_ = nullptr;
   WebAppUiManager* ui_manager_ = nullptr;
   InstallManager* install_manager_ = nullptr;
   SystemWebAppManager* system_web_app_manager_ = nullptr;
   OsIntegrationManager* os_integration_manager_ = nullptr;
 
-  base::ScopedObservation<AppRegistrar, AppRegistrarObserver>
+  base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver>
       registrar_observation_{this};
 
   base::flat_map<AppId, std::unique_ptr<ManifestUpdateTask>> tasks_;
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
index 00b95cc..7a95802 100644
--- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
+++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -29,13 +29,13 @@
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
 #include "chrome/browser/web_applications/test/web_app_test.h"
 #include "chrome/browser/web_applications/test/web_app_test_utils.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -150,7 +150,7 @@
     SkColorSetRGB(0x5C, 0x5C, 0x5C);
 
 ManifestUpdateManager& GetManifestUpdateManager(Browser* browser) {
-  return WebAppProviderBase::GetProviderBase(browser->profile())
+  return WebAppProvider::GetForWebApps(browser->profile())
       ->manifest_update_manager();
 }
 
@@ -347,8 +347,8 @@
     return std::move(awaiter).AwaitNextResult();
   }
 
-  WebAppProviderBase& GetProvider() {
-    return *WebAppProviderBase::GetProviderBase(browser()->profile());
+  WebAppProvider& GetProvider() {
+    return *WebAppProvider::GetForWebApps(browser()->profile());
   }
 
  protected:
diff --git a/chrome/browser/web_applications/manifest_update_task.cc b/chrome/browser/web_applications/manifest_update_task.cc
index 1ef572c..99c132e 100644
--- a/chrome/browser/web_applications/manifest_update_task.cc
+++ b/chrome/browser/web_applications/manifest_update_task.cc
@@ -13,7 +13,6 @@
 #include "base/feature_list.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
@@ -68,7 +67,7 @@
 
 // Some apps, such as pre-installed apps, have been vetted and are therefore
 // considered safe and permitted to update their names.
-bool AllowNameUpdating(const AppId& app_id, const AppRegistrar& registrar) {
+bool AllowNameUpdating(const AppId& app_id, const WebAppRegistrar& registrar) {
   const WebApp* web_app = registrar.AsWebAppRegistrar()->GetAppById(app_id);
   if (!web_app)
     return false;
@@ -78,7 +77,7 @@
 // Some apps, such as pre-installed apps, have been vetted and are therefore
 // considered safe and permitted to update their icon. For others, the feature
 // flag needs to be on.
-bool AllowIconUpdating(const AppId& app_id, const AppRegistrar& registrar) {
+bool AllowIconUpdating(const AppId& app_id, const WebAppRegistrar& registrar) {
   const WebApp* web_app = registrar.AsWebAppRegistrar()->GetAppById(app_id);
   if (!web_app)
     return false;
@@ -168,7 +167,7 @@
     content::WebContents* web_contents,
     StoppedCallback stopped_callback,
     bool hang_for_testing,
-    const AppRegistrar& registrar,
+    const WebAppRegistrar& registrar,
     const AppIconManager& icon_manager,
     WebAppUiManager* ui_manager,
     InstallManager* install_manager,
diff --git a/chrome/browser/web_applications/manifest_update_task.h b/chrome/browser/web_applications/manifest_update_task.h
index bf1f07541..3ad7db9a 100644
--- a/chrome/browser/web_applications/manifest_update_task.h
+++ b/chrome/browser/web_applications/manifest_update_task.h
@@ -42,7 +42,7 @@
     const std::vector<blink::Manifest::ProtocolHandler>& new_handlers);
 
 class AppIconManager;
-class AppRegistrar;
+class WebAppRegistrar;
 class WebAppUiManager;
 class InstallManager;
 class OsIntegrationManager;
@@ -95,7 +95,7 @@
                      content::WebContents* web_contents,
                      StoppedCallback stopped_callback,
                      bool hang_for_testing,
-                     const AppRegistrar& registrar,
+                     const WebAppRegistrar& registrar,
                      const AppIconManager& icon_manager,
                      WebAppUiManager* ui_manager,
                      InstallManager* install_manager,
@@ -146,7 +146,7 @@
       InstallResultCode code);
   void DestroySelf(ManifestUpdateResult result);
 
-  const AppRegistrar& registrar_;
+  const WebAppRegistrar& registrar_;
   const AppIconManager& icon_manager_;
   WebAppUiManager& ui_manager_;
   InstallManager& install_manager_;
diff --git a/chrome/browser/web_applications/os_integration_manager.cc b/chrome/browser/web_applications/os_integration_manager.cc
index dc558f5..5c03b885 100644
--- a/chrome/browser/web_applications/os_integration_manager.cc
+++ b/chrome/browser/web_applications/os_integration_manager.cc
@@ -21,12 +21,12 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/components/web_app_shortcut.h"
 #include "chrome/browser/web_applications/components/web_app_ui_manager.h"
 #include "chrome/browser/web_applications/components/web_app_uninstallation_via_os_settings_registration.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -102,7 +102,7 @@
 
 OsIntegrationManager::~OsIntegrationManager() = default;
 
-void OsIntegrationManager::SetSubsystems(AppRegistrar* registrar,
+void OsIntegrationManager::SetSubsystems(WebAppRegistrar* registrar,
                                          WebAppUiManager* ui_manager,
                                          AppIconManager* icon_manager) {
   registrar_ = registrar;
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
index 944bb94..1f75e45 100644
--- a/chrome/browser/web_applications/policy/web_app_policy_manager.cc
+++ b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
@@ -15,7 +15,6 @@
 #include "base/syslog_logging.h"
 #include "base/values.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
@@ -24,6 +23,7 @@
 #include "chrome/browser/web_applications/components/web_app_id_constants.h"
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
@@ -98,7 +98,7 @@
 
 void WebAppPolicyManager::SetSubsystems(
     ExternallyManagedAppManager* externally_managed_app_manager,
-    AppRegistrar* app_registrar,
+    WebAppRegistrar* app_registrar,
     AppRegistryController* app_registry_controller,
     SystemWebAppManager* web_app_manager,
     OsIntegrationManager* os_integration_manager) {
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.h b/chrome/browser/web_applications/policy/web_app_policy_manager.h
index 74203dc..901dec6 100644
--- a/chrome/browser/web_applications/policy/web_app_policy_manager.h
+++ b/chrome/browser/web_applications/policy/web_app_policy_manager.h
@@ -52,7 +52,7 @@
 
   void SetSubsystems(
       ExternallyManagedAppManager* externally_managed_app_manager,
-      AppRegistrar* app_registrar,
+      WebAppRegistrar* app_registrar,
       AppRegistryController* app_registry_controller,
       SystemWebAppManager* web_app_manager,
       OsIntegrationManager* os_integration_manager);
@@ -128,7 +128,7 @@
   // Used to install, uninstall, and update apps. Should outlive this class
   // (owned by WebAppProvider).
   ExternallyManagedAppManager* externally_managed_app_manager_ = nullptr;
-  AppRegistrar* app_registrar_ = nullptr;
+  WebAppRegistrar* app_registrar_ = nullptr;
   AppRegistryController* app_registry_controller_ = nullptr;
   SystemWebAppManager* web_app_manager_ = nullptr;
   OsIntegrationManager* os_integration_manager_ = nullptr;
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
index 562585f1..38d73dec 100644
--- a/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
+++ b/chrome/browser/web_applications/preinstalled_web_app_manager_browsertest.cc
@@ -122,8 +122,8 @@
     return embedded_test_server()->GetURL("/web_apps/basic.html");
   }
 
-  const AppRegistrar& registrar() {
-    return WebAppProvider::Get(profile())->registrar();
+  const WebAppRegistrar& registrar() {
+    return WebAppProvider::Get(browser()->profile())->registrar();
   }
 
   const PreinstalledWebAppManager& manager() {
diff --git a/chrome/browser/web_applications/preinstalled_web_app_utils.cc b/chrome/browser/web_applications/preinstalled_web_app_utils.cc
index fc8bc526..45df6e81 100644
--- a/chrome/browser/web_applications/preinstalled_web_app_utils.cc
+++ b/chrome/browser/web_applications/preinstalled_web_app_utils.cc
@@ -85,7 +85,7 @@
 // substring of start_url's existing params then it will not be added a second
 // time.
 // Note that substring matches include "param=a" matching in "some_param=abc".
-// Extend the implementation in AppRegistrar::GetAppLaunchUrl() if this edge
+// Extend the implementation in WebAppRegistrar::GetAppLaunchUrl() if this edge
 // case needs to be handled differently.
 constexpr char kLaunchQueryParams[] = "launch_query_params";
 
diff --git a/chrome/browser/web_applications/protocol_handler_manager.cc b/chrome/browser/web_applications/protocol_handler_manager.cc
index 292a3df..5571a56f 100644
--- a/chrome/browser/web_applications/protocol_handler_manager.cc
+++ b/chrome/browser/web_applications/protocol_handler_manager.cc
@@ -7,8 +7,8 @@
 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_protocol_handler_registration.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "third_party/blink/public/common/security/protocol_handler_security_level.h"
 
 namespace web_app {
@@ -18,7 +18,7 @@
 
 ProtocolHandlerManager::~ProtocolHandlerManager() = default;
 
-void ProtocolHandlerManager::SetSubsystems(AppRegistrar* registrar) {
+void ProtocolHandlerManager::SetSubsystems(WebAppRegistrar* registrar) {
   app_registrar_ = registrar;
 }
 
diff --git a/chrome/browser/web_applications/system_web_apps/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_apps/system_web_app_manager.cc
index 4afa6bac..b832f671 100644
--- a/chrome/browser/web_applications/system_web_apps/system_web_app_manager.cc
+++ b/chrome/browser/web_applications/system_web_apps/system_web_app_manager.cc
@@ -26,7 +26,6 @@
 #include "chrome/browser/ash/web_applications/chrome_camera_app_ui_constants.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/external_install_options.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
@@ -263,7 +262,7 @@
 
 void SystemWebAppManager::SetSubsystems(
     ExternallyManagedAppManager* externally_managed_app_manager,
-    AppRegistrar* registrar,
+    WebAppRegistrar* registrar,
     AppRegistryController* registry_controller,
     WebAppUiManager* ui_manager,
     OsIntegrationManager* os_integration_manager,
diff --git a/chrome/browser/web_applications/system_web_apps/system_web_app_manager.h b/chrome/browser/web_applications/system_web_apps/system_web_app_manager.h
index 8cc4c5bf..2dfb0758 100644
--- a/chrome/browser/web_applications/system_web_apps/system_web_app_manager.h
+++ b/chrome/browser/web_applications/system_web_apps/system_web_app_manager.h
@@ -83,7 +83,7 @@
 
   void SetSubsystems(
       ExternallyManagedAppManager* externally_managed_app_manager,
-      AppRegistrar* registrar,
+      WebAppRegistrar* registrar,
       AppRegistryController* registry_controller,
       WebAppUiManager* ui_manager,
       OsIntegrationManager* os_integration_manager,
@@ -252,7 +252,7 @@
   // Used to install, uninstall, and update apps. Should outlive this class.
   ExternallyManagedAppManager* externally_managed_app_manager_ = nullptr;
 
-  AppRegistrar* registrar_ = nullptr;
+  WebAppRegistrar* registrar_ = nullptr;
 
   AppRegistryController* registry_controller_ = nullptr;
 
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
index 7475c4a..f247cfad 100644
--- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
+++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
@@ -32,7 +32,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/proto/web_app.pb.h"
@@ -106,8 +105,8 @@
   EXPECT_TRUE(GetManager().IsSystemWebApp(app_id));
 
   Profile* profile = app_browser->profile();
-  AppRegistrar& registrar =
-      WebAppProviderBase::GetProviderBase(profile)->registrar();
+  WebAppRegistrar& registrar =
+      WebAppProvider::GetForWebApps(profile)->registrar();
 
   EXPECT_EQ("Test System App", registrar.GetAppShortName(app_id));
   EXPECT_EQ(SkColorSetRGB(0, 0xFF, 0), registrar.GetAppThemeColor(app_id));
@@ -1164,8 +1163,8 @@
   EXPECT_TRUE(GetManager().IsSystemWebApp(app_id));
 
   Profile* profile = app_browser->profile();
-  AppRegistrar& registrar =
-      WebAppProviderBase::GetProviderBase(profile)->registrar();
+  WebAppRegistrar& registrar =
+      WebAppProvider::GetForWebApps(profile)->registrar();
 
   EXPECT_EQ("Test System App", registrar.GetAppShortName(app_id));
   EXPECT_EQ(SkColorSetRGB(0, 0xFF, 0), registrar.GetAppThemeColor(app_id));
@@ -1395,7 +1394,7 @@
     ListPrefUpdate update(TestingBrowserProcess::GetGlobal()->local_state(),
                           policy::policy_prefs::kSystemFeaturesDisableList);
     base::ListValue* list = update.Get();
-    list->Clear();
+    list->ClearList();
   }
   GetAppServiceProxy(browser()->profile())->FlushMojoCallsForTesting();
   EXPECT_EQ(apps::mojom::Readiness::kReady, GetAppReadiness(*settings_id));
@@ -1431,7 +1430,7 @@
     ListPrefUpdate update(TestingBrowserProcess::GetGlobal()->local_state(),
                           policy::policy_prefs::kSystemFeaturesDisableList);
     base::ListValue* list = update.Get();
-    list->Clear();
+    list->ClearList();
   }
   proxy->FlushMojoCallsForTesting();
   EXPECT_EQ(apps::mojom::Readiness::kReady, GetAppReadiness(*settings_id));
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc
index 61a399a..b657bcd 100644
--- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_unittest.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_icon_generator.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/externally_managed_app_manager_impl.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_background_task.h"
@@ -44,6 +43,7 @@
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_install_finalizer.h"
 #include "chrome/browser/web_applications/web_app_install_manager.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
 #include "chrome/common/chrome_features.h"
 #include "content/public/browser/navigation_handle.h"
diff --git a/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.cc b/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.cc
index d9709951..a5fc48c6 100644
--- a/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.cc
+++ b/chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.cc
@@ -13,13 +13,13 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_delegate.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_types.h"
 #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h"
 #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_url_data_source.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/grit/generated_resources.h"
 #include "content/public/common/url_constants.h"
 #include "ui/webui/webui_allowlist.h"
diff --git a/chrome/browser/web_applications/test/test_web_app_provider.cc b/chrome/browser/web_applications/test/test_web_app_provider.cc
index b0068e4..02914b2b 100644
--- a/chrome/browser/web_applications/test/test_web_app_provider.cc
+++ b/chrome/browser/web_applications/test/test_web_app_provider.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/externally_managed_app_manager.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
@@ -20,6 +19,7 @@
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_install_manager.h"
 #include "chrome/browser/web_applications/web_app_provider_factory.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 
 namespace web_app {
 
@@ -62,7 +62,8 @@
   run_subsystem_startup_tasks_ = run_subsystem_startup_tasks;
 }
 
-void TestWebAppProvider::SetRegistrar(std::unique_ptr<AppRegistrar> registrar) {
+void TestWebAppProvider::SetRegistrar(
+    std::unique_ptr<WebAppRegistrar> registrar) {
   CheckNotStarted();
   registrar_ = std::move(registrar);
 }
diff --git a/chrome/browser/web_applications/test/test_web_app_provider.h b/chrome/browser/web_applications/test/test_web_app_provider.h
index 8492a8d..d92ac2d 100644
--- a/chrome/browser/web_applications/test/test_web_app_provider.h
+++ b/chrome/browser/web_applications/test/test_web_app_provider.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/callback.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
@@ -22,7 +21,7 @@
 
 namespace web_app {
 
-class AppRegistrar;
+class WebAppRegistrar;
 class OsIntegrationManager;
 class InstallFinalizer;
 class ExternallyManagedAppManager;
@@ -55,7 +54,7 @@
   // if it's a part of TestingProfile (see BuildDefault() method above).
   void SetRunSubsystemStartupTasks(bool run_subsystem_startup_tasks);
 
-  void SetRegistrar(std::unique_ptr<AppRegistrar> registrar);
+  void SetRegistrar(std::unique_ptr<WebAppRegistrar> registrar);
   void SetRegistryController(std::unique_ptr<AppRegistryController> controller);
   void SetOsIntegrationManager(
       std::unique_ptr<OsIntegrationManager> os_integration_manager);
diff --git a/chrome/browser/web_applications/test/web_app_install_observer.cc b/chrome/browser/web_applications/test/web_app_install_observer.cc
index 64c261a..daf95fe 100644
--- a/chrome/browser/web_applications/test/web_app_install_observer.cc
+++ b/chrome/browser/web_applications/test/web_app_install_observer.cc
@@ -8,15 +8,15 @@
 
 #include "base/run_loop.h"
 #include "base/test/bind.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 
 namespace web_app {
 
-WebAppInstallObserver::WebAppInstallObserver(AppRegistrar* registrar) {
+WebAppInstallObserver::WebAppInstallObserver(WebAppRegistrar* registrar) {
   observation_.Observe(registrar);
 }
 WebAppInstallObserver::WebAppInstallObserver(
-    AppRegistrar* registrar,
+    WebAppRegistrar* registrar,
     const std::set<AppId>& listening_for_install_app_ids,
     const std::set<AppId>& listening_for_uninstall_app_ids,
     const std::set<AppId>& listening_for_install_with_os_hooks_app_ids)
@@ -43,7 +43,7 @@
 
 WebAppInstallObserver::WebAppInstallObserver(Profile* profile)
     : WebAppInstallObserver(
-          &WebAppProviderBase::GetProviderBase(profile)->registrar()) {}
+          &WebAppProvider::GetForWebApps(profile)->registrar()) {}
 
 WebAppInstallObserver::WebAppInstallObserver(
     Profile* profile,
@@ -51,7 +51,7 @@
     const std::set<AppId>& listening_for_uninstall_app_id,
     const std::set<AppId>& listening_for_install_with_os_hooks_app_ids)
     : WebAppInstallObserver(
-          &WebAppProviderBase::GetProviderBase(profile)->registrar(),
+          &WebAppProvider::GetForWebApps(profile)->registrar(),
           listening_for_install_app_ids,
           listening_for_uninstall_app_id,
           listening_for_install_with_os_hooks_app_ids) {}
diff --git a/chrome/browser/web_applications/test/web_app_install_observer.h b/chrome/browser/web_applications/test/web_app_install_observer.h
index edc5b16..13a62493 100644
--- a/chrome/browser/web_applications/test/web_app_install_observer.h
+++ b/chrome/browser/web_applications/test/web_app_install_observer.h
@@ -10,18 +10,18 @@
 
 #include "base/callback.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 
 namespace web_app {
 
-class AppRegistrar;
+class WebAppRegistrar;
 class WebApp;
 
 class WebAppInstallObserver final : public AppRegistrarObserver {
  public:
-  explicit WebAppInstallObserver(AppRegistrar* registrar);
+  explicit WebAppInstallObserver(WebAppRegistrar* registrar);
   explicit WebAppInstallObserver(Profile* profile);
 
   // Restricts this observer to only listen for the given
@@ -125,7 +125,7 @@
   // |listening_for_install_app_ids| or |listening_for_uninstall_app_ids| are
   // installed or uninstalled (respectively).
   explicit WebAppInstallObserver(
-      AppRegistrar* registrar,
+      WebAppRegistrar* registrar,
       const std::set<AppId>& listening_for_install_app_ids,
       const std::set<AppId>& listening_for_uninstall_app_ids,
       const std::set<AppId>& listening_for_install_with_os_hooks_app_ids);
@@ -148,7 +148,7 @@
   SingleAppUninstalledDelegate single_app_uninstalled_delegate_;
   WebAppProfileWillBeDeletedDelegate app_profile_will_be_deleted_delegate_;
 
-  base::ScopedObservation<AppRegistrar, AppRegistrarObserver> observation_{
+  base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver> observation_{
       this};
 };
 
diff --git a/chrome/browser/web_applications/test/web_app_install_test_utils.cc b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
index 48f992e..1b489be 100644
--- a/chrome/browser/web_applications/test/web_app_install_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_install_test_utils.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_manager.h"
 #include "chrome/browser/web_applications/test/test_web_app_provider.h"
@@ -80,16 +79,14 @@
   // Hence we use FinalizeInstall instead of InstallWebAppFromManifest
   // to install the web app.
   base::RunLoop run_loop;
-  WebAppProviderBase::GetProviderBase(profile)
-      ->install_finalizer()
-      .FinalizeInstall(
-          web_app_info, options,
-          base::BindLambdaForTesting(
-              [&](const AppId& installed_app_id, InstallResultCode code) {
-                EXPECT_EQ(installed_app_id, app_id);
-                EXPECT_EQ(code, InstallResultCode::kSuccessNewInstall);
-                run_loop.Quit();
-              }));
+  WebAppProvider::GetForWebApps(profile)->install_finalizer().FinalizeInstall(
+      web_app_info, options,
+      base::BindLambdaForTesting(
+          [&](const AppId& installed_app_id, InstallResultCode code) {
+            EXPECT_EQ(installed_app_id, app_id);
+            EXPECT_EQ(code, InstallResultCode::kSuccessNewInstall);
+            run_loop.Quit();
+          }));
   run_loop.Run();
 
   return app_id;
@@ -136,7 +133,7 @@
   web_app::AppId app_id =
       web_app::test::InstallWebApp(profile, std::move(info));
 
-  auto& url_handler_manager = WebAppProviderBase::GetProviderBase(profile)
+  auto& url_handler_manager = WebAppProvider::GetForWebApps(profile)
                                   ->os_integration_manager()
                                   .url_handler_manager_for_testing();
 
diff --git a/chrome/browser/web_applications/test/web_app_uninstall_waiter.cc b/chrome/browser/web_applications/test/web_app_uninstall_waiter.cc
index 5f94d18..2af522de 100644
--- a/chrome/browser/web_applications/test/web_app_uninstall_waiter.cc
+++ b/chrome/browser/web_applications/test/web_app_uninstall_waiter.cc
@@ -4,14 +4,13 @@
 
 #include "chrome/browser/web_applications/test/web_app_uninstall_waiter.h"
 
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 
 namespace web_app {
 
 WebAppUninstallWaiter::WebAppUninstallWaiter(Profile* profile, AppId app_id)
     : app_id_(std::move(app_id)) {
-  observation_.Observe(
-      &WebAppProviderBase::GetProviderBase(profile)->registrar());
+  observation_.Observe(&WebAppProvider::GetForWebApps(profile)->registrar());
 }
 WebAppUninstallWaiter::~WebAppUninstallWaiter() = default;
 
diff --git a/chrome/browser/web_applications/test/web_app_uninstall_waiter.h b/chrome/browser/web_applications/test/web_app_uninstall_waiter.h
index 6a3d8851..536c7c36 100644
--- a/chrome/browser/web_applications/test/web_app_uninstall_waiter.h
+++ b/chrome/browser/web_applications/test/web_app_uninstall_waiter.h
@@ -7,9 +7,9 @@
 
 #include "base/run_loop.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 
 namespace web_app {
 
@@ -25,7 +25,7 @@
  private:
   AppId app_id_;
   base::RunLoop run_loop_;
-  base::ScopedObservation<AppRegistrar, AppRegistrarObserver> observation_{
+  base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver> observation_{
       this};
 };
 
diff --git a/chrome/browser/web_applications/url_handler_manager.cc b/chrome/browser/web_applications/url_handler_manager.cc
index 95b7bdb..6fc2ffc 100644
--- a/chrome/browser/web_applications/url_handler_manager.cc
+++ b/chrome/browser/web_applications/url_handler_manager.cc
@@ -7,7 +7,7 @@
 #include <utility>
 
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 
 namespace web_app {
 
@@ -18,7 +18,7 @@
 
 UrlHandlerManager::~UrlHandlerManager() = default;
 
-void UrlHandlerManager::SetSubsystems(AppRegistrar* const registrar) {
+void UrlHandlerManager::SetSubsystems(WebAppRegistrar* const registrar) {
   registrar_ = registrar;
 }
 
diff --git a/chrome/browser/web_applications/url_handler_manager_impl.cc b/chrome/browser/web_applications/url_handler_manager_impl.cc
index 0ca2604..497a236 100644
--- a/chrome/browser/web_applications/url_handler_manager_impl.cc
+++ b/chrome/browser/web_applications/url_handler_manager_impl.cc
@@ -11,9 +11,9 @@
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/url_handler_prefs.h"
 #include "chrome/browser/web_applications/components/web_app_origin_association_manager.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/prefs/pref_service.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/web_applications/web_app_file_handler_registration_linux.cc b/chrome/browser/web_applications/web_app_file_handler_registration_linux.cc
index 6bc1aba6..c2d35c4 100644
--- a/chrome/browser/web_applications/web_app_file_handler_registration_linux.cc
+++ b/chrome/browser/web_applications/web_app_file_handler_registration_linux.cc
@@ -13,10 +13,10 @@
 #include "base/no_destructor.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/shell_integration_linux.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_shortcut.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 
 namespace web_app {
 
@@ -98,7 +98,7 @@
   // On Linux, file associations are managed through shortcuts in the app menu,
   // so after enabling or disabling file handling for an app its shortcuts
   // need to be recreated.
-  WebAppProviderBase::GetProviderBase(profile)
+  WebAppProvider::GetForWebApps(profile)
       ->os_integration_manager()
       .GetShortcutInfoForApp(
           app_id, base::BindOnce(&OnShortcutInfoReceived, std::move(callback)));
@@ -172,7 +172,7 @@
   // If this was triggered as part of the uninstallation process, nothing more
   // is needed. Uninstalling already cleans up shortcuts (and thus, file
   // handlers).
-  auto* provider = WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = WebAppProvider::GetForWebApps(profile);
   DCHECK(provider->registrar().IsInstalled(app_id));
   if (provider->registrar().IsUninstalling(app_id)) {
     std::move(callback).Run(true);
diff --git a/chrome/browser/web_applications/web_app_helpers.cc b/chrome/browser/web_applications/web_app_helpers.cc
index 057abc6c..176a1c3cb 100644
--- a/chrome/browser/web_applications/web_app_helpers.cc
+++ b/chrome/browser/web_applications/web_app_helpers.cc
@@ -8,8 +8,8 @@
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/crx_file/id_util.h"
 #include "crypto/sha2.h"
 #include "extensions/common/constants.h"
@@ -114,7 +114,7 @@
 absl::optional<AppId> FindInstalledAppWithUrlInScope(Profile* profile,
                                                      const GURL& url,
                                                      bool window_only) {
-  auto* provider = WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = WebAppProvider::GetForWebApps(profile);
   return provider ? provider->registrar().FindInstalledAppWithUrlInScope(
                         url, window_only)
                   : absl::nullopt;
diff --git a/chrome/browser/web_applications/web_app_icon_manager.h b/chrome/browser/web_applications/web_app_icon_manager.h
index d7cdf17..2274e1a6 100644
--- a/chrome/browser/web_applications/web_app_icon_manager.h
+++ b/chrome/browser/web_applications/web_app_icon_manager.h
@@ -14,9 +14,9 @@
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/image/image_skia.h"
@@ -147,7 +147,7 @@
   base::FilePath web_apps_directory_;
   std::unique_ptr<FileUtilsWrapper> utils_;
 
-  base::ScopedObservation<AppRegistrar, AppRegistrarObserver>
+  base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver>
       registrar_observation_{this};
 
   // We cache different densities for high-DPI displays per each app.
diff --git a/chrome/browser/web_applications/web_app_icon_manager_browsertest.cc b/chrome/browser/web_applications/web_app_icon_manager_browsertest.cc
index fc05a3e..6f57a2f9 100644
--- a/chrome/browser/web_applications/web_app_icon_manager_browsertest.cc
+++ b/chrome/browser/web_applications/web_app_icon_manager_browsertest.cc
@@ -17,8 +17,8 @@
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_icon_generator.h"
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
@@ -87,8 +87,7 @@
     }
 
     InstallManager& install_manager =
-        WebAppProviderBase::GetProviderBase(browser()->profile())
-            ->install_manager();
+        WebAppProvider::GetForWebApps(browser()->profile())->install_manager();
 
     base::RunLoop run_loop;
     install_manager.InstallWebAppFromInfo(
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.cc b/chrome/browser/web_applications/web_app_install_finalizer.cc
index 0da7948..d208d74 100644
--- a/chrome/browser/web_applications/web_app_install_finalizer.cc
+++ b/chrome/browser/web_applications/web_app_install_finalizer.cc
@@ -18,12 +18,10 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_icon_generator.h"
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
 #include "chrome/browser/web_applications/components/web_app_prefs_utils.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_shortcuts_menu.h"
 #include "chrome/browser/web_applications/components/web_app_system_web_app_data.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
@@ -35,6 +33,8 @@
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_installation_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_registry_update.h"
 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
 #include "components/content_settings/core/common/content_settings.h"
diff --git a/chrome/browser/web_applications/web_app_install_manager.cc b/chrome/browser/web_applications/web_app_install_manager.cc
index a936177d..8de6e6d 100644
--- a/chrome/browser/web_applications/web_app_install_manager.cc
+++ b/chrome/browser/web_applications/web_app_install_manager.cc
@@ -12,7 +12,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_data_retriever.h"
@@ -20,6 +19,7 @@
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_install_task.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
index a208606..78493ec 100644
--- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc
+++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_icon_generator.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
@@ -40,6 +39,7 @@
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_install_finalizer.h"
 #include "chrome/browser/web_applications/web_app_install_task.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
 #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/web_applications/web_app_install_task.cc b/chrome/browser/web_applications/web_app_install_task.cc
index 437adf4..b8f294c 100644
--- a/chrome/browser/web_applications/web_app_install_task.cc
+++ b/chrome/browser/web_applications/web_app_install_task.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/favicon/favicon_utils.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/install_bounce_metric.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_data_retriever.h"
@@ -29,6 +28,7 @@
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/web_app_installation_utils.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "components/webapps/browser/installable/installable_manager.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
@@ -78,7 +78,7 @@
     OsIntegrationManager* os_integration_manager,
     InstallFinalizer* install_finalizer,
     std::unique_ptr<WebAppDataRetriever> data_retriever,
-    AppRegistrar* registrar)
+    WebAppRegistrar* registrar)
     : data_retriever_(std::move(data_retriever)),
       os_integration_manager_(os_integration_manager),
       install_finalizer_(install_finalizer),
diff --git a/chrome/browser/web_applications/web_app_install_task.h b/chrome/browser/web_applications/web_app_install_task.h
index fdd1b3c..d9bdc39 100644
--- a/chrome/browser/web_applications/web_app_install_task.h
+++ b/chrome/browser/web_applications/web_app_install_task.h
@@ -40,7 +40,7 @@
 class InstallFinalizer;
 class WebAppDataRetriever;
 class WebAppUrlLoader;
-class AppRegistrar;
+class WebAppRegistrar;
 
 // Used to do a variety of tasks involving installing web applications. Only one
 // of the public Load*, Update*, or Install* methods can be called on a single
@@ -55,7 +55,7 @@
                     OsIntegrationManager* os_integration_manager,
                     InstallFinalizer* install_finalizer,
                     std::unique_ptr<WebAppDataRetriever> data_retriever,
-                    AppRegistrar* registrar);
+                    WebAppRegistrar* registrar);
   WebAppInstallTask(const WebAppInstallTask&) = delete;
   WebAppInstallTask& operator=(const WebAppInstallTask&) = delete;
   ~WebAppInstallTask() override;
@@ -278,7 +278,7 @@
   OsIntegrationManager* os_integration_manager_;
   InstallFinalizer* install_finalizer_;
   Profile* const profile_;
-  AppRegistrar* registrar_;
+  WebAppRegistrar* registrar_;
 
   base::WeakPtrFactory<WebAppInstallTask> weak_ptr_factory_{this};
 
diff --git a/chrome/browser/web_applications/web_app_installation_utils.cc b/chrome/browser/web_applications/web_app_installation_utils.cc
index e041ce95f..2c77385 100644
--- a/chrome/browser/web_applications/web_app_installation_utils.cc
+++ b/chrome/browser/web_applications/web_app_installation_utils.cc
@@ -12,7 +12,6 @@
 #include "base/feature_list.h"
 #include "base/notreached.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
@@ -175,7 +174,7 @@
   web_app.SetManifestUrl(web_app_info.manifest_url);
 }
 
-void MaybeDisableOsIntegration(const AppRegistrar* app_registrar,
+void MaybeDisableOsIntegration(const WebAppRegistrar* app_registrar,
                                const AppId& app_id,
                                InstallOsHooksOptions* options) {
 #if !defined(OS_CHROMEOS)  // Deeper OS integration is expected on ChromeOS.
diff --git a/chrome/browser/web_applications/web_app_installation_utils.h b/chrome/browser/web_applications/web_app_installation_utils.h
index 82dfb75..5a1eb5d2 100644
--- a/chrome/browser/web_applications/web_app_installation_utils.h
+++ b/chrome/browser/web_applications/web_app_installation_utils.h
@@ -12,7 +12,7 @@
 namespace web_app {
 
 struct InstallOsHooksOptions;
-class AppRegistrar;
+class WebAppRegistrar;
 class WebApp;
 
 // Updates |web_app| using |web_app_info|
@@ -21,7 +21,7 @@
 
 // Possibly updates |options| to disable OS-integrations based on the
 // configuration of the given app.
-void MaybeDisableOsIntegration(const AppRegistrar* app_registrar,
+void MaybeDisableOsIntegration(const WebAppRegistrar* app_registrar,
                                const AppId& app_id,
                                InstallOsHooksOptions* options);
 
diff --git a/chrome/browser/web_applications/web_app_mover.cc b/chrome/browser/web_applications/web_app_mover.cc
index cfcdcaeb..7c6655c 100644
--- a/chrome/browser/web_applications/web_app_mover.cc
+++ b/chrome/browser/web_applications/web_app_mover.cc
@@ -14,10 +14,10 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/sync_service_factory.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/components/install_finalizer.h"
 #include "chrome/browser/web_applications/components/install_manager.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
@@ -40,7 +40,7 @@
 
 std::unique_ptr<WebAppMover> WebAppMover::CreateIfNeeded(
     Profile* profile,
-    AppRegistrar* registrar,
+    WebAppRegistrar* registrar,
     InstallFinalizer* install_finalizer,
     InstallManager* install_manager,
     AppRegistryController* controller) {
@@ -121,7 +121,7 @@
 }
 
 WebAppMover::WebAppMover(Profile* profile,
-                         AppRegistrar* registrar,
+                         WebAppRegistrar* registrar,
                          InstallFinalizer* install_finalizer,
                          InstallManager* install_manager,
                          AppRegistryController* controller,
diff --git a/chrome/browser/web_applications/web_app_mover.h b/chrome/browser/web_applications/web_app_mover.h
index 2d74dee..13e217b 100644
--- a/chrome/browser/web_applications/web_app_mover.h
+++ b/chrome/browser/web_applications/web_app_mover.h
@@ -27,7 +27,7 @@
 
 namespace web_app {
 
-class AppRegistrar;
+class WebAppRegistrar;
 class AppRegistryController;
 class InstallFinalizer;
 
@@ -38,7 +38,7 @@
   enum class UninstallMode { kPrefix, kPattern };
   static std::unique_ptr<WebAppMover> CreateIfNeeded(
       Profile* profile,
-      AppRegistrar* registrar,
+      WebAppRegistrar* registrar,
       InstallFinalizer* install_finalizer,
       InstallManager* install_manager,
       AppRegistryController* controller);
@@ -48,7 +48,7 @@
   static void SetCompletedCallbackForTesting(base::OnceClosure callback);
 
   WebAppMover(Profile* profile,
-              AppRegistrar* registrar,
+              WebAppRegistrar* registrar,
               InstallFinalizer* install_finalizer,
               InstallManager* install_manager,
               AppRegistryController* controller,
@@ -101,7 +101,7 @@
   void RecordResults(WebAppMoverResult result);
 
   Profile* profile_;
-  AppRegistrar* registrar_;
+  WebAppRegistrar* registrar_;
   InstallFinalizer* install_finalizer_;
   InstallManager* install_manager_;
   AppRegistryController* controller_;
diff --git a/chrome/browser/web_applications/web_app_mover_browsertest.cc b/chrome/browser/web_applications/web_app_mover_browsertest.cc
index b7dcd70a..4597503 100644
--- a/chrome/browser/web_applications/web_app_mover_browsertest.cc
+++ b/chrome/browser/web_applications/web_app_mover_browsertest.cc
@@ -8,13 +8,13 @@
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/test/web_app_test.h"
 #include "chrome/browser/web_applications/test/web_app_test_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -91,8 +91,8 @@
     return app_id;
   }
 
-  WebAppProviderBase& GetProvider() {
-    return *WebAppProviderBase::GetProviderBase(browser()->profile());
+  WebAppProvider& GetProvider() {
+    return *WebAppProvider::GetForWebApps(browser()->profile());
   }
 
   bool clean_up_completed_ = false;
diff --git a/chrome/browser/web_applications/web_app_protocol_handler_manager.cc b/chrome/browser/web_applications/web_app_protocol_handler_manager.cc
index 727c0ce..03cf532a 100644
--- a/chrome/browser/web_applications/web_app_protocol_handler_manager.cc
+++ b/chrome/browser/web_applications/web_app_protocol_handler_manager.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/web_applications/web_app_protocol_handler_manager.h"
 
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc
index ed46ec3..5def7b7 100644
--- a/chrome/browser/web_applications/web_app_provider.cc
+++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -129,7 +129,7 @@
   StartImpl();
 }
 
-AppRegistrar& WebAppProvider::registrar() {
+WebAppRegistrar& WebAppProvider::registrar() {
   CheckIsConnected();
   return *registrar_;
 }
diff --git a/chrome/browser/web_applications/web_app_provider.h b/chrome/browser/web_applications/web_app_provider.h
index 131354e..76631144 100644
--- a/chrome/browser/web_applications/web_app_provider.h
+++ b/chrome/browser/web_applications/web_app_provider.h
@@ -10,10 +10,10 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/one_shot_event.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/externally_managed_app_manager.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
+#include "components/keyed_service/core/keyed_service.h"
 
 class Profile;
 
@@ -54,7 +54,7 @@
 // Subsystem construction should have no side effects and start no tasks.
 // Tests can replace any of the subsystems before Start() is called.
 // Similarly, in destruction, subsystems should not refer to each other.
-class WebAppProvider : public WebAppProviderBase {
+class WebAppProvider : public KeyedService {
  public:
   // Deprecated: Use GetForWebApps or GetForSystemWebApps instead.
   static WebAppProvider* Get(Profile* profile);
@@ -92,19 +92,34 @@
   // Start the Web App system. This will run subsystem startup tasks.
   void Start();
 
-  // WebAppProviderBase:
-  AppRegistrar& registrar() override;
-  AppRegistryController& registry_controller() override;
-  InstallManager& install_manager() override;
-  InstallFinalizer& install_finalizer() override;
-  ManifestUpdateManager& manifest_update_manager() override;
-  ExternallyManagedAppManager& externally_managed_app_manager() override;
-  WebAppPolicyManager& policy_manager() override;
-  WebAppUiManager& ui_manager() override;
-  WebAppAudioFocusIdMap& audio_focus_id_map() override;
-  AppIconManager& icon_manager() override;
-  SystemWebAppManager& system_web_app_manager() override;
-  OsIntegrationManager& os_integration_manager() override;
+  // The app registry model.
+  WebAppRegistrar& registrar();
+  // The app registry controller.
+  AppRegistryController& registry_controller();
+  // UIs can use InstallManager for user-initiated Web Apps install.
+  InstallManager& install_manager();
+  // Implements persistence for Web Apps install.
+  InstallFinalizer& install_finalizer();
+  // Keeps app metadata up to date with site manifests.
+  ManifestUpdateManager& manifest_update_manager();
+  // Clients can use ExternallyManagedAppManager to install, uninstall, and
+  // update Web Apps.
+  ExternallyManagedAppManager& externally_managed_app_manager();
+  // Clients can use WebAppPolicyManager to request updates of policy installed
+  // Web Apps.
+  WebAppPolicyManager& policy_manager();
+
+  WebAppUiManager& ui_manager();
+
+  WebAppAudioFocusIdMap& audio_focus_id_map();
+
+  // Implements fetching of app icons.
+  AppIconManager& icon_manager();
+
+  SystemWebAppManager& system_web_app_manager();
+
+  // Manage all OS hooks that need to be deployed during Web Apps install
+  OsIntegrationManager& os_integration_manager();
 
   // KeyedService:
   void Shutdown() override;
@@ -144,7 +159,7 @@
   std::unique_ptr<WebAppMover> web_app_mover_;
 
   // Generalized subsystems:
-  std::unique_ptr<AppRegistrar> registrar_;
+  std::unique_ptr<WebAppRegistrar> registrar_;
   std::unique_ptr<AppRegistryController> registry_controller_;
   std::unique_ptr<PreinstalledWebAppManager> preinstalled_web_app_manager_;
   std::unique_ptr<AppIconManager> icon_manager_;
diff --git a/chrome/browser/web_applications/web_app_provider_factory.cc b/chrome/browser/web_applications/web_app_provider_factory.cc
index abc9c6f..27940c9 100644
--- a/chrome/browser/web_applications/web_app_provider_factory.cc
+++ b/chrome/browser/web_applications/web_app_provider_factory.cc
@@ -27,10 +27,9 @@
 }
 
 WebAppProviderFactory::WebAppProviderFactory()
-    : WebAppProviderBaseFactory(
+    : BrowserContextKeyedServiceFactory(
           "WebAppProvider",
           BrowserContextDependencyManager::GetInstance()) {
-  WebAppProviderBaseFactory::SetInstance(this);
   DependsOnExtensionsSystem();
   DependsOn(ModelTypeStoreServiceFactory::GetInstance());
   DependsOn(ukm::UkmBackgroundRecorderFactory::GetInstance());
@@ -39,9 +38,7 @@
   DependsOn(HostContentSettingsMapFactory::GetInstance());
 }
 
-WebAppProviderFactory::~WebAppProviderFactory() {
-  WebAppProviderBaseFactory::SetInstance(nullptr);
-}
+WebAppProviderFactory::~WebAppProviderFactory() = default;
 
 KeyedService* WebAppProviderFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
diff --git a/chrome/browser/web_applications/web_app_provider_factory.h b/chrome/browser/web_applications/web_app_provider_factory.h
index 154329d5..ae93462 100644
--- a/chrome/browser/web_applications/web_app_provider_factory.h
+++ b/chrome/browser/web_applications/web_app_provider_factory.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_PROVIDER_FACTORY_H_
 
 #include "base/memory/singleton.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base_factory.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 
 namespace content {
 class BrowserContext;
@@ -20,7 +20,7 @@
 
 // Singleton that owns all WebAppProviderFactories and associates them with
 // Profile.
-class WebAppProviderFactory : public WebAppProviderBaseFactory {
+class WebAppProviderFactory : public BrowserContextKeyedServiceFactory {
  public:
   WebAppProviderFactory(const WebAppProviderFactory&) = delete;
   WebAppProviderFactory& operator=(const WebAppProviderFactory&) = delete;
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc
index a3eb2db..63b5bdc 100644
--- a/chrome/browser/web_applications/web_app_registrar.cc
+++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -11,17 +11,360 @@
 #include "base/callback_helpers.h"
 #include "base/check_op.h"
 #include "base/containers/contains.h"
+#include "base/containers/cxx20_erase.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/web_applications/components/app_registrar_observer.h"
+#include "chrome/browser/web_applications/components/externally_installed_web_app_prefs.h"
+#include "chrome/browser/web_applications/components/install_bounce_metric.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
+#include "chrome/browser/web_applications/components/web_app_helpers.h"
+#include "chrome/browser/web_applications/components/web_app_prefs_utils.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/common/chrome_features.h"
+#include "content/public/common/content_features.h"
 
 namespace web_app {
 
-WebAppRegistrar::WebAppRegistrar(Profile* profile) : AppRegistrar(profile) {}
+WebAppRegistrar::WebAppRegistrar(Profile* profile) : profile_(profile) {}
 
-WebAppRegistrar::~WebAppRegistrar() = default;
+WebAppRegistrar::~WebAppRegistrar() {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnAppRegistrarDestroyed();
+}
+
+void WebAppRegistrar::SetSubsystems(
+    OsIntegrationManager* os_integration_manager) {
+  os_integration_manager_ = os_integration_manager;
+}
+
+bool WebAppRegistrar::IsLocallyInstalled(const GURL& start_url) const {
+  return IsLocallyInstalled(
+      GenerateAppId(/*manifest_id=*/absl::nullopt, start_url));
+}
+
+bool WebAppRegistrar::IsPlaceholderApp(const AppId& app_id) const {
+  return ExternallyInstalledWebAppPrefs(profile_->GetPrefs())
+      .IsPlaceholderApp(app_id);
+}
+
+void WebAppRegistrar::AddObserver(AppRegistrarObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void WebAppRegistrar::RemoveObserver(AppRegistrarObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void WebAppRegistrar::NotifyWebAppInstalled(const AppId& app_id) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppInstalled(app_id);
+  // TODO(alancutter): Call RecordWebAppInstallation here when we get access to
+  // the webapps::WebappInstallSource in this event.
+}
+
+void WebAppRegistrar::NotifyWebAppManifestUpdated(const AppId& app_id,
+                                                  base::StringPiece old_name) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppManifestUpdated(app_id, old_name);
+}
+
+void WebAppRegistrar::NotifyWebAppsWillBeUpdatedFromSync(
+    const std::vector<const WebApp*>& new_apps_state) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppsWillBeUpdatedFromSync(new_apps_state);
+}
+
+void WebAppRegistrar::NotifyWebAppUninstalled(const AppId& app_id) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppUninstalled(app_id);
+}
+
+void WebAppRegistrar::NotifyWebAppWillBeUninstalled(const AppId& app_id) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppWillBeUninstalled(app_id);
+  RecordWebAppUninstallation(profile()->GetPrefs(), app_id);
+}
+
+void WebAppRegistrar::NotifyWebAppLocallyInstalledStateChanged(
+    const AppId& app_id,
+    bool is_locally_installed) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppLocallyInstalledStateChanged(app_id, is_locally_installed);
+}
+
+void WebAppRegistrar::NotifyWebAppDisabledStateChanged(const AppId& app_id,
+                                                       bool is_disabled) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppDisabledStateChanged(app_id, is_disabled);
+}
+
+void WebAppRegistrar::NotifyWebAppsDisabledModeChanged() {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppsDisabledModeChanged();
+}
+
+void WebAppRegistrar::NotifyWebAppLastLaunchTimeChanged(
+    const AppId& app_id,
+    const base::Time& time) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppLastLaunchTimeChanged(app_id, time);
+}
+
+void WebAppRegistrar::NotifyWebAppInstallTimeChanged(const AppId& app_id,
+                                                     const base::Time& time) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppInstallTimeChanged(app_id, time);
+}
+
+void WebAppRegistrar::NotifyWebAppProfileWillBeDeleted(const AppId& app_id) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppProfileWillBeDeleted(app_id);
+}
+
+void WebAppRegistrar::NotifyWebAppInstalledWithOsHooks(const AppId& app_id) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppInstalledWithOsHooks(app_id);
+}
+
+void WebAppRegistrar::NotifyWebAppUserDisplayModeChanged(
+    const AppId& app_id,
+    DisplayMode user_display_mode) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppUserDisplayModeChanged(app_id, user_display_mode);
+}
+
+void WebAppRegistrar::NotifyWebAppExperimentalTabbedWindowModeChanged(
+    const AppId& app_id,
+    bool enabled) {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnWebAppExperimentalTabbedWindowModeChanged(app_id, enabled);
+}
+
+void WebAppRegistrar::NotifyAppRegistrarShutdown() {
+  for (AppRegistrarObserver& observer : observers_)
+    observer.OnAppRegistrarShutdown();
+}
+
+std::map<AppId, GURL> WebAppRegistrar::GetExternallyInstalledApps(
+    ExternalInstallSource install_source) const {
+  std::map<AppId, GURL> installed_apps =
+      ExternallyInstalledWebAppPrefs::BuildAppIdsMap(profile()->GetPrefs(),
+                                                     install_source);
+  base::EraseIf(installed_apps, [this](const std::pair<AppId, GURL>& app) {
+    return !IsInstalled(app.first);
+  });
+
+  return installed_apps;
+}
+
+absl::optional<AppId> WebAppRegistrar::LookupExternalAppId(
+    const GURL& install_url) const {
+  return ExternallyInstalledWebAppPrefs(profile()->GetPrefs())
+      .LookupAppId(install_url);
+}
+
+bool WebAppRegistrar::HasExternalApp(const AppId& app_id) const {
+  return ExternallyInstalledWebAppPrefs::HasAppId(profile()->GetPrefs(),
+                                                  app_id);
+}
+
+bool WebAppRegistrar::HasExternalAppWithInstallSource(
+    const AppId& app_id,
+    ExternalInstallSource install_source) const {
+  return ExternallyInstalledWebAppPrefs::HasAppIdWithInstallSource(
+      profile()->GetPrefs(), app_id, install_source);
+}
+
+GURL WebAppRegistrar::GetAppLaunchUrl(const AppId& app_id) const {
+  const GURL& start_url = GetAppStartUrl(app_id);
+  const std::string* launch_query_params = GetAppLaunchQueryParams(app_id);
+  if (!start_url.is_valid() || !launch_query_params)
+    return start_url;
+
+  GURL::Replacements replacements;
+  if (start_url.query_piece().empty()) {
+    replacements.SetQueryStr(*launch_query_params);
+    return start_url.ReplaceComponents(replacements);
+  }
+
+  if (start_url.query_piece().find(*launch_query_params) !=
+      base::StringPiece::npos) {
+    return start_url;
+  }
+
+  std::string query_params = start_url.query() + "&" + *launch_query_params;
+  replacements.SetQueryStr(query_params);
+  return start_url.ReplaceComponents(replacements);
+}
+
+GURL WebAppRegistrar::GetAppScope(const AppId& app_id) const {
+  absl::optional<GURL> scope = GetAppScopeInternal(app_id);
+  if (scope)
+    return *scope;
+  if (base::FeatureList::IsEnabled(
+          features::kDesktopPWAsTabStripLinkCapturing) &&
+      IsTabbedWindowModeEnabled(app_id)) {
+    return GetAppStartUrl(app_id).GetOrigin();
+  }
+  return GetAppStartUrl(app_id).GetWithoutFilename();
+}
+
+absl::optional<AppId> WebAppRegistrar::FindAppWithUrlInScope(
+    const GURL& url) const {
+  const std::string url_path = url.spec();
+
+  absl::optional<AppId> best_app_id;
+  size_t best_app_path_length = 0U;
+  bool best_app_is_shortcut = true;
+
+  for (const AppId& app_id : GetAppIds()) {
+    // TODO(crbug.com/910016): Treat shortcuts as PWAs.
+    bool app_is_shortcut = IsShortcutApp(app_id);
+    if (app_is_shortcut && !best_app_is_shortcut)
+      continue;
+
+    const std::string app_path = GetAppScope(app_id).spec();
+
+    if ((app_path.size() > best_app_path_length ||
+         (best_app_is_shortcut && !app_is_shortcut)) &&
+        base::StartsWith(url_path, app_path, base::CompareCase::SENSITIVE)) {
+      best_app_id = app_id;
+      best_app_path_length = app_path.size();
+      best_app_is_shortcut = app_is_shortcut;
+    }
+  }
+
+  return best_app_id;
+}
+
+bool WebAppRegistrar::DoesScopeContainAnyApp(const GURL& scope) const {
+  std::string scope_str = scope.spec();
+
+  for (const auto& app_id : GetAppIds()) {
+    if (!IsLocallyInstalled(app_id))
+      continue;
+
+    std::string app_scope = GetAppScope(app_id).spec();
+    DCHECK(!app_scope.empty());
+
+    if (base::StartsWith(app_scope, scope_str, base::CompareCase::SENSITIVE))
+      return true;
+  }
+
+  return false;
+}
+
+std::vector<AppId> WebAppRegistrar::FindAppsInScope(const GURL& scope) const {
+  std::string scope_str = scope.spec();
+
+  std::vector<AppId> in_scope;
+  for (const auto& app_id : GetAppIds()) {
+    if (!IsLocallyInstalled(app_id))
+      continue;
+
+    std::string app_scope = GetAppScope(app_id).spec();
+    DCHECK(!app_scope.empty());
+
+    if (!base::StartsWith(app_scope, scope_str, base::CompareCase::SENSITIVE))
+      continue;
+
+    in_scope.push_back(app_id);
+  }
+
+  return in_scope;
+}
+
+absl::optional<AppId> WebAppRegistrar::FindInstalledAppWithUrlInScope(
+    const GURL& url,
+    bool window_only) const {
+  const std::string url_path = url.spec();
+
+  absl::optional<AppId> best_app_id;
+  size_t best_app_path_length = 0U;
+  bool best_app_is_shortcut = true;
+
+  for (const AppId& app_id : GetAppIds()) {
+    // TODO(crbug.com/910016): Treat shortcuts as PWAs.
+    bool app_is_shortcut = IsShortcutApp(app_id);
+    if (app_is_shortcut && !best_app_is_shortcut)
+      continue;
+
+    if (!IsLocallyInstalled(app_id))
+      continue;
+
+    if (window_only &&
+        GetAppEffectiveDisplayMode(app_id) == DisplayMode::kBrowser) {
+      continue;
+    }
+
+    const std::string app_path = GetAppScope(app_id).spec();
+
+    if ((app_path.size() > best_app_path_length ||
+         (best_app_is_shortcut && !app_is_shortcut)) &&
+        base::StartsWith(url_path, app_path, base::CompareCase::SENSITIVE)) {
+      best_app_id = app_id;
+      best_app_path_length = app_path.size();
+      best_app_is_shortcut = app_is_shortcut;
+    }
+  }
+
+  return best_app_id;
+}
+
+bool WebAppRegistrar::IsShortcutApp(const AppId& app_id) const {
+  // TODO (crbug/910016): Make app scope always return a value and record this
+  //  distinction in some other way.
+  return !GetAppScopeInternal(app_id).has_value();
+}
+
+DisplayMode WebAppRegistrar::GetAppEffectiveDisplayMode(
+    const AppId& app_id) const {
+  if (!IsLocallyInstalled(app_id))
+    return DisplayMode::kBrowser;
+
+  auto app_display_mode = GetAppDisplayMode(app_id);
+  auto user_display_mode = GetAppUserDisplayMode(app_id);
+  if (app_display_mode == DisplayMode::kUndefined ||
+      user_display_mode == DisplayMode::kUndefined) {
+    return DisplayMode::kUndefined;
+  }
+
+  std::vector<DisplayMode> display_mode_overrides =
+      GetAppDisplayModeOverride(app_id);
+  return ResolveEffectiveDisplayMode(app_display_mode, display_mode_overrides,
+                                     user_display_mode);
+}
+
+DisplayMode WebAppRegistrar::GetEffectiveDisplayModeFromManifest(
+    const AppId& app_id) const {
+  std::vector<DisplayMode> display_mode_overrides =
+      GetAppDisplayModeOverride(app_id);
+
+  if (!display_mode_overrides.empty())
+    return display_mode_overrides[0];
+
+  return GetAppDisplayMode(app_id);
+}
+
+bool WebAppRegistrar::IsInExperimentalTabbedWindowMode(
+    const AppId& app_id) const {
+  return base::FeatureList::IsEnabled(features::kDesktopPWAsTabStrip) &&
+         base::FeatureList::IsEnabled(features::kDesktopPWAsTabStripSettings) &&
+         GetBoolWebAppPref(profile()->GetPrefs(), app_id,
+                           kExperimentalTabbedWindowMode);
+}
+
+bool WebAppRegistrar::IsTabbedWindowModeEnabled(const AppId& app_id) const {
+  if (!base::FeatureList::IsEnabled(features::kDesktopPWAsTabStrip))
+    return false;
+
+  DisplayMode display = GetAppEffectiveDisplayMode(app_id);
+
+  return IsInExperimentalTabbedWindowMode(app_id) ||
+         display == DisplayMode::kTabbed;
+}
 
 const WebApp* WebAppRegistrar::GetAppById(const AppId& app_id) const {
   if (registry_profile_being_deleted_)
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h
index 5ecf14d..cb00d86 100644
--- a/chrome/browser/web_applications/web_app_registrar.h
+++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -13,20 +13,24 @@
 
 #include "base/check_op.h"
 #include "chrome/browser/profiles/profile_manager_observer.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
+#include "components/services/app_service/public/cpp/file_handler.h"
+#include "components/services/app_service/public/cpp/protocol_handler_info.h"
+#include "components/services/app_service/public/cpp/url_handler_info.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace web_app {
 
+class AppRegistrarObserver;
 class WebApp;
+class OsIntegrationManager;
 
 using Registry = std::map<AppId, std::unique_ptr<WebApp>>;
 
 // A registry model. This is a read-only container, which owns WebApp objects.
-class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver {
+class WebAppRegistrar : public ProfileManagerObserver {
  public:
   explicit WebAppRegistrar(Profile* profile);
   WebAppRegistrar(const WebAppRegistrar&) = delete;
@@ -46,60 +50,204 @@
   // mechanism.
   bool WasInstalledByDefaultOnly(const AppId& app_id) const;
 
-  // AppRegistrar:
-  void Start() override;
-  void Shutdown() override;
-  bool IsInstalled(const AppId& app_id) const override;
-  bool IsUninstalling(const AppId& app_id) const override;
-  bool IsLocallyInstalled(const AppId& app_id) const override;
-  bool WasInstalledByUser(const AppId& app_id) const override;
-  bool WasInstalledByOem(const AppId& app_id) const override;
+  void Start();
+  void Shutdown();
+
+  // Returns whether the app with |app_id| is currently listed in the registry.
+  // ie. we have data for web app manifest and icons, and this |app_id| can be
+  // used in other registrar methods.
+  bool IsInstalled(const AppId& app_id) const;
+
+  // Returns whether the app is currently being uninstalled. This will be true
+  // after uninstall has begun but before the OS integration hooks for uninstall
+  // have completed. It will return false after uninstallation has completed.
+  // Note that the underlying field this checks is not yet persisted to the
+  // database; see https://crbug.com/1162477
+  bool IsUninstalling(const AppId& app_id) const;
+
+  // Returns whether the app with |app_id| is currently fully locally installed.
+  // ie. app is not grey in chrome://apps UI surface and may have OS integration
+  // like shortcuts. |IsLocallyInstalled| apps is a subset of |IsInstalled|
+  // apps. On Chrome OS all apps are always locally installed.
+  bool IsLocallyInstalled(const AppId& app_id) const;
+
+  // Returns true if the app was installed by user, false if default installed.
+  bool WasInstalledByUser(const AppId& app_id) const;
+
+  // Returns true if the app was installed by the device OEM. Always false on
+  // on non-Chrome OS.
+  bool WasInstalledByOem(const AppId& app_id) const;
+
+  // Returns the AppIds and URLs of apps externally installed from
+  // |install_source|.
+  virtual std::map<AppId, GURL> GetExternallyInstalledApps(
+      ExternalInstallSource install_source) const;
+
+  // Returns the app id for |install_url| if the WebAppRegistrar is aware of an
+  // externally installed app for it. Note that the |install_url| is the URL
+  // that the app was installed from, which may not necessarily match the app's
+  // current start URL.
+  virtual absl::optional<AppId> LookupExternalAppId(
+      const GURL& install_url) const;
+
+  // Returns whether the WebAppRegistrar has an externally installed app with
+  // |app_id| from any |install_source|.
+  virtual bool HasExternalApp(const AppId& app_id) const;
+
+  // Returns whether the WebAppRegistrar has an externally installed app with
+  // |app_id| from |install_source|.
+  virtual bool HasExternalAppWithInstallSource(
+      const AppId& app_id,
+      ExternalInstallSource install_source) const;
+
+  // Returns true if the web app with the |app_id| contains |protocol_scheme|
+  // as one of its approved launch protocols.
   bool IsApprovedLaunchProtocol(const AppId& app_id,
-                                std::string protocol_scheme) const override;
-  int CountUserInstalledApps() const override;
-  std::string GetAppShortName(const AppId& app_id) const override;
-  std::string GetAppDescription(const AppId& app_id) const override;
-  absl::optional<SkColor> GetAppThemeColor(const AppId& app_id) const override;
-  absl::optional<SkColor> GetAppBackgroundColor(
-      const AppId& app_id) const override;
-  const GURL& GetAppStartUrl(const AppId& app_id) const override;
-  absl::optional<std::string> GetAppManifestId(
-      const AppId& app_id) const override;
-  const std::string* GetAppLaunchQueryParams(
-      const AppId& app_id) const override;
-  const apps::ShareTarget* GetAppShareTarget(
-      const AppId& app_id) const override;
-  blink::mojom::CaptureLinks GetAppCaptureLinks(
-      const AppId& app_id) const override;
-  const apps::FileHandlers* GetAppFileHandlers(
-      const AppId& app_id) const override;
+                                std::string protocol_scheme) const;
+
+  // Count a number of all apps which are installed by user (non-default).
+  // Requires app registry to be in a ready state.
+  int CountUserInstalledApps() const;
+
+  // All names are UTF8 encoded.
+  std::string GetAppShortName(const AppId& app_id) const;
+  std::string GetAppDescription(const AppId& app_id) const;
+  absl::optional<SkColor> GetAppThemeColor(const AppId& app_id) const;
+  absl::optional<SkColor> GetAppBackgroundColor(const AppId& app_id) const;
+  const GURL& GetAppStartUrl(const AppId& app_id) const;
+  absl::optional<std::string> GetAppManifestId(const AppId& app_id) const;
+  const std::string* GetAppLaunchQueryParams(const AppId& app_id) const;
+  const apps::ShareTarget* GetAppShareTarget(const AppId& app_id) const;
+  blink::mojom::CaptureLinks GetAppCaptureLinks(const AppId& app_id) const;
+  const apps::FileHandlers* GetAppFileHandlers(const AppId& app_id) const;
   const apps::ProtocolHandlers* GetAppProtocolHandlers(
-      const AppId& app_id) const override;
-  bool IsAppFileHandlerPermissionBlocked(
-      const web_app::AppId& app_id) const override;
-  absl::optional<GURL> GetAppScopeInternal(const AppId& app_id) const override;
-  DisplayMode GetAppDisplayMode(const AppId& app_id) const override;
-  DisplayMode GetAppUserDisplayMode(const AppId& app_id) const override;
-  std::vector<DisplayMode> GetAppDisplayModeOverride(
-      const AppId& app_id) const override;
-  apps::UrlHandlers GetAppUrlHandlers(const AppId& app_id) const override;
-  GURL GetAppManifestUrl(const AppId& app_id) const override;
-  base::Time GetAppLastBadgingTime(const AppId& app_id) const override;
-  base::Time GetAppLastLaunchTime(const AppId& app_id) const override;
-  base::Time GetAppInstallTime(const AppId& app_id) const override;
+      const AppId& app_id) const;
+  bool IsAppFileHandlerPermissionBlocked(const web_app::AppId& app_id) const;
+
+  // Returns the start_url with launch_query_params appended to the end if any.
+  GURL GetAppLaunchUrl(const AppId& app_id) const;
+
+  // TODO(crbug.com/910016): Replace uses of this with GetAppScope().
+  absl::optional<GURL> GetAppScopeInternal(const AppId& app_id) const;
+
+  DisplayMode GetAppDisplayMode(const AppId& app_id) const;
+  DisplayMode GetAppUserDisplayMode(const AppId& app_id) const;
+  std::vector<DisplayMode> GetAppDisplayModeOverride(const AppId& app_id) const;
+
+  // Returns the "url_handlers" field from the app manifest.
+  apps::UrlHandlers GetAppUrlHandlers(const AppId& app_id) const;
+
+  GURL GetAppManifestUrl(const AppId& app_id) const;
+
+  base::Time GetAppLastBadgingTime(const AppId& app_id) const;
+  base::Time GetAppLastLaunchTime(const AppId& app_id) const;
+  base::Time GetAppInstallTime(const AppId& app_id) const;
+
+  // Returns the "icons" field from the app manifest, use |AppIconManager| to
+  // load icon bitmap data.
   std::vector<WebApplicationIconInfo> GetAppIconInfos(
-      const AppId& app_id) const override;
-  SortedSizesPx GetAppDownloadedIconSizesAny(
-      const AppId& app_id) const override;
+      const AppId& app_id) const;
+
+  // Represents which icon sizes we successfully downloaded from the IconInfos.
+  SortedSizesPx GetAppDownloadedIconSizesAny(const AppId& app_id) const;
+
+  // Returns the "shortcuts" field from the app manifest, use |AppIconManager|
+  // to load shortcuts menu icons bitmaps data.
   std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutsMenuItemInfos(
-      const AppId& app_id) const override;
+      const AppId& app_id) const;
+
+  // Represents which icon sizes we successfully downloaded from the
+  // ShortcutsMenuItemInfos.
   std::vector<IconSizes> GetAppDownloadedShortcutsMenuIconsSizes(
-      const AppId& app_id) const override;
-  RunOnOsLoginMode GetAppRunOnOsLoginMode(const AppId& app_id) const override;
-  bool GetWindowControlsOverlayEnabled(const AppId& app_id) const override;
-  std::vector<AppId> GetAppIds() const override;
-  WebAppRegistrar* AsWebAppRegistrar() override;
-  const WebAppRegistrar* AsWebAppRegistrar() const override;
+      const AppId& app_id) const;
+
+  // Returns the Run on OS Login mode.
+  RunOnOsLoginMode GetAppRunOnOsLoginMode(const AppId& app_id) const;
+
+  bool GetWindowControlsOverlayEnabled(const AppId& app_id) const;
+
+  std::vector<AppId> GetAppIds() const;
+
+  // TODO: Remove AsWebAppRegistrar.
+  WebAppRegistrar* AsWebAppRegistrar();
+  const WebAppRegistrar* AsWebAppRegistrar() const;
+
+  void SetSubsystems(OsIntegrationManager* os_integration_manager);
+
+  // Returns the "scope" field from the app manifest, or infers a scope from the
+  // "start_url" field if unavailable. Returns an invalid GURL iff the |app_id|
+  // does not refer to an installed web app.
+  GURL GetAppScope(const AppId& app_id) const;
+
+  // Returns the app id of an app in the registry with the longest scope that is
+  // a prefix of |url|, if any.
+  absl::optional<AppId> FindAppWithUrlInScope(const GURL& url) const;
+
+  // Returns true if there exists at least one app installed under |scope|.
+  bool DoesScopeContainAnyApp(const GURL& scope) const;
+
+  // Finds all apps that are installed under |scope|.
+  std::vector<AppId> FindAppsInScope(const GURL& scope) const;
+
+  // Returns the app id of an installed app in the registry with the longest
+  // scope that is a prefix of |url|, if any. If |window_only| is specified,
+  // only apps that open in app windows will be considered.
+  absl::optional<AppId> FindInstalledAppWithUrlInScope(
+      const GURL& url,
+      bool window_only = false) const;
+
+  // Returns whether the app is a shortcut app (as opposed to a PWA).
+  bool IsShortcutApp(const AppId& app_id) const;
+
+  // Returns true if the app with the specified |start_url| is currently fully
+  // locally installed. The provided |start_url| must exactly match the launch
+  // URL for the app; this method does not consult the app scope or match URLs
+  // that fall within the scope.
+  bool IsLocallyInstalled(const GURL& start_url) const;
+
+  // Returns whether the app is pending successful navigation in order to
+  // complete installation via the ExternallyManagedAppManager.
+  bool IsPlaceholderApp(const AppId& app_id) const;
+
+  // Computes and returns the DisplayMode, accounting for user preference
+  // to launch in a browser window and entries in the web app manifest.
+  DisplayMode GetAppEffectiveDisplayMode(const AppId& app_id) const;
+
+  // Computes and returns the DisplayMode only accounting for
+  // entries in the web app manifest.
+  DisplayMode GetEffectiveDisplayModeFromManifest(const AppId& app_id) const;
+
+  // Returns whether the app should be opened in tabbed window mode.
+  bool IsTabbedWindowModeEnabled(const AppId& app_id) const;
+
+  // TODO(crbug.com/897314): This can be removed once feature has launched.
+  bool IsInExperimentalTabbedWindowMode(const AppId& app_id) const;
+
+  void AddObserver(AppRegistrarObserver* observer);
+  void RemoveObserver(AppRegistrarObserver* observer);
+
+  void NotifyWebAppInstalled(const AppId& app_id);
+  void NotifyWebAppManifestUpdated(const AppId& app_id,
+                                   base::StringPiece old_name);
+  void NotifyWebAppsWillBeUpdatedFromSync(
+      const std::vector<const WebApp*>& new_apps_state);
+  void NotifyWebAppUninstalled(const AppId& app_id);
+  void NotifyWebAppWillBeUninstalled(const AppId& app_id);
+  void NotifyWebAppLocallyInstalledStateChanged(const AppId& app_id,
+                                                bool is_locally_installed);
+  void NotifyWebAppDisabledStateChanged(const AppId& app_id, bool is_disabled);
+  void NotifyWebAppsDisabledModeChanged();
+  void NotifyWebAppLastLaunchTimeChanged(const AppId& app_id,
+                                         const base::Time& time);
+  void NotifyWebAppInstallTimeChanged(const AppId& app_id,
+                                      const base::Time& time);
+
+  // Notify when OS hooks installation is finished during Web App installation.
+  void NotifyWebAppInstalledWithOsHooks(const AppId& app_id);
+  void NotifyWebAppUserDisplayModeChanged(const AppId& app_id,
+                                          DisplayMode user_display_mode);
+  void NotifyWebAppExperimentalTabbedWindowModeChanged(const AppId& app_id,
+                                                       bool enabled);
 
   // ProfileManagerObserver:
   void OnProfileMarkedForPermanentDeletion(
@@ -184,6 +332,14 @@
   const AppSet GetApps() const;
 
  protected:
+  Profile* profile() const { return profile_; }
+  OsIntegrationManager& os_integration_manager() {
+    return *os_integration_manager_;
+  }
+
+  void NotifyWebAppProfileWillBeDeleted(const AppId& app_id);
+  void NotifyAppRegistrarShutdown();
+
   Registry& registry() { return registry_; }
   void SetRegistry(Registry&& registry);
 
@@ -192,6 +348,11 @@
   void CountMutation();
 
  private:
+  Profile* const profile_;
+
+  base::ObserverList<AppRegistrarObserver, /*check_empty=*/true> observers_;
+  OsIntegrationManager* os_integration_manager_ = nullptr;
+
   Registry registry_;
   bool registry_profile_being_deleted_ = false;
 #if DCHECK_IS_ON()
diff --git a/chrome/browser/web_applications/web_app_shortcut_manager.cc b/chrome/browser/web_applications/web_app_shortcut_manager.cc
index 56d60b66..d07c925 100644
--- a/chrome/browser/web_applications/web_app_shortcut_manager.cc
+++ b/chrome/browser/web_applications/web_app_shortcut_manager.cc
@@ -12,7 +12,6 @@
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/file_handler_manager.h"
 #include "chrome/browser/web_applications/components/protocol_handler_manager.h"
 #include "chrome/browser/web_applications/components/web_app_shortcut.h"
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc
index 13e8f6ad..30ffa80b 100644
--- a/chrome/browser/web_applications/web_app_sync_bridge.cc
+++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -19,12 +19,12 @@
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_prefs_utils.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_database.h"
 #include "chrome/browser/web_applications/web_app_database_factory.h"
 #include "chrome/browser/web_applications/web_app_proto_utils.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registry_update.h"
 #include "chrome/browser/web_applications/web_app_sync_install_delegate.h"
 #include "chrome/common/channel_info.h"
diff --git a/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc b/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc
index 7f5eb2c..8dfa2f7 100644
--- a/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc
+++ b/chrome/browser/web_applications/web_app_sync_bridge_unittest.cc
@@ -16,13 +16,13 @@
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/test/test_web_app_database_factory.h"
 #include "chrome/browser/web_applications/test/test_web_app_registry_controller.h"
 #include "chrome/browser/web_applications/test/web_app_install_observer.h"
 #include "chrome/browser/web_applications/test/web_app_test.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registry_update.h"
 #include "components/sync/model/data_batch.h"
 #include "components/sync/model/entity_change.h"
diff --git a/chrome/browser/web_applications/web_app_tab_helper.cc b/chrome/browser/web_applications/web_app_tab_helper.cc
index 46bf977..25f1dfa 100644
--- a/chrome/browser/web_applications/web_app_tab_helper.cc
+++ b/chrome/browser/web_applications/web_app_tab_helper.cc
@@ -11,11 +11,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/components/os_integration_manager.h"
 #include "chrome/browser/web_applications/components/web_app_audio_focus_id_map.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
 #include "chrome/browser/web_applications/components/web_app_ui_manager.h"
 #include "chrome/browser/web_applications/manifest_update_manager.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
 #include "content/public/browser/media_session.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/site_instance.h"
@@ -32,7 +32,7 @@
 
 WebAppTabHelper::WebAppTabHelper(content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
-      provider_(WebAppProviderBase::GetProviderBase(
+      provider_(WebAppProvider::GetForWebApps(
           Profile::FromBrowserContext(web_contents->GetBrowserContext()))) {
   DCHECK(provider_);
   observation_.Observe(&provider_->registrar());
diff --git a/chrome/browser/web_applications/web_app_tab_helper.h b/chrome/browser/web_applications/web_app_tab_helper.h
index 1a8879d..302e898 100644
--- a/chrome/browser/web_applications/web_app_tab_helper.h
+++ b/chrome/browser/web_applications/web_app_tab_helper.h
@@ -7,9 +7,9 @@
 
 #include "base/scoped_observation.h"
 #include "base/unguessable_token.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
@@ -19,7 +19,7 @@
 
 namespace web_app {
 
-class WebAppProviderBase;
+class WebAppProvider;
 
 // Per-tab web app helper. Allows to associate a tab (web page) with a web app
 // (or legacy bookmark app).
@@ -90,9 +90,9 @@
 
   bool has_loaded_non_about_blank_page_ = false;
 
-  base::ScopedObservation<AppRegistrar, AppRegistrarObserver> observation_{
+  base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver> observation_{
       this};
-  WebAppProviderBase* provider_ = nullptr;
+  WebAppProvider* provider_ = nullptr;
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
diff --git a/chrome/browser/web_applications/web_app_utils.cc b/chrome/browser/web_applications/web_app_utils.cc
index 578de2b..30a40643 100644
--- a/chrome/browser/web_applications/web_app_utils.cc
+++ b/chrome/browser/web_applications/web_app_utils.cc
@@ -11,8 +11,8 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/app_registrar.h"
-#include "chrome/browser/web_applications/components/web_app_provider_base.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/site_engagement/content/site_engagement_service.h"
@@ -185,11 +185,11 @@
 
 apps::FileHandlers GetFileHandlersForAllWebAppsWithOrigin(Profile* profile,
                                                           const GURL& url) {
-  auto* provider = WebAppProviderBase::GetProviderBase(profile);
+  auto* provider = WebAppProvider::GetForWebApps(profile);
   if (!provider)
     return {};
 
-  const AppRegistrar& registrar = provider->registrar();
+  const WebAppRegistrar& registrar = provider->registrar();
   std::vector<AppId> app_ids = registrar.FindAppsInScope(url.GetOrigin());
   if (app_ids.empty())
     return {};
diff --git a/chrome/common/extensions/api/accessibility_private.json b/chrome/common/extensions/api/accessibility_private.json
index df0a05ff..d7976d51 100644
--- a/chrome/common/extensions/api/accessibility_private.json
+++ b/chrome/common/extensions/api/accessibility_private.json
@@ -225,7 +225,7 @@
       {
         "id": "AccessibilityFeature",
         "type": "string",
-        "enum": [ "selectToSpeakNavigationControl" ],
+        "enum": [ "selectToSpeakNavigationControl", "enhancedNetworkVoices" ],
         "description": "Subset of accessibility features."
       },
       {
diff --git a/chrome/services/printing/BUILD.gn b/chrome/services/printing/BUILD.gn
index d8b4d5d1..15b3bca6 100644
--- a/chrome/services/printing/BUILD.gn
+++ b/chrome/services/printing/BUILD.gn
@@ -40,16 +40,22 @@
     ]
   }
 
-  if (is_chromeos_ash) {
+  if (is_chromeos) {
     sources += [
       "pdf_flattener.cc",
       "pdf_flattener.h",
+    ]
+
+    deps += [ "//pdf" ]
+  }
+
+  if (is_chromeos_ash) {
+    sources += [
       "pdf_thumbnailer.cc",
       "pdf_thumbnailer.h",
     ]
 
     deps += [
-      "//build:chromeos_buildflags",
       "//pdf",
       "//ui/gfx/codec",
     ]
diff --git a/chrome/services/printing/pdf_thumbnailer.cc b/chrome/services/printing/pdf_thumbnailer.cc
index 9bb07d63..e93a3e7e 100644
--- a/chrome/services/printing/pdf_thumbnailer.cc
+++ b/chrome/services/printing/pdf_thumbnailer.cc
@@ -10,7 +10,6 @@
 #include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/memory/shared_memory_mapping.h"
-#include "build/chromeos_buildflags.h"
 #include "pdf/pdf.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
@@ -30,7 +29,6 @@
 
 PdfThumbnailer::~PdfThumbnailer() = default;
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 void PdfThumbnailer::GetThumbnail(printing::mojom::ThumbParamsPtr params,
                                   base::ReadOnlySharedMemoryRegion pdf_region,
                                   GetThumbnailCallback callback) {
@@ -83,6 +81,5 @@
   DCHECK_EQ(height_px, result.height());
   std::move(callback).Run(result);
 }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace printing
diff --git a/chrome/services/printing/pdf_thumbnailer.h b/chrome/services/printing/pdf_thumbnailer.h
index c60ddff..a3656cf8 100644
--- a/chrome/services/printing/pdf_thumbnailer.h
+++ b/chrome/services/printing/pdf_thumbnailer.h
@@ -6,7 +6,6 @@
 #define CHROME_SERVICES_PRINTING_PDF_THUMBNAILER_H_
 
 #include "base/memory/read_only_shared_memory_region.h"
-#include "build/chromeos_buildflags.h"
 #include "chrome/services/printing/public/mojom/pdf_thumbnailer.mojom.h"
 
 namespace printing {
@@ -22,12 +21,10 @@
   PdfThumbnailer(const PdfThumbnailer&) = delete;
   PdfThumbnailer& operator=(const PdfThumbnailer&) = delete;
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   // printing::mojom::PdfThumbnailer:
   void GetThumbnail(printing::mojom::ThumbParamsPtr params,
                     base::ReadOnlySharedMemoryRegion pdf_region,
                     GetThumbnailCallback callback) override;
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   // The maximum width of a thumbnail we accept. If the specified width
   // exceeds the maximum, an empty, invalid bitmap is returned.
diff --git a/chrome/services/printing/printing_service.cc b/chrome/services/printing/printing_service.cc
index 80666ab..2427c92 100644
--- a/chrome/services/printing/printing_service.cc
+++ b/chrome/services/printing/printing_service.cc
@@ -10,8 +10,11 @@
 #include "chrome/services/printing/pdf_to_pwg_raster_converter.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 #include "chrome/services/printing/pdf_flattener.h"
+#endif
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/services/printing/pdf_thumbnailer.h"
 #endif
 
@@ -41,13 +44,15 @@
       std::move(receiver));
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 void PrintingService::BindPdfFlattener(
     mojo::PendingReceiver<mojom::PdfFlattener> receiver) {
   mojo::MakeSelfOwnedReceiver(std::make_unique<printing::PdfFlattener>(),
                               std::move(receiver));
 }
+#endif
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
 void PrintingService::BindPdfThumbnailer(
     mojo::PendingReceiver<mojom::PdfThumbnailer> receiver) {
   mojo::MakeSelfOwnedReceiver(std::make_unique<printing::PdfThumbnailer>(),
diff --git a/chrome/services/printing/printing_service.h b/chrome/services/printing/printing_service.h
index 8637bac..f76f5e2 100644
--- a/chrome/services/printing/printing_service.h
+++ b/chrome/services/printing/printing_service.h
@@ -26,9 +26,11 @@
       mojo::PendingReceiver<mojom::PdfNupConverter> receiver) override;
   void BindPdfToPwgRasterConverter(
       mojo::PendingReceiver<mojom::PdfToPwgRasterConverter> receiver) override;
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
   void BindPdfFlattener(
       mojo::PendingReceiver<mojom::PdfFlattener> receiver) override;
+#endif
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   void BindPdfThumbnailer(
       mojo::PendingReceiver<mojom::PdfThumbnailer> receiver) override;
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/services/printing/public/mojom/BUILD.gn b/chrome/services/printing/public/mojom/BUILD.gn
index aa96e58..bae6a32 100644
--- a/chrome/services/printing/public/mojom/BUILD.gn
+++ b/chrome/services/printing/public/mojom/BUILD.gn
@@ -23,11 +23,12 @@
     "//url/mojom:url_mojom_gurl",
   ]
 
+  if (is_chromeos) {
+    sources += [ "pdf_flattener.mojom" ]
+  }
+
   if (is_chromeos_ash) {
-    sources += [
-      "pdf_flattener.mojom",
-      "pdf_thumbnailer.mojom",
-    ]
+    sources += [ "pdf_thumbnailer.mojom" ]
     deps += [ "//skia/public/mojom" ]
   }
 
diff --git a/chrome/services/printing/public/mojom/pdf_thumbnailer.mojom b/chrome/services/printing/public/mojom/pdf_thumbnailer.mojom
index b497584..46f60cee5 100644
--- a/chrome/services/printing/public/mojom/pdf_thumbnailer.mojom
+++ b/chrome/services/printing/public/mojom/pdf_thumbnailer.mojom
@@ -30,7 +30,6 @@
   // |params| dictate details (e.g., size) of the thumbnail. |pdf_region|
   // should hold bytes of the PDF for which the thumbnail is generated.
   // |bitmap| contains the generated PDF thumbnail.
-  [EnableIf=is_chromeos_ash]
   GetThumbnail(ThumbParams params,
                mojo_base.mojom.ReadOnlySharedMemoryRegion pdf_region)
       => (skia.mojom.BitmapN32? bitmap);
diff --git a/chrome/services/printing/public/mojom/printing_service.mojom b/chrome/services/printing/public/mojom/printing_service.mojom
index d4da52f..dc16846 100644
--- a/chrome/services/printing/public/mojom/printing_service.mojom
+++ b/chrome/services/printing/public/mojom/printing_service.mojom
@@ -7,7 +7,7 @@
 import "chrome/services/printing/public/mojom/pdf_nup_converter.mojom";
 import "chrome/services/printing/public/mojom/pdf_to_pwg_raster_converter.mojom";
 
-[EnableIf=is_chromeos_ash]
+[EnableIf=is_chromeos]
 import "chrome/services/printing/public/mojom/pdf_flattener.mojom";
 [EnableIf=is_chromeos_ash]
 import "chrome/services/printing/public/mojom/pdf_thumbnailer.mojom";
@@ -26,7 +26,7 @@
       pending_receiver<PdfToPwgRasterConverter> receiver);
 
   // Binds an interface that can be used to flatten a PDF.
-  [EnableIf=is_chromeos_ash]
+  [EnableIf=is_chromeos]
   BindPdfFlattener(pending_receiver<PdfFlattener> receiver);
 
   // Binds an interface that is used to generate thumbnails for PDF content.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index f2c68df..46dacbb6 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1623,6 +1623,7 @@
       "../browser/page_load_metrics/observers/live_tab_count_page_load_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/multi_tab_loading_page_load_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/prefetch_proxy_page_load_metrics_observer_browsertest.cc",
+      "../browser/page_load_metrics/observers/prerender_page_load_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/signed_exchange_page_load_metrics_browsertest.cc",
       "../browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc",
@@ -6831,7 +6832,6 @@
       "../browser/safe_browsing/incident_reporting/tracked_preference_incident_unittest.cc",
       "../browser/safe_browsing/local_two_phase_testserver.cc",
       "../browser/safe_browsing/local_two_phase_testserver.h",
-      "../browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc",
       "../browser/safe_browsing/verdict_cache_manager_factory_unittest.cc",
       "../common/safe_browsing/binary_feature_extractor_unittest.cc",
       "../common/safe_browsing/download_type_util_unittest.cc",
@@ -7311,7 +7311,7 @@
       "../browser/ui/views/webid/webid_dialog_views_unittest.cc",
       "../browser/ui/views/window_name_prompt_unittest.cc",
     ]
-    if (is_linux || is_chromeos_lacros) {
+    if (is_linux) {
       sources += [ "../browser/ui/views/frame/browser_frame_view_layout_linux_native_unittest.cc" ]
     }
     if (enable_plugins) {
@@ -7330,11 +7330,13 @@
     }
     if (!is_chromeos_ash) {
       sources += [
-        "../browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc",
         "../browser/ui/views/sync/one_click_signin_dialog_view_unittest.cc",
         "../browser/ui/views/sync/profile_signin_confirmation_dialog_views_unittest.cc",
       ]
     }
+    if (!is_chromeos) {
+      sources += [ "../browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc" ]
+    }
     if (use_aura) {
       sources += [
         "../browser/ui/views/apps/shaped_app_window_targeter_unittest.cc",
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index a6b222b7..48bec33 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -1935,7 +1935,7 @@
 
   session->input_cancel_list.clear();
   session->input_state_table.Clear();
-  session->active_input_sources.Clear();
+  session->active_input_sources.ClearList();
   session->mouse_position = WebPoint(0, 0);
   session->click_count = 0;
   session->mouse_click_timestamp = base::TimeTicks::Now();
diff --git a/chrome/test/data/webui/cr_components/BUILD.gn b/chrome/test/data/webui/cr_components/BUILD.gn
index eb83fa5..92a08bf1 100644
--- a/chrome/test/data/webui/cr_components/BUILD.gn
+++ b/chrome/test/data/webui/cr_components/BUILD.gn
@@ -16,25 +16,12 @@
                   ]
 
   deps = [
-    ":customize_themes_test",
     ":managed_dialog_test",
     ":most_visited_focus_test",
     ":most_visited_test",
   ]
 }
 
-js_library("customize_themes_test") {
-  deps = [
-    "..:chai_assert",
-    "..:test_browser_proxy.m",
-    "..:test_util.m",
-    "//ui/webui/resources/cr_components/customize_themes",
-    "//ui/webui/resources/cr_components/customize_themes:browser_proxy",
-    "//ui/webui/resources/cr_components/customize_themes:theme_icon",
-  ]
-  externs_list = [ "$externs_path/mocha-2.5.js" ]
-}
-
 js_library("managed_dialog_test") {
   deps = [
     "..:chai_assert",
diff --git a/chrome/test/data/webui/cr_components/customize_themes_test.js b/chrome/test/data/webui/cr_components/customize_themes_test.js
index 7b675b5..7df683d0 100644
--- a/chrome/test/data/webui/cr_components/customize_themes_test.js
+++ b/chrome/test/data/webui/cr_components/customize_themes_test.js
@@ -5,7 +5,7 @@
 import 'chrome://new-tab-page/strings.m.js';
 import '../mojo_webui_test_support.js';
 
-import {CustomizeThemesBrowserProxy, CustomizeThemesBrowserProxyImpl} from 'chrome://resources/cr_components/customize_themes/browser_proxy.js';
+import {CustomizeThemesBrowserProxyImpl} from 'chrome://resources/cr_components/customize_themes/browser_proxy.js';
 import {CustomizeThemesElement} from 'chrome://resources/cr_components/customize_themes/customize_themes.js';
 import {ChromeTheme, CustomizeThemesClientCallbackRouter, CustomizeThemesHandlerInterface, ThemeType} from 'chrome://resources/cr_components/customize_themes/customize_themes.mojom-webui.js';
 import {ThemeIconElement} from 'chrome://resources/cr_components/customize_themes/theme_icon.js';
@@ -137,7 +137,7 @@
   setup(() => {
     document.innerHTML = '';
     testProxy = new TestCustomizeThemesBrowserProxy();
-    CustomizeThemesBrowserProxyImpl.instance_ = testProxy;
+    CustomizeThemesBrowserProxyImpl.setInstance(testProxy);
   });
 
   test('creating element shows theme tiles', async () => {
diff --git a/chrome/test/data/webui/new_tab_page/modules/modules_test.js b/chrome/test/data/webui/new_tab_page/modules/modules_test.js
index 7e075cf..638f8299 100644
--- a/chrome/test/data/webui/new_tab_page/modules/modules_test.js
+++ b/chrome/test/data/webui/new_tab_page/modules/modules_test.js
@@ -233,7 +233,7 @@
       });
     });
 
-    test('drag first module to second position', async () => {
+    test('drag first module to third position', async () => {
       // Arrange.
       const moduleArray = [];
       for (let i = 0; i < 3; ++i) {
@@ -261,30 +261,80 @@
 
       let moduleWrappers = Array.from(
           modulesElement.shadowRoot.querySelectorAll('ntp-module-wrapper'));
-      const moduleWrapper = moduleWrappers[0];
-      assertTrue(!!moduleWrapper);
+      const firstModule = moduleWrappers[0];
+      const secondModule = moduleWrappers[1];
+      const thirdModule = moduleWrappers[2];
+      assertTrue(!!firstModule);
+      assertTrue(!!secondModule);
+      assertTrue(!!thirdModule);
 
-      const moduleRect = moduleWrapper.getBoundingClientRect();
-      const startX = moduleRect.x + moduleRect.width / 2;
-      const startY = moduleRect.y + moduleRect.height / 2;
+      const firstPositionRect = moduleWrappers[0].getBoundingClientRect();
       const secondPositionRect = moduleWrappers[1].getBoundingClientRect();
+      const thirdPositionRect = moduleWrappers[2].getBoundingClientRect();
+
+      const startX = firstPositionRect.x + firstPositionRect.width / 2;
+      const startY = firstPositionRect.y + firstPositionRect.height / 2;
+      let changeX = 10;
+      let changeY = firstPositionRect.height;
 
       // Act.
-      moduleWrapper.dispatchEvent(new DragEvent('dragstart', {
+      firstModule.dispatchEvent(new DragEvent('dragstart', {
         clientX: startX,
         clientY: startY,
       }));
 
       document.dispatchEvent(new DragEvent('dragover', {
-        clientX: startX + 10,
-        clientY: startY + moduleRect.height,
+        clientX: startX + changeX,
+        clientY: startY + changeY,
       }));
 
       // Assert.
-      assertEquals(moduleRect.x + 10, moduleWrapper.getBoundingClientRect().x);
       assertEquals(
-          moduleRect.y + moduleRect.height,
-          moduleWrapper.getBoundingClientRect().y);
+          firstPositionRect.x + changeX, firstModule.getBoundingClientRect().x);
+      assertEquals(
+          firstPositionRect.y + changeY, firstModule.getBoundingClientRect().y);
+
+      // Act.
+      secondModule.dispatchEvent(new DragEvent('dragenter'));
+
+      // Assert.
+      moduleWrappers = Array.from(
+          modulesElement.shadowRoot.querySelectorAll('ntp-module-wrapper'));
+      assertEquals(0, moduleWrappers.indexOf(secondModule));
+      assertEquals(1, moduleWrappers.indexOf(firstModule));
+      assertEquals(2, moduleWrappers.indexOf(thirdModule));
+      assertEquals(firstPositionRect.x, secondModule.getBoundingClientRect().x);
+      assertEquals(firstPositionRect.y, secondModule.getBoundingClientRect().y);
+      assertEquals(thirdPositionRect.x, thirdModule.getBoundingClientRect().x);
+      assertEquals(thirdPositionRect.y, thirdModule.getBoundingClientRect().y);
+
+      // Act.
+      changeX += 5;
+      changeY += firstPositionRect.height;
+      document.dispatchEvent(new DragEvent('dragover', {
+        clientX: startX + changeX,
+        clientY: startY + changeY,
+      }));
+
+      // Assert.
+      assertEquals(
+          firstPositionRect.x + changeX, firstModule.getBoundingClientRect().x);
+      assertEquals(
+          firstPositionRect.y + changeY, firstModule.getBoundingClientRect().y);
+
+      // Act.
+      thirdModule.dispatchEvent(new DragEvent('dragenter'));
+
+      // Assert.
+      moduleWrappers = Array.from(
+          modulesElement.shadowRoot.querySelectorAll('ntp-module-wrapper'));
+      assertEquals(0, moduleWrappers.indexOf(secondModule));
+      assertEquals(1, moduleWrappers.indexOf(thirdModule));
+      assertEquals(2, moduleWrappers.indexOf(firstModule));
+      assertEquals(firstPositionRect.x, secondModule.getBoundingClientRect().x);
+      assertEquals(firstPositionRect.y, secondModule.getBoundingClientRect().y);
+      assertEquals(secondPositionRect.x, thirdModule.getBoundingClientRect().x);
+      assertEquals(secondPositionRect.y, thirdModule.getBoundingClientRect().y);
 
       // Act.
       document.dispatchEvent(new DragEvent('dragend'));
@@ -292,11 +342,9 @@
       // Assert.
       moduleWrappers = Array.from(
           modulesElement.shadowRoot.querySelectorAll('ntp-module-wrapper'));
-      assertEquals(1, moduleWrappers.indexOf(moduleWrapper));
-      assertEquals(
-          secondPositionRect.x, moduleWrapper.getBoundingClientRect().x);
-      assertEquals(
-          secondPositionRect.y, moduleWrapper.getBoundingClientRect().y);
+      assertEquals(2, moduleWrappers.indexOf(firstModule));
+      assertEquals(thirdPositionRect.x, firstModule.getBoundingClientRect().x);
+      assertEquals(thirdPositionRect.y, firstModule.getBoundingClientRect().y);
     });
   });
 });
diff --git a/chrome/test/data/webui/signin/BUILD.gn b/chrome/test/data/webui/signin/BUILD.gn
index a227c7b..c51ef8b1 100644
--- a/chrome/test/data/webui/signin/BUILD.gn
+++ b/chrome/test/data/webui/signin/BUILD.gn
@@ -49,6 +49,7 @@
     "..:chai_assert",
     "..:test_util.m",
     "//chrome/browser/resources/signin/dice_web_signin_intercept:dice_web_signin_intercept_app",
+    "//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite",
     "//ui/webui/resources/js:cr.m",
   ]
   externs_list = [ "$externs_path/mocha-2.5.js" ]
diff --git a/chrome/test/data/webui/signin/dice_web_signin_intercept_test.js b/chrome/test/data/webui/signin/dice_web_signin_intercept_test.js
index 0197c2fe..54ef995 100644
--- a/chrome/test/data/webui/signin/dice_web_signin_intercept_test.js
+++ b/chrome/test/data/webui/signin/dice_web_signin_intercept_test.js
@@ -81,7 +81,8 @@
 
   test('ClickAccept', function() {
     assertTrue(isChildVisible(app, '#acceptButton'));
-    const spinner = app.$$('paper-spinner-lite');
+    const spinner =
+        /** @type {PaperSpinnerLiteElement} */ (app.$$('paper-spinner-lite'));
     const acceptButton = app.$$('#acceptButton');
     const cancelButton = app.$$('#cancelButton');
     assertFalse(spinner.active);
diff --git a/chrome/test/data/webui/usb_internals_test.js b/chrome/test/data/webui/usb_internals_test.js
index 10da37f..ff260686 100644
--- a/chrome/test/data/webui/usb_internals_test.js
+++ b/chrome/test/data/webui/usb_internals_test.js
@@ -124,10 +124,10 @@
     if (!response) {
       return {
         status: UsbTransferStatus.TRANSFER_ERROR,
-        data: [],
+        data: {buffer: []},
       };
     }
-    response.data = response.data.slice(0, length);
+    response.data = {buffer: response.data.slice(0, length)};
     return response;
   }
 
diff --git a/chromecast/crash/linux/synchronized_minidump_manager.cc b/chromecast/crash/linux/synchronized_minidump_manager.cc
index d38283e..23a22d4 100644
--- a/chromecast/crash/linux/synchronized_minidump_manager.cc
+++ b/chromecast/crash/linux/synchronized_minidump_manager.cc
@@ -392,7 +392,7 @@
 
 bool SynchronizedMinidumpManager::SetCurrentDumps(
     const std::vector<std::unique_ptr<DumpInfo>>& dumps) {
-  dumps_->Clear();
+  dumps_->ClearList();
 
   for (auto& dump : dumps)
     dumps_->Append(dump->GetAsValue());
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 59aae2c..36f9457 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-14086.0.0
\ No newline at end of file
+14087.0.0
\ No newline at end of file
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index c9d1b2e..f4c8ca1 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -1576,6 +1576,9 @@
       <message name="IDS_TRAFFIC_COUNTERS_REQUEST_TRAFFIC_COUNTERS" desc="Label for button requesting traffic counters">
         Request Traffic Counters
       </message>
+      <message name="IDS_TRAFFIC_COUNTERS_RESET_TRAFFIC_COUNTERS" desc="Label for button resetting traffic counters">
+        Reset Traffic Counters
+      </message>
       <message name="IDS_TRAFFIC_COUNTERS_TRAFFIC_COUNTERS" desc="Label for showing traffic counters">
         Traffic Counters
       </message>
diff --git a/chromeos/chromeos_strings_grd/IDS_TRAFFIC_COUNTERS_RESET_TRAFFIC_COUNTERS.png.sha1 b/chromeos/chromeos_strings_grd/IDS_TRAFFIC_COUNTERS_RESET_TRAFFIC_COUNTERS.png.sha1
new file mode 100644
index 0000000..337c5994
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_TRAFFIC_COUNTERS_RESET_TRAFFIC_COUNTERS.png.sha1
@@ -0,0 +1 @@
+392e722fdef80106b98cee2918a239921b689f65
\ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/css/main.css b/chromeos/components/camera_app_ui/resources/css/main.css
index ce8e1559..0d0e5e44 100644
--- a/chromeos/components/camera_app_ui/resources/css/main.css
+++ b/chromeos/components/camera_app_ui/resources/css/main.css
@@ -74,6 +74,9 @@
 
 [tabindex] {
   outline: none; /* Prevent default focus ring style. */
+}
+
+[i18n-text] {
   user-select: none;
 }
 
@@ -242,6 +245,7 @@
   overflow: auto;
   pointer-events: auto;
   text-align: center;
+  user-select: none;
   white-space: nowrap;
 }
 
diff --git a/chromeos/components/network_ui/traffic_counters_resource_provider.cc b/chromeos/components/network_ui/traffic_counters_resource_provider.cc
index d4eb715..7a3dc8f 100644
--- a/chromeos/components/network_ui/traffic_counters_resource_provider.cc
+++ b/chromeos/components/network_ui/traffic_counters_resource_provider.cc
@@ -29,6 +29,8 @@
     {"TrafficCountersTrafficCounters", IDS_TRAFFIC_COUNTERS_TRAFFIC_COUNTERS},
     {"TrafficCountersRequestTrafficCounters",
      IDS_TRAFFIC_COUNTERS_REQUEST_TRAFFIC_COUNTERS},
+    {"TrafficCountersResetTrafficCounters",
+     IDS_TRAFFIC_COUNTERS_RESET_TRAFFIC_COUNTERS},
 };
 
 }  // namespace
diff --git a/chromeos/dbus/shill/fake_shill_manager_client.cc b/chromeos/dbus/shill/fake_shill_manager_client.cc
index 1104463c..3c383b36 100644
--- a/chromeos/dbus/shill/fake_shill_manager_client.cc
+++ b/chromeos/dbus/shill/fake_shill_manager_client.cc
@@ -500,7 +500,7 @@
 }
 
 void FakeShillManagerClient::ClearDevices() {
-  GetListProperty(shill::kDevicesProperty)->Clear();
+  GetListProperty(shill::kDevicesProperty)->ClearList();
   CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
 }
 
@@ -623,7 +623,7 @@
 
 void FakeShillManagerClient::ClearManagerServices() {
   VLOG(1) << "ClearManagerServices";
-  GetListProperty(shill::kServiceCompleteListProperty)->Clear();
+  GetListProperty(shill::kServiceCompleteListProperty)->ClearList();
   CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
 }
 
diff --git a/chromeos/network/network_util_unittest.cc b/chromeos/network/network_util_unittest.cc
index 0d9fb881..c1b89cd 100644
--- a/chromeos/network/network_util_unittest.cc
+++ b/chromeos/network/network_util_unittest.cc
@@ -120,7 +120,7 @@
   EXPECT_FALSE(ParseCellularScanResults(list, &scan_results));
 
   // Scan result has no network id.
-  list.Clear();
+  list.ClearList();
   auto dict_value = std::make_unique<base::DictionaryValue>();
   dict_value->SetString(shill::kStatusProperty, "available");
   list.Append(std::move(dict_value));
diff --git a/chromeos/printing/usb_printer_id.cc b/chromeos/printing/usb_printer_id.cc
index d37346b3..c907cf4 100644
--- a/chromeos/printing/usb_printer_id.cc
+++ b/chromeos/printing/usb_printer_id.cc
@@ -20,7 +20,7 @@
 const char kCommandSet[] = "COMMAND SET";
 const char kCommandSetAbbr[] = "CMD";
 
-UsbPrinterId::UsbPrinterId(const std::vector<uint8_t>& device_id_data) {
+UsbPrinterId::UsbPrinterId(base::span<const uint8_t> device_id_data) {
   // Build mapping.
   id_mappings_ = BuildDeviceIdMapping(device_id_data);
 
@@ -52,7 +52,7 @@
 UsbPrinterId::~UsbPrinterId() = default;
 
 std::map<std::string, std::vector<std::string>> BuildDeviceIdMapping(
-    const std::vector<uint8_t>& data) {
+    base::span<const uint8_t> data) {
   // Must contain at least the length information.
   if (data.size() < 2) {
     return {};
diff --git a/chromeos/printing/usb_printer_id.h b/chromeos/printing/usb_printer_id.h
index edffbc95..28280a0 100644
--- a/chromeos/printing/usb_printer_id.h
+++ b/chromeos/printing/usb_printer_id.h
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/containers/span.h"
 #include "chromeos/chromeos_export.h"
 
 namespace chromeos {
@@ -25,7 +26,7 @@
 
   // Expects |printer_id_data| to contain the data portion response to a USB
   // Printer Class-Specific GET_DEVICE_ID Request.
-  explicit UsbPrinterId(const std::vector<uint8_t>& printer_id_data);
+  explicit UsbPrinterId(base::span<const uint8_t> printer_id_data);
 
   // Accessors.
   const std::string& make() const { return make_; }
@@ -53,7 +54,7 @@
 // Expects data to hold a IEEE 1284 Device ID. Parses |data| and returns the
 // resulting key-value(s) pairs.
 CHROMEOS_EXPORT std::map<std::string, std::vector<std::string>>
-BuildDeviceIdMapping(const std::vector<uint8_t>& data);
+BuildDeviceIdMapping(base::span<const uint8_t> data);
 
 }  // namespace chromeos
 
diff --git a/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc b/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc
index 0618de9..96d3a811 100644
--- a/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc
+++ b/chromeos/services/device_sync/cryptauth_device_manager_impl_unittest.cc
@@ -704,7 +704,7 @@
     InitWithExistingPrefs_MigrateDeprecateBooleansFromPrefsToSoftwareFeature) {
   ListPrefUpdate update_clear(&pref_service_,
                               prefs::kCryptAuthDeviceSyncUnlockKeys);
-  update_clear.Get()->Clear();
+  update_clear.Get()->ClearList();
 
   // Simulate a deprecated device being persisted to prefs.
   auto device_dictionary = std::make_unique<base::DictionaryValue>();
diff --git a/chromeos/ui/frame/caption_buttons/frame_center_button.cc b/chromeos/ui/frame/caption_buttons/frame_center_button.cc
index 3122a7cf..cd9dc31 100644
--- a/chromeos/ui/frame/caption_buttons/frame_center_button.cc
+++ b/chromeos/ui/frame/caption_buttons/frame_center_button.cc
@@ -4,6 +4,7 @@
 
 #include "chromeos/ui/frame/caption_buttons/frame_center_button.h"
 
+#include "base/numerics/safe_conversions.h"
 #include "chromeos/ui/vector_icons/vector_icons.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
@@ -44,8 +45,9 @@
   gfx::Size size = GetPreferredSize();
   // Similar to CalculatePreferredSize(), but allow the text width to be zero.
   size.set_width((sub_icon_image_
-                      ? icon_image().width() / 2 + kMarginBetweenContents +
-                            sub_icon_image_->width() / 2
+                      ? base::ClampCeil(icon_image().width() / 2.0f) +
+                            kMarginBetweenContents +
+                            base::ClampCeil(sub_icon_image_->width() / 2.0f)
                       : 0) +
                  views::kCaptionButtonWidth);
   return size;
@@ -105,9 +107,11 @@
   gfx::Size size = views::View::CalculatePreferredSize();
 
   size.set_width(
-      (text_ || sub_icon_image_ ? icon_image().width() / 2 : 0) +
+      (text_ || sub_icon_image_ ? base::ClampCeil(icon_image().width() / 2.0f)
+                                : 0) +
       (text_ ? kMarginBetweenContents + text_->GetStringSize().width() : 0) +
-      (sub_icon_image_ ? kMarginBetweenContents + sub_icon_image_->width() / 2
+      (sub_icon_image_ ? kMarginBetweenContents +
+                             base::ClampCeil(sub_icon_image_->width() / 2.0f)
                        : 0) +
       views::kCaptionButtonWidth);
   return size;
@@ -136,10 +140,11 @@
   // The width available is basically the same as width(), but we need to
   // adjust the corner radius on both sides from views::kCaptionButtonWidth to
   // the actual content radius.
-  int available_content_width = width() - views::kCaptionButtonWidth +
-                                icon_image().width() / 2 +
-                                (sub_icon_image_ ? sub_icon_image_->width() / 2
-                                                 : icon_image().width() / 2);
+  int available_content_width =
+      width() - views::kCaptionButtonWidth +
+      base::ClampCeil(icon_image().width() / 2.0f) +
+      (sub_icon_image_ ? base::ClampCeil(sub_icon_image_->width() / 2.0f)
+                       : base::ClampCeil(icon_image().width() / 2.0f));
   int content_width = std::min(full_content_width, available_content_width);
   int current_offset = (width() - content_width) / 2;
 
diff --git a/components/arc/compat_mode/arc_resize_lock_manager.cc b/components/arc/compat_mode/arc_resize_lock_manager.cc
index e75bdbd..c8a8ce4 100644
--- a/components/arc/compat_mode/arc_resize_lock_manager.cc
+++ b/components/arc/compat_mode/arc_resize_lock_manager.cc
@@ -298,6 +298,9 @@
       case ash::ArcResizeLockType::RESIZABLE:
         NOTREACHED();
     }
+    // As we updated the resize lock state above, we need to update compat mode
+    // button.
+    UpdateCompatModeButton(window);
     is_first_launch = true;
   }
 
@@ -308,8 +311,6 @@
   // Because we use the compat mode button as the "anchor" in the splash, we
   // need to show it after the setup of the compat mode button.
   if (is_first_launch && ShouldShowSplashScreenDialog(pref_delegate_)) {
-    // Compat-mode button must exist as the anchoring target of the splash.
-    UpdateCompatModeButton(window);
     const bool is_for_unresizable =
         window->GetProperty(ash::kArcResizeLockTypeKey) ==
         ash::ArcResizeLockType::FULLY_LOCKED;
diff --git a/components/arc/mojom/intent_helper.mojom b/components/arc/mojom/intent_helper.mojom
index 241a32d..bab75a7 100644
--- a/components/arc/mojom/intent_helper.mojom
+++ b/components/arc/mojom/intent_helper.mojom
@@ -122,87 +122,52 @@
 };
 
 // Describes a specific page in chrome://, about:blank, about:downloads and about:history.
+// This enum should have only the chrome pages used by ARC.
+// Numerical values should be used for each constant and should not be reused.
 [Extensible]
 enum ChromePage {
-  MULTIDEVICE,
-  MAIN,
-  POWER,
-  BLUETOOTH,
-  DATETIME,
-  DISPLAY,
-  WIFI,
-  LANGUAGES,
-  PRIVACY,
-  HELP,
-  ACCOUNTS,
-  APPEARANCE,
-  AUTOFILL,
-  BLUETOOTHDEVICES,
-  CHANGEPICTURE,
-  CLEARBROWSERDATA,
-  CLOUDPRINTERS,
-  CUPSPRINTERS,
-  DOWNLOADS,
-  KEYBOARDOVERLAY,
-  LOCKSCREEN,
-  MANAGEACCESSIBILITY,
-  NETWORKSTYPEVPN,
-  ONSTARTUP,
-  PASSWORDS,
-  POINTEROVERLAY,
-  RESET,
-  SEARCH,
-  STORAGE,
-  SYNCSETUP,
-  ABOUTBLANK,
-  ABOUTDOWNLOADS,
-  ABOUTHISTORY,
-  DEPRECATED_CROSTINIDISKRESIZE,
-  ACCESSIBILITY,
-  ACCOUNTMANAGER,
-  ANDROIDAPPSDETAILS,
-  ANDROIDAPPSDETAILSINBROWSERSETTINGS,
-  APPMANAGEMENT,
-  APPMANAGEMENTDETAILS,
-  ASSISTANT,
-  CONNECTEDDEVICES,
-  CROSTINISHAREDPATHS,
-  CROSTINISHAREDUSBDEVICES,
-  CROSTINIEXPORTIMPORT,
-  EXTERNALSTORAGE,
-  INTERNET,
-  DEPRECATED_KERBEROSACCOUNTS,
-  KNOWNNETWORKS,
-  MANAGEACCESSIBILITYTTS,
-  SMARTLOCKSETTINGS,
-  SWITCHACCESS,
-  STYLUS,
-  TETHERSETTINGS,
-  ETHERNET,
-  CELLULAR,
-  AMBIENTMODE,
-  DEPRECATED_PLUGINVMDETAILS,
-  PLUGINVMSHAREDPATHS,
-  OSACCESSIBILITY,
-  OSLANGUAGES,
-  DEPRECATED_OSLANGUAGESDETAILS,
-  DEPRECATED_OSLANGUAGESINPUTMETHODS,
-  OSPRINTING,
-  PRINTING,
-  OSPEOPLE,
-  OSPRIVACY,
-  OSSEARCH,
-  OSRESET,
-  OSLANGUAGESSMARTINPUTS,
-  DEPRECATED_DOWNLOADEDCONTENT,
-  OSLANGUAGESINPUT,
-  OSLANGUAGESLANGUAGES,
-  OSLANGUAGESEDITDICTIONARY,
-  KERBEROS,
-  KERBEROSACCOUNTSV2,
-  SEARCHSUBPAGE,
+  MULTIDEVICE = 0,
+  MAIN = 1,
+  POWER = 2,
+  BLUETOOTH = 3,
+  DATETIME = 4,
+  DISPLAY = 5,
+  WIFI = 6,
+  LANGUAGES = 7,
+  // TODO(b/181930573): Remove after P retires. This value is used only by P.
+  PRIVACY = 8,
+  HELP = 9,
+  ACCOUNTS = 10,
+  APPEARANCE = 11,
+  AUTOFILL = 12,
+  BLUETOOTHDEVICES = 13,
+  CHANGEPICTURE = 14,
+  CLEARBROWSERDATA = 15,
+  CLOUDPRINTERS = 16,
+  CUPSPRINTERS = 17,
+  DOWNLOADS = 18,
+  KEYBOARDOVERLAY = 19,
+  LOCKSCREEN = 20,
+  MANAGEACCESSIBILITY = 21,
+  NETWORKSTYPEVPN = 22,
+  ONSTARTUP = 23,
+  PASSWORDS = 24,
+  POINTEROVERLAY = 25,
+  RESET = 26,
+  SEARCH = 27,
+  STORAGE = 28,
+  SYNCSETUP = 29,
+  ABOUTBLANK = 30,
+  ABOUTDOWNLOADS = 31,
+  ABOUTHISTORY = 32,
+  // 33-48 are removed intentionally. Do not reuse them.
+  MANAGEACCESSIBILITYTTS = 49,
+  // 50-70 are removed intentionally. Do not reuse them.
+  OSLANGUAGESINPUT = 71,
+  OSLANGUAGESLANGUAGES = 72,
+  // 73-76 are removed intentionally. Do not reuse them.
 
-  LAST = SEARCHSUBPAGE
+  // Next value to be used is 77.
 };
 
 // Describes an unique chrome app.
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn
index f0b022d..e0fcee1 100644
--- a/components/autofill_assistant/browser/BUILD.gn
+++ b/components/autofill_assistant/browser/BUILD.gn
@@ -260,6 +260,8 @@
     "web/element_store.h",
     "web/js_snippets.cc",
     "web/js_snippets.h",
+    "web/keyboard_input_data.cc",
+    "web/keyboard_input_data.h",
     "web/send_keyboard_input_worker.cc",
     "web/send_keyboard_input_worker.h",
     "web/web_controller.cc",
@@ -444,6 +446,7 @@
     "wait_for_document_operation_unittest.cc",
     "web/element_action_util_unittest.cc",
     "web/element_store_unittest.cc",
+    "web/send_keyboard_input_worker_unittest.cc",
     "website_login_manager_impl_unittest.cc",
   ]
 
diff --git a/components/autofill_assistant/browser/DEPS b/components/autofill_assistant/browser/DEPS
index 9adb618f..4220b59c 100644
--- a/components/autofill_assistant/browser/DEPS
+++ b/components/autofill_assistant/browser/DEPS
@@ -28,5 +28,5 @@
   "+third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h",
   "+third_party/re2",
   "+ui/base/l10n/l10n_util.h",
-  "+ui/events/keycodes/dom",
+  "+ui/events/keycodes",
 ]
diff --git a/components/autofill_assistant/browser/action_value.proto b/components/autofill_assistant/browser/action_value.proto
index d58bd32..d7d4b3c 100644
--- a/components/autofill_assistant/browser/action_value.proto
+++ b/components/autofill_assistant/browser/action_value.proto
@@ -101,8 +101,6 @@
 // A key event, for definition see here:
 // https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchKeyEvent
 message KeyEvent {
-  // Unique key identifier (e.g., 'U+0041').
-  optional string key_identifier = 1;
   // Unique DOM defined string value for each physical key (e.g., 'KeyA').
   optional string code = 2;
   // Text as generated by processing a virtual key code with a keyboard layout.
@@ -114,4 +112,13 @@
   // The list of commands can be found here:
   // https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/commands/editor_command_names.h
   repeated string command = 5;
+  // Legacy keyCode for the KeyEvent:
+  // https://w3c.github.io/uievents/#dom-keyboardevent-keycode
+  // This is populated on a best-effort basis, with some characters mapped
+  // assuming content expects US English layout input, as specified by:
+  // https://w3c.github.io/uievents/#determine-keydown-keyup-keyCode
+  // VKEY_UNKNOWN otherwise.
+  optional int32 key_code = 6;
+
+  reserved 1;
 }
diff --git a/components/autofill_assistant/browser/web/keyboard_input_data.cc b/components/autofill_assistant/browser/web/keyboard_input_data.cc
new file mode 100644
index 0000000..ce72e9c
--- /dev/null
+++ b/components/autofill_assistant/browser/web/keyboard_input_data.cc
@@ -0,0 +1,94 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/web/keyboard_input_data.h"
+
+#include "base/containers/flat_map.h"
+#include "base/no_destructor.h"
+#include "base/strings/string_util.h"
+
+namespace autofill_assistant {
+namespace keyboard_input_data {
+namespace {
+
+// Get KeyboardCode as described in
+// https://w3c.github.io/uievents/#determine-keydown-keyup-keyCode
+ui::KeyboardCode GetKeyboardCodeForASCII(UChar32 codepoint) {
+  // Numerical characters.
+  if (base::IsAsciiDigit(codepoint)) {
+    return static_cast<ui::KeyboardCode>(codepoint);
+  }
+  // Alphabetical characters.
+  if (base::IsAsciiAlpha(codepoint)) {
+    return static_cast<ui::KeyboardCode>(base::ToUpperASCII(codepoint));
+  }
+
+  static const base::NoDestructor<base::flat_map<UChar32, ui::KeyboardCode>>
+      fixed_char_to_vkey(
+          {// https://w3c.github.io/uievents/#fixed-virtual-key-codes
+           {'\b', ui::KeyboardCode::VKEY_BACK},
+           {'\t', ui::KeyboardCode::VKEY_TAB},
+           {'\r', ui::KeyboardCode::VKEY_RETURN},
+           {'\n', ui::KeyboardCode::VKEY_RETURN},
+           {'\e', ui::KeyboardCode::VKEY_ESCAPE},
+           {' ', ui::KeyboardCode::VKEY_SPACE},
+           // https://w3c.github.io/uievents/#optionally-fixed-virtual-key-codes
+           {';', ui::KeyboardCode::VKEY_OEM_1},
+           {':', ui::KeyboardCode::VKEY_OEM_1},
+           {'=', ui::KeyboardCode::VKEY_OEM_PLUS},
+           {'+', ui::KeyboardCode::VKEY_OEM_PLUS},
+           {',', ui::KeyboardCode::VKEY_OEM_COMMA},
+           {'<', ui::KeyboardCode::VKEY_OEM_COMMA},
+           {'-', ui::KeyboardCode::VKEY_OEM_MINUS},
+           {'_', ui::KeyboardCode::VKEY_OEM_MINUS},
+           {'.', ui::KeyboardCode::VKEY_OEM_PERIOD},
+           {'>', ui::KeyboardCode::VKEY_OEM_PERIOD},
+           {'/', ui::KeyboardCode::VKEY_OEM_2},
+           {'?', ui::KeyboardCode::VKEY_OEM_2},
+           {'`', ui::KeyboardCode::VKEY_OEM_3},
+           {'~', ui::KeyboardCode::VKEY_OEM_3},
+           {'[', ui::KeyboardCode::VKEY_OEM_4},
+           {'{', ui::KeyboardCode::VKEY_OEM_4},
+           {'\\', ui::KeyboardCode::VKEY_OEM_5},
+           {'|', ui::KeyboardCode::VKEY_OEM_5},
+           {']', ui::KeyboardCode::VKEY_OEM_6},
+           {'}', ui::KeyboardCode::VKEY_OEM_6},
+           {'\'', ui::KeyboardCode::VKEY_OEM_7},
+           {'"', ui::KeyboardCode::VKEY_OEM_7}});
+
+  auto vkey_it = fixed_char_to_vkey->find(codepoint);
+  if (vkey_it != fixed_char_to_vkey->end()) {
+    return vkey_it->second;
+  }
+
+  return ui::KeyboardCode::VKEY_UNKNOWN;
+}
+
+}  // namespace
+
+DevToolsDispatchKeyEventParams::DevToolsDispatchKeyEventParams() = default;
+DevToolsDispatchKeyEventParams::~DevToolsDispatchKeyEventParams() = default;
+DevToolsDispatchKeyEventParams::DevToolsDispatchKeyEventParams(
+    const DevToolsDispatchKeyEventParams&) = default;
+DevToolsDispatchKeyEventParams& DevToolsDispatchKeyEventParams::operator=(
+    const DevToolsDispatchKeyEventParams&) = default;
+
+DevToolsDispatchKeyEventParams GetDevToolsDispatchKeyEventParamsForCodepoint(
+    UChar32 codepoint) {
+  static const base::NoDestructor<base::flat_map<UChar32, std::string>>
+      char_to_commands({{'\b', "DeleteBackward"}});
+
+  DevToolsDispatchKeyEventParams key_info;
+  key_info.key_code = GetKeyboardCodeForASCII(codepoint);
+
+  auto commands_it = char_to_commands->find(codepoint);
+  if (commands_it != char_to_commands->end()) {
+    key_info.command = commands_it->second;
+  }
+
+  return key_info;
+}
+
+}  // namespace keyboard_input_data
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/web/keyboard_input_data.h b/components/autofill_assistant/browser/web/keyboard_input_data.h
new file mode 100644
index 0000000..d3d6f22
--- /dev/null
+++ b/components/autofill_assistant/browser/web/keyboard_input_data.h
@@ -0,0 +1,43 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_KEYBOARD_INPUT_DATA_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_KEYBOARD_INPUT_DATA_H_
+
+#include <string>
+
+#include "third_party/icu/source/common/unicode/umachine.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+namespace autofill_assistant {
+namespace keyboard_input_data {
+
+struct DevToolsDispatchKeyEventParams {
+  DevToolsDispatchKeyEventParams();
+  ~DevToolsDispatchKeyEventParams();
+  DevToolsDispatchKeyEventParams(const DevToolsDispatchKeyEventParams&);
+  DevToolsDispatchKeyEventParams& operator=(
+      const DevToolsDispatchKeyEventParams&);
+
+  // Legacy keyCode for the KeyEvent as described here:
+  // https://w3c.github.io/uievents/#dom-keyboardevent-keycode
+  ui::KeyboardCode key_code = ui::KeyboardCode::VKEY_UNKNOWN;
+
+  // The list of commands can be found here:
+  // https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/commands/editor_command_names.h
+  std::string command;
+};
+
+// Get "best guess" information on how to synthesize a devtools keyup / keydown
+// event based on the character provided. This approach performs the keycode
+// value evaluation based on the W3C spec here:
+// https://w3c.github.io/uievents/#determine-keydown-keyup-keyCode
+// This is not fit for general usage and works best for US layout.
+DevToolsDispatchKeyEventParams GetDevToolsDispatchKeyEventParamsForCodepoint(
+    UChar32 codepoint);
+
+}  // namespace keyboard_input_data
+}  // namespace autofill_assistant
+
+#endif  // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_WEB_SEND_KEYBOARD_INPUT_WORKER_H_
diff --git a/components/autofill_assistant/browser/web/send_keyboard_input_worker.cc b/components/autofill_assistant/browser/web/send_keyboard_input_worker.cc
index c58f0b65..ce3da76 100644
--- a/components/autofill_assistant/browser/web/send_keyboard_input_worker.cc
+++ b/components/autofill_assistant/browser/web/send_keyboard_input_worker.cc
@@ -6,22 +6,16 @@
 
 #include "base/logging.h"
 #include "components/autofill_assistant/browser/string_conversions_util.h"
+#include "components/autofill_assistant/browser/web/keyboard_input_data.h"
 #include "components/autofill_assistant/browser/web/web_controller_util.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "ui/events/keycodes/dom/dom_key.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
 
 namespace autofill_assistant {
 namespace {
 
-absl::optional<std::vector<std::string>> GetCommandForDomKey(
-    ui::DomKey dom_key) {
-  if (dom_key == ui::DomKey::BACKSPACE) {
-    return std::vector<std::string>({"DeleteBackward"});
-  }
-  return absl::nullopt;
-}
-
 std::unique_ptr<input::DispatchKeyEventParams> CreateKeyEventParamsForKeyEvent(
     input::DispatchKeyEventType type,
     absl::optional<base::Time> timestamp,
@@ -31,9 +25,6 @@
     params->SetTimestamp(timestamp->ToDoubleT());
   }
 
-  if (key_event.has_key_identifier()) {
-    params->SetKeyIdentifier(key_event.key_identifier());
-  }
   if (key_event.has_code()) {
     params->SetCode(key_event.code());
   }
@@ -47,6 +38,11 @@
     params->SetCommands(std::vector<std::string>(key_event.command().begin(),
                                                  key_event.command().end()));
   }
+  if (key_event.has_key_code()) {
+    // Set legacy keyCode for the KeyEvent as described here:
+    // https://w3c.github.io/uievents/#dom-keyboardevent-keycode
+    params->SetWindowsVirtualKeyCode(key_event.key_code());
+  }
 
   return params;
 }
@@ -78,13 +74,6 @@
   auto dom_key = ui::DomKey::FromCharacter(codepoint);
   if (dom_key.IsValid()) {
     key_event.set_key(ui::KeycodeConverter::DomKeyToKeyString(dom_key));
-    auto commands = GetCommandForDomKey(dom_key);
-    if (commands.has_value()) {
-      for (const std::string& command : *commands) {
-        key_event.add_command(command);
-      }
-    }
-
   } else {
 #ifdef NDEBUG
     VLOG(1) << __func__ << ": Failed to set DomKey for codepoint";
@@ -94,6 +83,14 @@
 #endif
   }
 
+  auto key_info =
+      keyboard_input_data::GetDevToolsDispatchKeyEventParamsForCodepoint(
+          codepoint);
+  key_event.set_key_code(static_cast<int32_t>(key_info.key_code));
+  if (!key_info.command.empty()) {
+    key_event.add_command(key_info.command);
+  }
+
   return key_event;
 }
 
diff --git a/components/autofill_assistant/browser/web/send_keyboard_input_worker_unittest.cc b/components/autofill_assistant/browser/web/send_keyboard_input_worker_unittest.cc
new file mode 100644
index 0000000..c98bd28
--- /dev/null
+++ b/components/autofill_assistant/browser/web/send_keyboard_input_worker_unittest.cc
@@ -0,0 +1,136 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/web/send_keyboard_input_worker.h"
+
+#include "components/autofill_assistant/browser/action_value.pb.h"
+#include "components/autofill_assistant/browser/string_conversions_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace autofill_assistant {
+namespace {
+
+using ::testing::ElementsAre;
+
+TEST(SendKeyboardInputWorkerTest, ConvertLowerCaseCharacter) {
+  std::vector<UChar32> characters = UTF8ToUnicode("az");
+
+  KeyEvent key_event_a =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[0]);
+  EXPECT_EQ(key_event_a.text(), "a");
+  EXPECT_EQ(key_event_a.key(), "a");
+  EXPECT_EQ(key_event_a.key_code(), 65);
+
+  KeyEvent key_event_z =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[1]);
+  EXPECT_EQ(key_event_z.text(), "z");
+  EXPECT_EQ(key_event_z.key(), "z");
+  EXPECT_EQ(key_event_z.key_code(), 90);
+}
+
+TEST(SendKeyboardInputWorkerTest, ConvertUpperCaseCharacter) {
+  std::vector<UChar32> characters = UTF8ToUnicode("AZ");
+
+  KeyEvent key_event_a =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[0]);
+  EXPECT_EQ(key_event_a.text(), "A");
+  EXPECT_EQ(key_event_a.key(), "A");
+  EXPECT_EQ(key_event_a.key_code(), 65);
+
+  KeyEvent key_event_z =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[1]);
+  EXPECT_EQ(key_event_z.text(), "Z");
+  EXPECT_EQ(key_event_z.key(), "Z");
+  EXPECT_EQ(key_event_z.key_code(), 90);
+}
+
+TEST(SendKeyboardInputWorkerTest, ConvertNumber) {
+  std::vector<UChar32> characters = UTF8ToUnicode("09");
+
+  KeyEvent key_event_0 =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[0]);
+  EXPECT_EQ(key_event_0.text(), "0");
+  EXPECT_EQ(key_event_0.key(), "0");
+  EXPECT_EQ(key_event_0.key_code(), 48);
+
+  KeyEvent key_event_9 =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[1]);
+  EXPECT_EQ(key_event_9.text(), "9");
+  EXPECT_EQ(key_event_9.key(), "9");
+  EXPECT_EQ(key_event_9.key_code(), 57);
+}
+
+TEST(SendKeyboardInputWorkerTest, ConvertSpace) {
+  std::vector<UChar32> characters = UTF8ToUnicode(" ");
+
+  KeyEvent key_event_space =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[0]);
+  EXPECT_EQ(key_event_space.text(), " ");
+  EXPECT_EQ(key_event_space.key(), " ");
+  EXPECT_EQ(key_event_space.key_code(), 32);
+}
+
+TEST(SendKeyboardInputWorkerTest, ConvertControlKeys) {
+  std::vector<UChar32> characters = UTF8ToUnicode("\b\r");
+
+  KeyEvent key_event_backspace =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[0]);
+  EXPECT_EQ(key_event_backspace.text(), "\b");
+  EXPECT_EQ(key_event_backspace.key(), "Backspace");
+  EXPECT_THAT(key_event_backspace.command(), ElementsAre("DeleteBackward"));
+  EXPECT_EQ(key_event_backspace.key_code(), 8);
+
+  KeyEvent key_event_enter =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[1]);
+  EXPECT_EQ(key_event_enter.text(), "\r");
+  EXPECT_EQ(key_event_enter.key(), "Enter");
+  EXPECT_EQ(key_event_enter.key_code(), 13);
+}
+
+TEST(SendKeyboardInputWorkerTest, ConvertFixedCharacters) {
+  std::vector<UChar32> characters = UTF8ToUnicode(",:");
+
+  KeyEvent key_event_comma =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[0]);
+  EXPECT_EQ(key_event_comma.text(), ",");
+  EXPECT_EQ(key_event_comma.key(), ",");
+  EXPECT_EQ(key_event_comma.key_code(), 188);
+
+  KeyEvent key_event_colon =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[1]);
+  EXPECT_EQ(key_event_colon.text(), ":");
+  EXPECT_EQ(key_event_colon.key(), ":");
+  EXPECT_EQ(key_event_colon.key_code(), 186);
+}
+
+TEST(SendKeyboardInputWorkerTest, ConvertMultiByteCharachters) {
+  std::vector<UChar32> characters = UTF8ToUnicode("Aü万𠜎");
+
+  KeyEvent event_0 =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[0]);
+  EXPECT_EQ(event_0.text(), "A");
+  EXPECT_EQ(event_0.key(), "A");
+  EXPECT_EQ(event_0.key_code(), 65);
+
+  KeyEvent event_1 =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[1]);
+  EXPECT_EQ(event_1.text(), "ü");
+  EXPECT_EQ(event_1.key(), "ü");
+  EXPECT_EQ(event_1.key_code(), 0);
+
+  KeyEvent event_2 =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[2]);
+  EXPECT_EQ(event_2.text(), "万");
+  EXPECT_EQ(event_2.key(), "万");
+  EXPECT_EQ(event_2.key_code(), 0);
+
+  KeyEvent event_3 =
+      SendKeyboardInputWorker::KeyEventFromCodepoint(characters[3]);
+  EXPECT_EQ(event_3.text(), "𠜎");
+  EXPECT_EQ(event_3.key(), "𠜎");
+  EXPECT_EQ(event_3.key_code(), 0);
+}
+
+}  // namespace
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/web/web_controller_browsertest.cc b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
index bdcaf7c9..81b5cd4 100644
--- a/components/autofill_assistant/browser/web/web_controller_browsertest.cc
+++ b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
@@ -2782,4 +2782,73 @@
       20.0, 0.5);
 }
 
+IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, KeyMappings) {
+  EXPECT_TRUE(ExecJs(shell(), R"(
+    document.getElementById('input1').addEventListener('keydown', (e) => {
+      lastKeydownEvent = `${e.key} ${e.keyCode} ${e.which}`;
+    });
+    document.getElementById('input1').addEventListener('keypress', (e) => {
+      lastKeypressEvent = `${e.key} ${e.keyCode} ${e.which}`;
+    });
+    document.getElementById('input1').addEventListener('keyup', (e) => {
+      lastKeyupEvent = `${e.key} ${e.keyCode} ${e.which}`;
+    });
+  )"));
+
+  Selector selector({"#input1"});
+
+  EXPECT_EQ(SendKeyboardInput(selector, UTF8ToUnicode("a")).proto_status(),
+            ACTION_APPLIED);
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeydownEvent").ExtractString(),
+            "a 65 65");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeypressEvent").ExtractString(),
+            "a 97 97");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeyupEvent").ExtractString(),
+            "a 65 65");
+
+  EXPECT_EQ(SendKeyboardInput(selector, UTF8ToUnicode("A")).proto_status(),
+            ACTION_APPLIED);
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeydownEvent").ExtractString(),
+            "A 65 65");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeypressEvent").ExtractString(),
+            "A 65 65");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeyupEvent").ExtractString(),
+            "A 65 65");
+
+  EXPECT_EQ(SendKeyboardInput(selector, UTF8ToUnicode("\b")).proto_status(),
+            ACTION_APPLIED);
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeydownEvent").ExtractString(),
+            "Backspace 8 8");
+  // No keypress for backspace.
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeyupEvent").ExtractString(),
+            "Backspace 8 8");
+
+  EXPECT_EQ(SendKeyboardInput(selector, UTF8ToUnicode("\r")).proto_status(),
+            ACTION_APPLIED);
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeydownEvent").ExtractString(),
+            "Enter 13 13");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeypressEvent").ExtractString(),
+            "Enter 13 13");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeyupEvent").ExtractString(),
+            "Enter 13 13");
+
+  EXPECT_EQ(SendKeyboardInput(selector, UTF8ToUnicode(",")).proto_status(),
+            ACTION_APPLIED);
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeydownEvent").ExtractString(),
+            ", 188 188");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeypressEvent").ExtractString(),
+            ", 44 44");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeyupEvent").ExtractString(),
+            ", 188 188");
+
+  EXPECT_EQ(SendKeyboardInput(selector, UTF8ToUnicode("<")).proto_status(),
+            ACTION_APPLIED);
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeydownEvent").ExtractString(),
+            "< 188 188");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeypressEvent").ExtractString(),
+            "< 60 60");
+  EXPECT_EQ(content::EvalJs(shell(), "lastKeyupEvent").ExtractString(),
+            "< 188 188");
+}
+
 }  // namespace autofill_assistant
diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc
index 4d3da8f1..ea4af4a 100644
--- a/components/bookmarks/browser/bookmark_codec.cc
+++ b/components/bookmarks/browser/bookmark_codec.cc
@@ -17,6 +17,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/strings/grit/components_strings.h"
@@ -58,15 +59,14 @@
 
 BookmarkCodec::~BookmarkCodec() = default;
 
-std::unique_ptr<base::Value> BookmarkCodec::Encode(
-    BookmarkModel* model,
-    const std::string& sync_metadata_str) {
+base::Value BookmarkCodec::Encode(BookmarkModel* model,
+                                  const std::string& sync_metadata_str) {
   return Encode(model->bookmark_bar_node(), model->other_node(),
                 model->mobile_node(), model->root_node()->GetMetaInfoMap(),
                 sync_metadata_str);
 }
 
-std::unique_ptr<base::Value> BookmarkCodec::Encode(
+base::Value BookmarkCodec::Encode(
     const BookmarkNode* bookmark_bar_node,
     const BookmarkNode* other_folder_node,
     const BookmarkNode* mobile_folder_node,
@@ -75,27 +75,27 @@
   ids_reassigned_ = false;
   guids_reassigned_ = false;
   InitializeChecksum();
-  auto roots = std::make_unique<base::DictionaryValue>();
-  roots->Set(kRootFolderNameKey, EncodeNode(bookmark_bar_node));
-  roots->Set(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node));
-  roots->Set(kMobileBookmarkFolderNameKey, EncodeNode(mobile_folder_node));
+  base::Value roots(base::Value::Type::DICTIONARY);
+  roots.SetKey(kRootFolderNameKey, EncodeNode(bookmark_bar_node));
+  roots.SetKey(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node));
+  roots.SetKey(kMobileBookmarkFolderNameKey, EncodeNode(mobile_folder_node));
   if (model_meta_info_map)
-    roots->Set(kMetaInfo, EncodeMetaInfo(*model_meta_info_map));
-  auto main = std::make_unique<base::DictionaryValue>();
-  main->SetInteger(kVersionKey, kCurrentVersion);
+    roots.SetKey(kMetaInfo, EncodeMetaInfo(*model_meta_info_map));
+  base::Value main(base::Value::Type::DICTIONARY);
+  main.SetIntKey(kVersionKey, kCurrentVersion);
   FinalizeChecksum();
   // We are going to store the computed checksum. So set stored checksum to be
   // the same as computed checksum.
   stored_checksum_ = computed_checksum_;
-  main->SetString(kChecksumKey, computed_checksum_);
-  main->Set(kRootsKey, std::move(roots));
+  main.SetStringKey(kChecksumKey, computed_checksum_);
+  main.SetKey(kRootsKey, std::move(roots));
   if (!sync_metadata_str.empty()) {
     std::string sync_metadata_str_base64;
     base::Base64Encode(sync_metadata_str, &sync_metadata_str_base64);
-    main->SetKey(kSyncMetadata,
-                 base::Value(std::move(sync_metadata_str_base64)));
+    main.SetKey(kSyncMetadata,
+                base::Value(std::move(sync_metadata_str_base64)));
   }
-  return std::move(main);
+  return main;
 }
 
 bool BookmarkCodec::Decode(const base::Value& value,
@@ -127,47 +127,46 @@
   return success;
 }
 
-std::unique_ptr<base::Value> BookmarkCodec::EncodeNode(
-    const BookmarkNode* node) {
-  std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
+base::Value BookmarkCodec::EncodeNode(const BookmarkNode* node) {
+  base::Value value(base::Value::Type::DICTIONARY);
   std::string id = base::NumberToString(node->id());
-  value->SetString(kIdKey, id);
+  value.SetStringKey(kIdKey, id);
   const std::u16string& title = node->GetTitle();
-  value->SetString(kNameKey, title);
+  value.SetStringKey(kNameKey, title);
   const std::string& guid = node->guid().AsLowercaseString();
-  value->SetString(kGuidKey, guid);
-  value->SetString(kDateAddedKey,
-                   base::NumberToString(node->date_added().ToInternalValue()));
+  value.SetStringKey(kGuidKey, guid);
+  // TODO(crbug.com/634507): Avoid ToInternalValue().
+  value.SetStringKey(kDateAddedKey, base::NumberToString(
+                                        node->date_added().ToInternalValue()));
   if (node->is_url()) {
-    value->SetString(kTypeKey, kTypeURL);
+    value.SetStringKey(kTypeKey, kTypeURL);
     std::string url = node->url().possibly_invalid_spec();
-    value->SetString(kURLKey, url);
+    value.SetStringKey(kURLKey, url);
     UpdateChecksumWithUrlNode(id, title, url);
   } else {
-    value->SetString(kTypeKey, kTypeFolder);
-    value->SetString(
+    value.SetStringKey(kTypeKey, kTypeFolder);
+    value.SetStringKey(
         kDateModifiedKey,
         base::NumberToString(node->date_folder_modified().ToInternalValue()));
     UpdateChecksumWithFolderNode(id, title);
 
-    auto child_values = std::make_unique<base::ListValue>();
+    base::Value child_values(base::Value::Type::LIST);
     for (const auto& child : node->children())
-      child_values->Append(EncodeNode(child.get()));
-    value->Set(kChildrenKey, std::move(child_values));
+      child_values.Append(EncodeNode(child.get()));
+    value.SetKey(kChildrenKey, std::move(child_values));
   }
   const BookmarkNode::MetaInfoMap* meta_info_map = node->GetMetaInfoMap();
   if (meta_info_map)
-    value->Set(kMetaInfo, EncodeMetaInfo(*meta_info_map));
-  return std::move(value);
+    value.SetKey(kMetaInfo, EncodeMetaInfo(*meta_info_map));
+  return value;
 }
 
-std::unique_ptr<base::Value> BookmarkCodec::EncodeMetaInfo(
+base::Value BookmarkCodec::EncodeMetaInfo(
     const BookmarkNode::MetaInfoMap& meta_info_map) {
-  auto meta_info = std::make_unique<base::DictionaryValue>();
-  for (const auto& item : meta_info_map) {
-    meta_info->SetKey(item.first, base::Value(item.second));
-  }
-  return std::move(meta_info);
+  base::Value meta_info(base::Value::Type::DICTIONARY);
+  for (const auto& item : meta_info_map)
+    meta_info.SetKey(item.first, base::Value(item.second));
+  return meta_info;
 }
 
 bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node,
@@ -175,51 +174,42 @@
                                  BookmarkNode* mobile_folder_node,
                                  const base::Value& value,
                                  std::string* sync_metadata_str) {
-  const base::DictionaryValue* d_value = nullptr;
-  if (!value.GetAsDictionary(&d_value))
+  if (!value.is_dict())
     return false;  // Unexpected type.
 
-  int version;
-  if (!d_value->GetInteger(kVersionKey, &version) || version != kCurrentVersion)
+  absl::optional<int> version = value.FindIntKey(kVersionKey);
+  if (!version || *version != kCurrentVersion)
     return false;  // Unknown version.
 
-  const base::Value* checksum_value;
-  if (d_value->Get(kChecksumKey, &checksum_value)) {
-    if (!checksum_value->is_string())
-      return false;
-    if (!checksum_value->GetAsString(&stored_checksum_))
+  const base::Value* checksum_value = value.FindKey(kChecksumKey);
+  if (checksum_value) {
+    const std::string* checksum = checksum_value->GetIfString();
+    if (checksum)
+      stored_checksum_ = *checksum;
+    else
       return false;
   }
 
-  const base::Value* roots;
-  if (!d_value->Get(kRootsKey, &roots))
-    return false;  // No roots.
-
-  const base::DictionaryValue* roots_d_value = nullptr;
-  if (!roots->GetAsDictionary(&roots_d_value))
-    return false;  // Invalid type for roots.
-  const base::Value* root_folder_value;
-  const base::Value* other_folder_value = nullptr;
-  const base::DictionaryValue* root_folder_d_value = nullptr;
-  const base::DictionaryValue* other_folder_d_value = nullptr;
-  if (!roots_d_value->Get(kRootFolderNameKey, &root_folder_value) ||
-      !root_folder_value->GetAsDictionary(&root_folder_d_value) ||
-      !roots_d_value->Get(kOtherBookmarkFolderNameKey, &other_folder_value) ||
-      !other_folder_value->GetAsDictionary(&other_folder_d_value)) {
+  const base::Value* roots = value.FindDictKey(kRootsKey);
+  if (!roots)
+    return false;  // No roots, or invalid type for roots.
+  const base::Value* root_folder_value = roots->FindDictKey(kRootFolderNameKey);
+  const base::Value* other_folder_value =
+      roots->FindDictKey(kOtherBookmarkFolderNameKey);
+  if (!root_folder_value || !other_folder_value) {
     return false;  // Invalid type for root folder and/or other
                    // folder.
   }
-  DecodeNode(*root_folder_d_value, nullptr, bb_node);
-  DecodeNode(*other_folder_d_value, nullptr, other_folder_node);
+  DecodeNode(*root_folder_value, nullptr, bb_node);
+  DecodeNode(*other_folder_value, nullptr, other_folder_node);
 
   // Fail silently if we can't deserialize mobile bookmarks. We can't require
   // them to exist in order to be backwards-compatible with older versions of
   // chrome.
-  const base::Value* mobile_folder_value;
-  const base::DictionaryValue* mobile_folder_d_value = nullptr;
-  if (roots_d_value->Get(kMobileBookmarkFolderNameKey, &mobile_folder_value) &&
-      mobile_folder_value->GetAsDictionary(&mobile_folder_d_value)) {
-    DecodeNode(*mobile_folder_d_value, nullptr, mobile_folder_node);
+  const base::Value* mobile_folder_value =
+      roots->FindDictKey(kMobileBookmarkFolderNameKey);
+  if (mobile_folder_value) {
+    DecodeNode(*mobile_folder_value, nullptr, mobile_folder_node);
   } else {
     // If we didn't find the mobile folder, we're almost guaranteed to have a
     // duplicate id when we add the mobile folder. Consequently, if we don't
@@ -230,13 +220,14 @@
       ReassignIDsHelper(mobile_folder_node);
   }
 
-  if (!DecodeMetaInfo(*roots_d_value, &model_meta_info_map_))
+  if (!DecodeMetaInfo(*roots, &model_meta_info_map_))
     return false;
 
-  std::string sync_metadata_str_base64;
-  if (sync_metadata_str &&
-      d_value->GetString(kSyncMetadata, &sync_metadata_str_base64)) {
-    base::Base64Decode(sync_metadata_str_base64, sync_metadata_str);
+  if (sync_metadata_str) {
+    const std::string* sync_metadata_str_base64 =
+        value.FindStringKey(kSyncMetadata);
+    if (sync_metadata_str_base64)
+      base::Base64Decode(*sync_metadata_str_base64, sync_metadata_str);
   }
 
   // Need to reset the title as the title is persisted and restored from
@@ -250,24 +241,21 @@
   return true;
 }
 
-bool BookmarkCodec::DecodeChildren(const base::ListValue& child_value_list,
+bool BookmarkCodec::DecodeChildren(const base::Value& child_value_list,
                                    BookmarkNode* parent) {
-  for (size_t i = 0; i < child_value_list.GetSize(); ++i) {
-    const base::Value* child_value;
-    if (!child_value_list.Get(i, &child_value))
+  DCHECK(child_value_list.is_list());
+  for (const base::Value& child_value : child_value_list.GetList()) {
+    if (!child_value.is_dict())
       return false;
-
-    const base::DictionaryValue* child_d_value = nullptr;
-    if (!child_value->GetAsDictionary(&child_d_value))
-      return false;
-    DecodeNode(*child_d_value, parent, nullptr);
+    DecodeNode(child_value, parent, nullptr);
   }
   return true;
 }
 
-bool BookmarkCodec::DecodeNode(const base::DictionaryValue& value,
+bool BookmarkCodec::DecodeNode(const base::Value& value,
                                BookmarkNode* parent,
                                BookmarkNode* node) {
+  DCHECK(value.is_dict());
   // If no |node| is specified, we'll create one and add it to the |parent|.
   // Therefore, in that case, |parent| must be non-NULL.
   if (!node && !parent) {
@@ -284,19 +272,20 @@
   std::string id_string;
   int64_t id = 0;
   if (ids_valid_) {
-    if (!value.GetString(kIdKey, &id_string) ||
-        !base::StringToInt64(id_string, &id) ||
-        ids_.count(id) != 0) {
+    const std::string* string = value.FindStringKey(kIdKey);
+    if (!string || !base::StringToInt64(*string, &id) || ids_.count(id) != 0)
       ids_valid_ = false;
-    } else {
+    else
       ids_.insert(id);
-    }
+    id_string = *string;
   }
 
   maximum_id_ = std::max(maximum_id_, id);
 
   std::u16string title;
-  value.GetString(kNameKey, &title);
+  const std::string* string_value = value.FindStringKey(kNameKey);
+  if (string_value)
+    title = base::UTF8ToUTF16(*string_value);
 
   base::GUID guid;
   // |node| is only passed in for bookmarks of type BookmarkPermanentNode, in
@@ -327,24 +316,27 @@
   }
 
   std::string date_added_string;
-  if (!value.GetString(kDateAddedKey, &date_added_string))
+  string_value = value.FindStringKey(kDateAddedKey);
+  if (string_value)
+    date_added_string = *string_value;
+  else
     date_added_string = base::NumberToString(Time::Now().ToInternalValue());
   int64_t internal_time;
   base::StringToInt64(date_added_string, &internal_time);
 
-  std::string type_string;
-  if (!value.GetString(kTypeKey, &type_string))
+  const std::string* type_string = value.FindStringKey(kTypeKey);
+  if (!type_string)
     return false;
 
-  if (type_string != kTypeURL && type_string != kTypeFolder)
+  if (*type_string != kTypeURL && *type_string != kTypeFolder)
     return false;  // Unknown type.
 
-  if (type_string == kTypeURL) {
-    std::string url_string;
-    if (!value.GetString(kURLKey, &url_string))
+  if (*type_string == kTypeURL) {
+    const std::string* url_string = value.FindStringKey(kURLKey);
+    if (!url_string)
       return false;
 
-    GURL url = GURL(url_string);
+    GURL url = GURL(*url_string);
     if (!node && url.is_valid()) {
       DCHECK(guid.is_valid());
       node = new BookmarkNode(id, guid, url);
@@ -354,17 +346,17 @@
 
     if (parent)
       parent->Add(base::WrapUnique(node));
-    UpdateChecksumWithUrlNode(id_string, title, url_string);
+    UpdateChecksumWithUrlNode(id_string, title, *url_string);
   } else {
     std::string last_modified_date;
-    if (!value.GetString(kDateModifiedKey, &last_modified_date))
+    string_value = value.FindStringKey(kDateModifiedKey);
+    if (string_value)
+      last_modified_date = *string_value;
+    else
       last_modified_date = base::NumberToString(Time::Now().ToInternalValue());
 
-    const base::Value* child_values;
-    if (!value.Get(kChildrenKey, &child_values))
-      return false;
-
-    if (child_values->type() != base::Value::Type::LIST)
+    const base::Value* child_values = value.FindListKey(kChildrenKey);
+    if (!child_values)
       return false;
 
     if (!node) {
@@ -384,10 +376,7 @@
 
     UpdateChecksumWithFolderNode(id_string, title);
 
-    const base::ListValue* child_l_values = nullptr;
-    if (!child_values->GetAsList(&child_l_values))
-      return false;
-    if (!DecodeChildren(*child_l_values, node))
+    if (!DecodeChildren(*child_values, node))
       return false;
   }
 
@@ -402,23 +391,23 @@
   return true;
 }
 
-bool BookmarkCodec::DecodeMetaInfo(const base::DictionaryValue& value,
+bool BookmarkCodec::DecodeMetaInfo(const base::Value& value,
                                    BookmarkNode::MetaInfoMap* meta_info_map) {
+  DCHECK(value.is_dict());
   DCHECK(meta_info_map);
   meta_info_map->clear();
 
-  const base::Value* meta_info;
-  if (!value.Get(kMetaInfo, &meta_info))
+  const base::Value* meta_info = value.FindKey(kMetaInfo);
+  if (!meta_info)
     return true;
 
   std::unique_ptr<base::Value> deserialized_holder;
 
   // Meta info used to be stored as a serialized dictionary, so attempt to
   // parse the value as one.
-  if (meta_info->is_string()) {
-    std::string meta_info_str;
-    meta_info->GetAsString(&meta_info_str);
-    JSONStringValueDeserializer deserializer(meta_info_str);
+  const std::string* meta_info_str = meta_info->GetIfString();
+  if (meta_info_str) {
+    JSONStringValueDeserializer deserializer(*meta_info_str);
     deserialized_holder = deserializer.Deserialize(nullptr, nullptr);
     if (!deserialized_holder)
       return false;
@@ -427,30 +416,30 @@
   // meta_info is now either the kMetaInfo node, or the deserialized node if it
   // was stored as a string. Either way it should now be a (possibly nested)
   // dictionary of meta info values.
-  const base::DictionaryValue* meta_info_dict;
-  if (!meta_info->GetAsDictionary(&meta_info_dict))
+  if (!meta_info->is_dict())
     return false;
-  DecodeMetaInfoHelper(*meta_info_dict, std::string(), meta_info_map);
+  DecodeMetaInfoHelper(*meta_info, std::string(), meta_info_map);
 
   return true;
 }
 
 void BookmarkCodec::DecodeMetaInfoHelper(
-    const base::DictionaryValue& dict,
+    const base::Value& dict,
     const std::string& prefix,
     BookmarkNode::MetaInfoMap* meta_info_map) {
-  for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
+  DCHECK(dict.is_dict());
+  for (const auto it : dict.DictItems()) {
     // Deprecated keys should be excluded after removing enhanced bookmarks
     // feature crrev.com/1638413003.
-    if (base::StartsWith(it.key(), "stars.", base::CompareCase::SENSITIVE))
+    if (base::StartsWith(it.first, "stars.", base::CompareCase::SENSITIVE))
       continue;
 
-    if (it.value().is_dict()) {
-      const base::DictionaryValue* subdict;
-      it.value().GetAsDictionary(&subdict);
-      DecodeMetaInfoHelper(*subdict, prefix + it.key() + ".", meta_info_map);
-    } else if (it.value().is_string()) {
-      it.value().GetAsString(&(*meta_info_map)[prefix + it.key()]);
+    if (it.second.is_dict()) {
+      DecodeMetaInfoHelper(it.second, prefix + it.first + ".", meta_info_map);
+    } else {
+      const std::string* str = it.second.GetIfString();
+      if (str)
+        (*meta_info_map)[prefix + it.first] = *str;
     }
   }
 }
diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmarks/browser/bookmark_codec.h
index 1a78c01a..3932ebd 100644
--- a/components/bookmarks/browser/bookmark_codec.h
+++ b/components/bookmarks/browser/bookmark_codec.h
@@ -17,8 +17,6 @@
 #include "components/bookmarks/browser/bookmark_node.h"
 
 namespace base {
-class DictionaryValue;
-class ListValue;
 class Value;
 }
 
@@ -38,20 +36,18 @@
   BookmarkCodec();
   ~BookmarkCodec();
 
-  // Encodes the model to a JSON value. It's up to the caller to delete the
-  // returned object. This is invoked to encode the contents of the bookmark bar
-  // model and is currently a convenience to invoking Encode that takes the
-  // bookmark bar node and other folder node.
-  std::unique_ptr<base::Value> Encode(BookmarkModel* model,
-                                      const std::string& sync_metadata_str);
+  // Encodes the model to a JSON value. This is invoked to encode the contents
+  // of the bookmark bar model and is currently a convenience to invoking Encode
+  // that takes the bookmark bar node and other folder node.
+  base::Value Encode(BookmarkModel* model,
+                     const std::string& sync_metadata_str);
 
   // Encodes the bookmark bar and other folders returning the JSON value.
-  std::unique_ptr<base::Value> Encode(
-      const BookmarkNode* bookmark_bar_node,
-      const BookmarkNode* other_folder_node,
-      const BookmarkNode* mobile_folder_node,
-      const BookmarkNode::MetaInfoMap* model_meta_info_map,
-      const std::string& sync_metadata_str);
+  base::Value Encode(const BookmarkNode* bookmark_bar_node,
+                     const BookmarkNode* other_folder_node,
+                     const BookmarkNode* mobile_folder_node,
+                     const BookmarkNode::MetaInfoMap* model_meta_info_map,
+                     const std::string& sync_metadata_str);
 
   // Decodes the previously encoded value to the specified nodes as well as
   // setting |max_node_id| to the greatest node id. Returns true on success,
@@ -114,11 +110,10 @@
 
  private:
   // Encodes node and all its children into a Value object and returns it.
-  std::unique_ptr<base::Value> EncodeNode(const BookmarkNode* node);
+  base::Value EncodeNode(const BookmarkNode* node);
 
   // Encodes the given meta info into a Value object and returns it.
-  std::unique_ptr<base::Value> EncodeMetaInfo(
-      const BookmarkNode::MetaInfoMap& meta_info_map);
+  base::Value EncodeMetaInfo(const BookmarkNode::MetaInfoMap& meta_info_map);
 
   // Helper to perform decoding.
   bool DecodeHelper(BookmarkNode* bb_node,
@@ -127,8 +122,9 @@
                     const base::Value& value,
                     std::string* sync_metadata_str);
 
-  // Decodes the children of the specified node. Returns true on success.
-  bool DecodeChildren(const base::ListValue& child_value_list,
+  // Decodes the children of the specified node. |child_value_list| needs to be
+  // a list value. Returns true on success.
+  bool DecodeChildren(const base::Value& child_value_list,
                       BookmarkNode* parent);
 
   // Reassigns bookmark IDs for all nodes.
@@ -139,23 +135,23 @@
   // Helper to recursively reassign IDs.
   void ReassignIDsHelper(BookmarkNode* node);
 
-  // Decodes the supplied node from the supplied value. Child nodes are
-  // created appropriately by way of DecodeChildren. If node is NULL a new
-  // node is created and added to parent (parent must then be non-NULL),
-  // otherwise node is used.
-  bool DecodeNode(const base::DictionaryValue& value,
+  // Decodes the supplied node from the supplied value, which needs to be a
+  // dictionary value. Child nodes are created appropriately by way of
+  // DecodeChildren. If node is NULL a new node is created and added to parent
+  // (parent must then be non-NULL), otherwise node is used.
+  bool DecodeNode(const base::Value& value,
                   BookmarkNode* parent,
                   BookmarkNode* node);
 
   // Decodes the meta info from the supplied value. meta_info_map must not be
   // nullptr.
-  bool DecodeMetaInfo(const base::DictionaryValue& value,
+  bool DecodeMetaInfo(const base::Value& value,
                       BookmarkNode::MetaInfoMap* meta_info_map);
 
   // Decodes the meta info from the supplied sub-node dictionary. The values
   // found will be inserted in meta_info_map with the given prefix added to the
   // start of their keys.
-  void DecodeMetaInfoHelper(const base::DictionaryValue& dict,
+  void DecodeMetaInfoHelper(const base::Value& dict,
                             const std::string& prefix,
                             BookmarkNode::MetaInfoMap* meta_info_map);
 
diff --git a/components/bookmarks/browser/bookmark_codec_unittest.cc b/components/bookmarks/browser/bookmark_codec_unittest.cc
index f2dd8cef..958ce96 100644
--- a/components/bookmarks/browser/bookmark_codec_unittest.cc
+++ b/components/bookmarks/browser/bookmark_codec_unittest.cc
@@ -141,17 +141,15 @@
     *result_value = &child_value;
   }
 
-  std::unique_ptr<base::Value> EncodeHelper(
-      BookmarkModel* model,
-      const std::string& sync_metadata_str,
-      std::string* checksum) {
+  base::Value EncodeHelper(BookmarkModel* model,
+                           const std::string& sync_metadata_str,
+                           std::string* checksum) {
     BookmarkCodec encoder;
     // Computed and stored checksums should be empty.
     EXPECT_EQ("", encoder.computed_checksum());
     EXPECT_EQ("", encoder.stored_checksum());
 
-    std::unique_ptr<base::Value> value(
-        encoder.Encode(model, sync_metadata_str));
+    base::Value value(encoder.Encode(model, sync_metadata_str));
     const std::string& computed_checksum = encoder.computed_checksum();
     const std::string& stored_checksum = encoder.stored_checksum();
 
@@ -234,15 +232,13 @@
 TEST_F(BookmarkCodecTest, ChecksumEncodeDecodeTest) {
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
   std::string enc_checksum;
-  std::unique_ptr<base::Value> value =
+  base::Value value =
       EncodeHelper(model_to_encode.get(), /*sync_metadata_str=*/std::string(),
                    &enc_checksum);
 
-  EXPECT_TRUE(value.get() != nullptr);
-
   std::string dec_checksum;
   std::unique_ptr<BookmarkModel> decoded_model =
-      DecodeHelper(*value.get(), enc_checksum, &dec_checksum, false,
+      DecodeHelper(value, enc_checksum, &dec_checksum, false,
                    /*sync_metadata_str=*/nullptr);
 }
 
@@ -251,15 +247,13 @@
   // as the data is the same.
   std::unique_ptr<BookmarkModel> model1(CreateTestModel1());
   std::string enc_checksum1;
-  std::unique_ptr<base::Value> value1 = EncodeHelper(
-      model1.get(), /*sync_metadata_str=*/std::string(), &enc_checksum1);
-  EXPECT_TRUE(value1.get() != nullptr);
+  EncodeHelper(model1.get(), /*sync_metadata_str=*/std::string(),
+               &enc_checksum1);
 
   std::unique_ptr<BookmarkModel> model2(CreateTestModel1());
   std::string enc_checksum2;
-  std::unique_ptr<base::Value> value2 = EncodeHelper(
-      model2.get(), /*sync_metadata_str=*/std::string(), &enc_checksum2);
-  EXPECT_TRUE(value2.get() != nullptr);
+  EncodeHelper(model2.get(), /*sync_metadata_str=*/std::string(),
+               &enc_checksum2);
 
   ASSERT_EQ(enc_checksum1, enc_checksum2);
 }
@@ -267,15 +261,13 @@
 TEST_F(BookmarkCodecTest, ChecksumManualEditTest) {
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
   std::string enc_checksum;
-  std::unique_ptr<base::Value> value =
+  base::Value value =
       EncodeHelper(model_to_encode.get(), /*sync_metadata_str=*/std::string(),
                    &enc_checksum);
 
-  EXPECT_TRUE(value.get() != nullptr);
-
   // Change something in the encoded value before decoding it.
   base::Value* child1_value = nullptr;
-  GetBookmarksBarChildValue(value.get(), 0, &child1_value);
+  GetBookmarksBarChildValue(&value, 0, &child1_value);
   std::string* title = child1_value->FindStringKey(BookmarkCodec::kNameKey);
   ASSERT_TRUE(title);
   std::string original_title = *title;
@@ -283,13 +275,13 @@
 
   std::string dec_checksum;
   std::unique_ptr<BookmarkModel> decoded_model1 =
-      DecodeHelper(*value.get(), enc_checksum, &dec_checksum, true,
+      DecodeHelper(value, enc_checksum, &dec_checksum, true,
                    /*sync_metadata_str=*/nullptr);
 
   // Undo the change and make sure the checksum is same as original.
   child1_value->SetStringKey(BookmarkCodec::kNameKey, original_title);
   std::unique_ptr<BookmarkModel> decoded_model2 =
-      DecodeHelper(*value.get(), enc_checksum, &dec_checksum, false,
+      DecodeHelper(value, enc_checksum, &dec_checksum, false,
                    /*sync_metadata_str=*/nullptr);
 }
 
@@ -303,16 +295,14 @@
   ASSERT_GT(bb_child_count, 1u);
 
   std::string enc_checksum;
-  std::unique_ptr<base::Value> value =
+  base::Value value =
       EncodeHelper(model_to_encode.get(), /*sync_metadata_str=*/std::string(),
                    &enc_checksum);
 
-  EXPECT_TRUE(value.get() != nullptr);
-
   // Change IDs for all children of bookmark bar to be 1.
   base::Value* child_value = nullptr;
   for (size_t i = 0; i < bb_child_count; ++i) {
-    GetBookmarksBarChildValue(value.get(), i, &child_value);
+    GetBookmarksBarChildValue(&value, i, &child_value);
     std::string* id = child_value->FindStringKey(BookmarkCodec::kIdKey);
     ASSERT_TRUE(id);
     child_value->SetStringKey(BookmarkCodec::kIdKey, "1");
@@ -320,7 +310,7 @@
 
   std::string dec_checksum;
   std::unique_ptr<BookmarkModel> decoded_model =
-      DecodeHelper(*value.get(), enc_checksum, &dec_checksum, true,
+      DecodeHelper(value, enc_checksum, &dec_checksum, true,
                    /*sync_metadata_str=*/nullptr);
 
   ExpectIDsUnique(decoded_model.get());
@@ -336,13 +326,12 @@
 TEST_F(BookmarkCodecTest, PersistIDsTest) {
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel3());
   BookmarkCodec encoder;
-  std::unique_ptr<base::Value> model_value(
-      encoder.Encode(model_to_encode.get(), std::string()));
+  base::Value model_value(encoder.Encode(model_to_encode.get(), std::string()));
 
   std::unique_ptr<BookmarkModel> decoded_model(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder;
-  ASSERT_TRUE(Decode(&decoder, *model_value.get(), decoded_model.get(),
+  ASSERT_TRUE(Decode(&decoder, model_value, decoded_model.get(),
                      /*sync_metadata_str=*/nullptr));
   ASSERT_NO_FATAL_FAILURE(
       AssertModelsEqual(model_to_encode.get(), decoded_model.get()));
@@ -357,13 +346,12 @@
   decoded_model->AddURL(folder2_node, 0, kUrl4Title, GURL(kUrl4Url));
 
   BookmarkCodec encoder2;
-  std::unique_ptr<base::Value> model_value2(
-      encoder2.Encode(decoded_model.get(), std::string()));
+  base::Value model_value2(encoder2.Encode(decoded_model.get(), std::string()));
 
   std::unique_ptr<BookmarkModel> decoded_model2(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder2;
-  ASSERT_TRUE(Decode(&decoder2, *model_value2.get(), decoded_model2.get(),
+  ASSERT_TRUE(Decode(&decoder2, model_value2, decoded_model2.get(),
                      /*sync_metadata_str=*/nullptr));
   ASSERT_NO_FATAL_FAILURE(
       AssertModelsEqual(decoded_model.get(), decoded_model2.get()));
@@ -419,12 +407,11 @@
   model->SetNodeMetaInfo(model->bookmark_bar_node()->children().front().get(),
                          "node_info", "value2");
   std::string checksum;
-  std::unique_ptr<base::Value> value =
+  base::Value value =
       EncodeHelper(model.get(), /*sync_metadata_str=*/std::string(), &checksum);
-  ASSERT_TRUE(value.get() != nullptr);
 
   // Decode and check for meta info.
-  model = DecodeHelper(*value, checksum, &checksum, false,
+  model = DecodeHelper(value, checksum, &checksum, false,
                        /*sync_metadata_str=*/nullptr);
   std::string meta_value;
   EXPECT_TRUE(model->root_node()->GetMetaInfo("model_info", &meta_value));
@@ -473,13 +460,11 @@
   // Since metadata str serialized proto, it could contain no ASCII characters.
   std::string sync_metadata_str("a/2'\"");
   std::string checksum;
-  std::unique_ptr<base::Value> value =
-      EncodeHelper(model.get(), sync_metadata_str, &checksum);
-  ASSERT_TRUE(value.get() != nullptr);
+  base::Value value = EncodeHelper(model.get(), sync_metadata_str, &checksum);
 
   std::string decoded_sync_metadata_str;
   // Decode and verify.
-  DecodeHelper(*value, checksum, &checksum, false, &decoded_sync_metadata_str);
+  DecodeHelper(value, checksum, &checksum, false, &decoded_sync_metadata_str);
   EXPECT_EQ(sync_metadata_str, decoded_sync_metadata_str);
 }
 
@@ -492,13 +477,13 @@
             model->bookmark_bar_node()->children()[1]->guid());
 
   std::string checksum;
-  std::unique_ptr<base::Value> model_value =
+  base::Value model_value =
       EncodeHelper(model.get(), /*sync_metadata_str=*/std::string(), &checksum);
 
   // Decode and check for GUIDs.
-  std::unique_ptr<BookmarkModel> decoded_model = DecodeHelper(
-      *model_value, checksum, &checksum, /*expected_changes=*/false,
-      /*sync_metadata_str=*/nullptr);
+  std::unique_ptr<BookmarkModel> decoded_model =
+      DecodeHelper(model_value, checksum, &checksum, /*expected_changes=*/false,
+                   /*sync_metadata_str=*/nullptr);
 
   ASSERT_NO_FATAL_FAILURE(AssertModelsEqual(model.get(), decoded_model.get()));
 
@@ -512,22 +497,19 @@
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
 
   BookmarkCodec encoder;
-  std::unique_ptr<base::Value> value(
-      encoder.Encode(model_to_encode.get(), std::string()));
-
-  EXPECT_TRUE(value.get() != nullptr);
+  base::Value value(encoder.Encode(model_to_encode.get(), std::string()));
 
   std::unique_ptr<BookmarkModel> decoded_model1(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder1;
-  ASSERT_TRUE(Decode(&decoder1, *value.get(), decoded_model1.get(),
+  ASSERT_TRUE(Decode(&decoder1, value, decoded_model1.get(),
                      /*sync_metadata_str=*/nullptr));
 
   EXPECT_FALSE(decoder1.guids_reassigned());
 
   // Change GUID of child to be empty.
   base::Value* child_value = nullptr;
-  GetBookmarksBarChildValue(value.get(), 0, &child_value);
+  GetBookmarksBarChildValue(&value, 0, &child_value);
   std::string* guid_str = child_value->FindStringKey(BookmarkCodec::kGuidKey);
   ASSERT_TRUE(guid_str);
   std::string original_guid_str = *guid_str;
@@ -536,7 +518,7 @@
   std::unique_ptr<BookmarkModel> decoded_model2(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder2;
-  ASSERT_TRUE(Decode(&decoder2, *value.get(), decoded_model2.get(),
+  ASSERT_TRUE(Decode(&decoder2, value, decoded_model2.get(),
                      /*sync_metadata_str=*/nullptr));
 
   const base::GUID guid = base::GUID::ParseCaseInsensitive(original_guid_str);
@@ -551,22 +533,19 @@
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
 
   BookmarkCodec encoder;
-  std::unique_ptr<base::Value> value(
-      encoder.Encode(model_to_encode.get(), std::string()));
-
-  EXPECT_TRUE(value.get() != nullptr);
+  base::Value value(encoder.Encode(model_to_encode.get(), std::string()));
 
   std::unique_ptr<BookmarkModel> decoded_model1(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder1;
-  ASSERT_TRUE(Decode(&decoder1, *value.get(), decoded_model1.get(),
+  ASSERT_TRUE(Decode(&decoder1, value, decoded_model1.get(),
                      /*sync_metadata_str=*/nullptr));
 
   EXPECT_FALSE(decoder1.guids_reassigned());
 
   // Change GUID of child to be missing.
   base::Value* child_value = nullptr;
-  GetBookmarksBarChildValue(value.get(), 0, &child_value);
+  GetBookmarksBarChildValue(&value, 0, &child_value);
   std::string* guid_str = child_value->FindStringKey(BookmarkCodec::kGuidKey);
   ASSERT_TRUE(guid_str);
   std::string original_guid_str = *guid_str;
@@ -575,7 +554,7 @@
   std::unique_ptr<BookmarkModel> decoded_model2(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder2;
-  ASSERT_TRUE(Decode(&decoder2, *value.get(), decoded_model2.get(),
+  ASSERT_TRUE(Decode(&decoder2, value, decoded_model2.get(),
                      /*sync_metadata_str=*/nullptr));
 
   const base::GUID guid = base::GUID::ParseCaseInsensitive(original_guid_str);
@@ -593,14 +572,11 @@
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
 
   BookmarkCodec encoder;
-  std::unique_ptr<base::Value> value(
-      encoder.Encode(model_to_encode.get(), std::string()));
-
-  EXPECT_TRUE(value.get() != nullptr);
+  base::Value value(encoder.Encode(model_to_encode.get(), std::string()));
 
   // Change GUID of child to be invalid.
   base::Value* child_value = nullptr;
-  GetBookmarksBarChildValue(value.get(), 0, &child_value);
+  GetBookmarksBarChildValue(&value, 0, &child_value);
   child_value->SetStringKey(BookmarkCodec::kGuidKey, kInvalidGuid);
 
   std::string* guid = child_value->FindStringKey(BookmarkCodec::kGuidKey);
@@ -610,7 +586,7 @@
   std::unique_ptr<BookmarkModel> decoded_model(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder;
-  ASSERT_TRUE(Decode(&decoder, *value.get(), decoded_model.get(),
+  ASSERT_TRUE(Decode(&decoder, value, decoded_model.get(),
                      /*sync_metadata_str=*/nullptr));
 
   EXPECT_TRUE(
@@ -621,20 +597,17 @@
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel2());
 
   BookmarkCodec encoder;
-  std::unique_ptr<base::Value> value(
-      encoder.Encode(model_to_encode.get(), std::string()));
-
-  EXPECT_TRUE(value.get() != nullptr);
+  base::Value value(encoder.Encode(model_to_encode.get(), std::string()));
 
   base::Value* child1_value = nullptr;
-  GetBookmarksBarChildValue(value.get(), 0, &child1_value);
+  GetBookmarksBarChildValue(&value, 0, &child1_value);
 
   std::string* child1_guid =
       child1_value->FindStringKey(BookmarkCodec::kGuidKey);
   ASSERT_TRUE(child1_guid);
 
   base::Value* child2_value = nullptr;
-  GetBookmarksBarChildValue(value.get(), 1, &child2_value);
+  GetBookmarksBarChildValue(&value, 1, &child2_value);
 
   // Change GUID of child to be duplicate.
   child2_value->SetStringKey(BookmarkCodec::kGuidKey, *child1_guid);
@@ -647,7 +620,7 @@
   std::unique_ptr<BookmarkModel> decoded_model(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder;
-  ASSERT_TRUE(Decode(&decoder, *value.get(), decoded_model.get(),
+  ASSERT_TRUE(Decode(&decoder, value, decoded_model.get(),
                      /*sync_metadata_str=*/nullptr));
 
   EXPECT_NE(decoded_model->bookmark_bar_node()->children()[0]->guid(),
@@ -658,13 +631,10 @@
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
 
   BookmarkCodec encoder;
-  std::unique_ptr<base::Value> value(
-      encoder.Encode(model_to_encode.get(), std::string()));
-
-  EXPECT_TRUE(value.get() != nullptr);
+  base::Value value(encoder.Encode(model_to_encode.get(), std::string()));
 
   base::Value* child_value = nullptr;
-  GetBookmarksBarChildValue(value.get(), 0, &child_value);
+  GetBookmarksBarChildValue(&value, 0, &child_value);
 
   // Change GUID of child to be the root node GUID.
   child_value->SetStringKey(BookmarkCodec::kGuidKey,
@@ -677,7 +647,7 @@
   std::unique_ptr<BookmarkModel> decoded_model(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder;
-  ASSERT_TRUE(Decode(&decoder, *value.get(), decoded_model.get(),
+  ASSERT_TRUE(Decode(&decoder, value, decoded_model.get(),
                      /*sync_metadata_str=*/nullptr));
 
   EXPECT_NE(base::GUID::ParseLowercase(BookmarkNode::kRootNodeGuid),
@@ -691,19 +661,18 @@
 
   std::unique_ptr<BookmarkModel> model_to_encode(CreateTestModel1());
   BookmarkCodec encoder;
-  std::unique_ptr<base::Value> value(
-      encoder.Encode(model_to_encode.get(), std::string()));
+  base::Value value(encoder.Encode(model_to_encode.get(), std::string()));
 
   // Change a GUID to a capitalized form, which could have been produced by an
   // older version of the browser, before canonicalization was enforced.
   base::Value* child_value = nullptr;
-  GetBookmarksBarChildValue(value.get(), 0, &child_value);
+  GetBookmarksBarChildValue(&value, 0, &child_value);
   child_value->SetStringKey(BookmarkCodec::kGuidKey, kUpperCaseGuid);
 
   std::unique_ptr<BookmarkModel> decoded_model2(
       TestBookmarkClient::CreateModel());
   BookmarkCodec decoder2;
-  ASSERT_TRUE(Decode(&decoder2, *value.get(), decoded_model2.get(),
+  ASSERT_TRUE(Decode(&decoder2, value, decoded_model2.get(),
                      /*sync_metadata_str=*/nullptr));
 
   EXPECT_EQ(kGuid, decoded_model2->bookmark_bar_node()->children()[0]->guid());
diff --git a/components/bookmarks/browser/bookmark_expanded_state_tracker.cc b/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
index c879fc3..6169d44 100644
--- a/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
+++ b/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
@@ -42,7 +42,7 @@
   if (!pref_service_)
     return nodes;
 
-  const base::ListValue* value =
+  const base::Value* value =
       pref_service_->GetList(prefs::kBookmarkEditorExpandedNodes);
   if (!value)
     return nodes;
diff --git a/components/bookmarks/browser/bookmark_storage.cc b/components/bookmarks/browser/bookmark_storage.cc
index 5a1bfc7..42ac4309 100644
--- a/components/bookmarks/browser/bookmark_storage.cc
+++ b/components/bookmarks/browser/bookmark_storage.cc
@@ -83,15 +83,15 @@
 base::ImportantFileWriter::BackgroundDataProducerCallback
 BookmarkStorage::GetSerializedDataProducerForBackgroundSequence() {
   BookmarkCodec codec;
-  std::unique_ptr<base::Value> value(
+  base::Value value(
       codec.Encode(model_, model_->client()->EncodeBookmarkSyncMetadata()));
 
   return base::BindOnce(
-      [](std::unique_ptr<base::Value> value, std::string* output) {
+      [](base::Value value, std::string* output) {
         // This runs on the background sequence.
         JSONStringValueSerializer serializer(output);
         serializer.set_pretty_print(true);
-        return serializer.Serialize(*value);
+        return serializer.Serialize(value);
       },
       std::move(value));
 }
diff --git a/components/bookmarks/managed/managed_bookmark_service.cc b/components/bookmarks/managed/managed_bookmark_service.cc
index f6fe6cac..e345207 100644
--- a/components/bookmarks/managed/managed_bookmark_service.cc
+++ b/components/bookmarks/managed/managed_bookmark_service.cc
@@ -30,14 +30,14 @@
 // representation, title id and starting node id.
 class BookmarkPermanentNodeLoader {
  public:
-  BookmarkPermanentNodeLoader(
-      std::unique_ptr<BookmarkPermanentNode> node,
-      std::unique_ptr<base::ListValue> initial_bookmarks,
-      int title_id)
+  BookmarkPermanentNodeLoader(std::unique_ptr<BookmarkPermanentNode> node,
+                              base::Value initial_bookmarks,
+                              int title_id)
       : node_(std::move(node)),
         initial_bookmarks_(std::move(initial_bookmarks)),
         title_id_(title_id) {
     DCHECK(node_);
+    DCHECK(initial_bookmarks_.is_list());
   }
 
   ~BookmarkPermanentNodeLoader() {}
@@ -48,14 +48,14 @@
   std::unique_ptr<BookmarkPermanentNode> Load(int64_t* next_node_id) {
     node_->set_id(*next_node_id);
     *next_node_id = ManagedBookmarksTracker::LoadInitial(
-        node_.get(), initial_bookmarks_.get(), node_->id() + 1);
+        node_.get(), &initial_bookmarks_, node_->id() + 1);
     node_->SetTitle(l10n_util::GetStringUTF16(title_id_));
     return std::move(node_);
   }
 
  private:
   std::unique_ptr<BookmarkPermanentNode> node_;
-  std::unique_ptr<base::ListValue> initial_bookmarks_;
+  base::Value initial_bookmarks_;
   int title_id_;
 
   DISALLOW_COPY_AND_ASSIGN(BookmarkPermanentNodeLoader);
diff --git a/components/bookmarks/managed/managed_bookmarks_policy_handler_unittest.cc b/components/bookmarks/managed/managed_bookmarks_policy_handler_unittest.cc
index 52a64997..6eb84d1c7 100644
--- a/components/bookmarks/managed/managed_bookmarks_policy_handler_unittest.cc
+++ b/components/bookmarks/managed/managed_bookmarks_policy_handler_unittest.cc
@@ -175,8 +175,8 @@
 
 TEST_F(ManagedBookmarksPolicyHandlerTest, WrongPolicyType) {
   PolicyMap policy;
-  // The expected type is base::ListValue, but this policy sets it as an
-  // unparsed base::Value. Any type other than ListValue should fail.
+  // The expected type is a list base::Value, but this policy sets it as an
+  // unparsed base::Value. Any type other than list should fail.
   policy.Set(kManagedBookmarks, policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
              base::Value("["
diff --git a/components/bookmarks/managed/managed_bookmarks_tracker.cc b/components/bookmarks/managed/managed_bookmarks_tracker.cc
index 225b46bd..fb714d9 100644
--- a/components/bookmarks/managed/managed_bookmarks_tracker.cc
+++ b/components/bookmarks/managed/managed_bookmarks_tracker.cc
@@ -42,21 +42,21 @@
 
 ManagedBookmarksTracker::~ManagedBookmarksTracker() {}
 
-std::unique_ptr<base::ListValue>
-ManagedBookmarksTracker::GetInitialManagedBookmarks() {
-  const base::ListValue* list = prefs_->GetList(prefs::kManagedBookmarks);
-  return base::WrapUnique(list->DeepCopy());
+base::Value ManagedBookmarksTracker::GetInitialManagedBookmarks() {
+  const base::Value* list = prefs_->GetList(prefs::kManagedBookmarks);
+  return list->Clone();
 }
 
 // static
 int64_t ManagedBookmarksTracker::LoadInitial(BookmarkNode* folder,
-                                             const base::ListValue* list,
+                                             const base::Value* list,
                                              int64_t next_node_id) {
-  for (size_t i = 0; i < list->GetSize(); ++i) {
+  DCHECK(list->is_list());
+  for (size_t i = 0; i < list->GetList().size(); ++i) {
     // Extract the data for the next bookmark from the |list|.
     std::u16string title;
     GURL url;
-    const base::ListValue* children = nullptr;
+    const base::Value* children = nullptr;
     if (!LoadBookmark(list, i, &title, &url, &children))
       continue;
 
@@ -108,18 +108,19 @@
   model_->SetTitle(managed_node_, GetBookmarksFolderTitle());
 
   // Recursively update all the managed bookmarks and folders.
-  const base::ListValue* list = prefs_->GetList(prefs::kManagedBookmarks);
+  const base::Value* list = prefs_->GetList(prefs::kManagedBookmarks);
   UpdateBookmarks(managed_node_, list);
 }
 
 void ManagedBookmarksTracker::UpdateBookmarks(const BookmarkNode* folder,
-                                              const base::ListValue* list) {
+                                              const base::Value* list) {
+  DCHECK(list->is_list());
   size_t folder_index = 0;
-  for (size_t i = 0; i < list->GetSize(); ++i) {
+  for (size_t i = 0; i < list->GetList().size(); ++i) {
     // Extract the data for the next bookmark from the |list|.
     std::u16string title;
     GURL url;
-    const base::ListValue* children = nullptr;
+    const base::Value* children = nullptr;
     if (!LoadBookmark(list, i, &title, &url, &children)) {
       // Skip this bookmark from |list| but don't advance |folder_index|.
       continue;
@@ -156,25 +157,33 @@
 }
 
 // static
-bool ManagedBookmarksTracker::LoadBookmark(const base::ListValue* list,
+bool ManagedBookmarksTracker::LoadBookmark(const base::Value* list,
                                            size_t index,
                                            std::u16string* title,
                                            GURL* url,
-                                           const base::ListValue** children) {
-  std::string spec;
+                                           const base::Value** children) {
+  DCHECK(list->is_list());
   *url = GURL();
   *children = nullptr;
-  const base::DictionaryValue* dict = nullptr;
-  if (!list->GetDictionary(index, &dict) ||
-      !dict->GetString(kName, title) ||
-      (!dict->GetString(kUrl, &spec) &&
-       !dict->GetList(kChildren, children))) {
+  const base::Value& dict = list->GetList()[index];
+  if (!dict.is_dict()) {
     // Should never happen after policy validation.
     NOTREACHED();
     return false;
   }
+  const std::string* name = dict.FindStringKey(kName);
+  const std::string* spec = dict.FindStringKey(kUrl);
+  const base::Value* children_list = dict.FindListKey(kChildren);
+  if (!dict.is_dict() || !name || (!spec && !children_list)) {
+    // Should never happen after policy validation.
+    NOTREACHED();
+    return false;
+  }
+
+  *title = base::UTF8ToUTF16(*name);
+  *children = children_list;
   if (!*children) {
-    *url = GURL(spec);
+    *url = GURL(*spec);
     DCHECK(url->is_valid());
   }
   return true;
diff --git a/components/bookmarks/managed/managed_bookmarks_tracker.h b/components/bookmarks/managed/managed_bookmarks_tracker.h
index df7116d..ed42ff0 100644
--- a/components/bookmarks/managed/managed_bookmarks_tracker.h
+++ b/components/bookmarks/managed/managed_bookmarks_tracker.h
@@ -19,7 +19,7 @@
 class PrefService;
 
 namespace base {
-class ListValue;
+class Value;
 }
 
 namespace bookmarks {
@@ -47,13 +47,13 @@
 
   // Returns the initial list of managed bookmarks, which can be passed to
   // LoadInitial() to do the initial load.
-  std::unique_ptr<base::ListValue> GetInitialManagedBookmarks();
+  base::Value GetInitialManagedBookmarks();
 
   // Loads the initial managed bookmarks in |list| into |folder|.
   // New nodes will be assigned IDs starting at |next_node_id|.
   // Returns the next node ID to use.
   static int64_t LoadInitial(BookmarkNode* folder,
-                             const base::ListValue* list,
+                             const base::Value* list,
                              int64_t next_node_id);
 
   // Starts tracking the pref for updates to the managed bookmarks.
@@ -65,12 +65,12 @@
 
   void ReloadManagedBookmarks();
 
-  void UpdateBookmarks(const BookmarkNode* folder, const base::ListValue* list);
-  static bool LoadBookmark(const base::ListValue* list,
+  void UpdateBookmarks(const BookmarkNode* folder, const base::Value* list);
+  static bool LoadBookmark(const base::Value* list,
                            size_t index,
                            std::u16string* title,
                            GURL* url,
-                           const base::ListValue** children);
+                           const base::Value** children);
 
   BookmarkModel* model_;
   BookmarkPermanentNode* managed_node_;
diff --git a/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc b/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc
index e273967..0b60350c 100644
--- a/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc
+++ b/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc
@@ -82,34 +82,35 @@
     return node && node->HasAncestor(managed_node_);
   }
 
-  static std::unique_ptr<base::DictionaryValue> CreateBookmark(
-      const std::string& title,
-      const std::string& url) {
+  void SetManagedPref(const std::string& path, const base::Value& value) {
+    prefs_.SetManagedPref(path, base::Value::ToUniquePtrValue(value.Clone()));
+  }
+
+  static base::Value CreateBookmark(const std::string& title,
+                                    const std::string& url) {
     EXPECT_TRUE(GURL(url).is_valid());
-    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-    dict->SetString("name", title);
-    dict->SetString("url", GURL(url).spec());
+    base::Value dict(base::Value::Type::DICTIONARY);
+    dict.SetStringKey("name", title);
+    dict.SetStringKey("url", GURL(url).spec());
     return dict;
   }
 
-  static std::unique_ptr<base::DictionaryValue> CreateFolder(
-      const std::string& title,
-      std::unique_ptr<base::ListValue> children) {
-    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-    dict->SetString("name", title);
-    dict->SetKey("children",
-                 base::Value::FromUniquePtrValue(std::move(children)));
+  static base::Value CreateFolder(const std::string& title,
+                                  base::Value children) {
+    base::Value dict(base::Value::Type::DICTIONARY);
+    dict.SetStringKey("name", title);
+    dict.SetKey("children", std::move(children));
     return dict;
   }
 
-  static std::unique_ptr<base::ListValue> CreateTestTree() {
-    auto folder = std::make_unique<base::ListValue>();
-    folder->Append(CreateFolder("Empty", std::make_unique<base::ListValue>()));
-    folder->Append(CreateBookmark("Youtube", "http://youtube.com/"));
+  static base::Value CreateTestTree() {
+    base::Value folder(base::Value::Type::LIST);
+    folder.Append(CreateFolder("Empty", base::Value(base::Value::Type::LIST)));
+    folder.Append(CreateBookmark("Youtube", "http://youtube.com/"));
 
-    auto list = std::make_unique<base::ListValue>();
-    list->Append(CreateBookmark("Google", "http://google.com/"));
-    list->Append(CreateFolder("Folder", std::move(folder)));
+    base::Value list(base::Value::Type::LIST);
+    list.Append(CreateBookmark("Google", "http://google.com/"));
+    list.Append(CreateFolder("Folder", std::move(folder)));
 
     return list;
   }
@@ -123,34 +124,33 @@
         IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME);
   }
 
-  static std::unique_ptr<base::DictionaryValue> CreateExpectedTree() {
+  static base::Value CreateExpectedTree() {
     return CreateFolder(GetManagedFolderTitle(), CreateTestTree());
   }
 
   static bool NodeMatchesValue(const BookmarkNode* node,
-                               const base::DictionaryValue* dict) {
-    std::u16string title;
-    if (!dict->GetString("name", &title) || node->GetTitle() != title)
+                               const base::Value& dict) {
+    DCHECK(dict.is_dict());
+    const std::string* title = dict.FindStringKey("name");
+    if (!title || node->GetTitle() != base::UTF8ToUTF16(*title))
       return false;
 
     if (node->is_folder()) {
-      const base::ListValue* children = nullptr;
-      if (!dict->GetList("children", &children) ||
-          node->children().size() != children->GetSize()) {
+      const base::Value* children = dict.FindListKey("children");
+      if (!children || node->children().size() != children->GetList().size())
         return false;
-      }
       size_t i = 0;
       return std::all_of(node->children().cbegin(), node->children().cend(),
                          [children, &i](const auto& child_node) {
-                           const base::DictionaryValue* child = nullptr;
-                           return children->GetDictionary(i++, &child) &&
+                           const base::Value& child = children->GetList()[i++];
+                           return child.is_dict() &&
                                   NodeMatchesValue(child_node.get(), child);
                          });
     }
     if (!node->is_url())
       return false;
-    std::string url;
-    return dict->GetString("url", &url) && node->url() == url;
+    const std::string* url = dict.FindStringKey("url");
+    return url && node->url() == *url;
   }
 
   base::ScopedTempDir scoped_temp_dir_;
@@ -172,15 +172,15 @@
 
 TEST_F(ManagedBookmarksTrackerTest, LoadInitial) {
   // Set a policy before loading the model.
-  prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
+  SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
   CreateModel();
   EXPECT_TRUE(model_->bookmark_bar_node()->children().empty());
   EXPECT_TRUE(model_->other_node()->children().empty());
   EXPECT_FALSE(managed_node()->children().empty());
   EXPECT_TRUE(managed_node()->IsVisible());
 
-  std::unique_ptr<base::DictionaryValue> expected(CreateExpectedTree());
-  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected.get()));
+  base::Value expected(CreateExpectedTree());
+  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
 }
 
 TEST_F(ManagedBookmarksTrackerTest, LoadInitialWithTitle) {
@@ -188,70 +188,67 @@
   const char kExpectedFolderName[] = "foo";
   prefs_.SetString(prefs::kManagedBookmarksFolderName, kExpectedFolderName);
   // Set a policy before loading the model.
-  prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
+  SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
   CreateModel();
   EXPECT_TRUE(model_->bookmark_bar_node()->children().empty());
   EXPECT_TRUE(model_->other_node()->children().empty());
   EXPECT_FALSE(managed_node()->children().empty());
   EXPECT_TRUE(managed_node()->IsVisible());
 
-  std::unique_ptr<base::DictionaryValue> expected(
-      CreateFolder(kExpectedFolderName, CreateTestTree()));
-  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected.get()));
+  base::Value expected(CreateFolder(kExpectedFolderName, CreateTestTree()));
+  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
 }
 
 TEST_F(ManagedBookmarksTrackerTest, SwapNodes) {
-  prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
+  SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
   CreateModel();
 
   // Swap the Google bookmark with the Folder.
-  std::unique_ptr<base::ListValue> updated(CreateTestTree());
-  base::Value::ListView updated_listview = updated->GetList();
+  base::Value updated(CreateTestTree());
+  base::Value::ListView updated_listview = updated.GetList();
   ASSERT_FALSE(updated_listview.empty());
   base::Value removed = std::move(updated_listview[0]);
-  ASSERT_TRUE(updated->EraseListIter(updated_listview.begin()));
-  updated->Append(std::move(removed));
+  ASSERT_TRUE(updated.EraseListIter(updated_listview.begin()));
+  updated.Append(std::move(removed));
 
   // These two nodes should just be swapped.
   const BookmarkNode* parent = managed_node();
   EXPECT_CALL(observer_, BookmarkNodeMoved(model_.get(), parent, 1, parent, 0));
-  prefs_.SetManagedPref(prefs::kManagedBookmarks,
-                        base::Value::ToUniquePtrValue(updated->Clone()));
+  SetManagedPref(prefs::kManagedBookmarks, updated);
   Mock::VerifyAndClearExpectations(&observer_);
 
   // Verify the final tree.
-  std::unique_ptr<base::DictionaryValue> expected(
+  base::Value expected(
       CreateFolder(GetManagedFolderTitle(), std::move(updated)));
-  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected.get()));
+  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
 }
 
 TEST_F(ManagedBookmarksTrackerTest, RemoveNode) {
-  prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
+  SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
   CreateModel();
 
   // Remove the Folder.
-  std::unique_ptr<base::ListValue> updated(CreateTestTree());
-  ASSERT_TRUE(updated->EraseListIter(updated->GetList().begin() + 1));
+  base::Value updated(CreateTestTree());
+  ASSERT_TRUE(updated.EraseListIter(updated.GetList().begin() + 1));
 
   const BookmarkNode* parent = managed_node();
   EXPECT_CALL(observer_, BookmarkNodeRemoved(model_.get(), parent, 1, _, _));
-  prefs_.SetManagedPref(prefs::kManagedBookmarks,
-                        base::Value::ToUniquePtrValue(updated->Clone()));
+  SetManagedPref(prefs::kManagedBookmarks, updated);
   Mock::VerifyAndClearExpectations(&observer_);
 
   // Verify the final tree.
-  std::unique_ptr<base::DictionaryValue> expected(
+  base::Value expected(
       CreateFolder(GetManagedFolderTitle(), std::move(updated)));
-  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected.get()));
+  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
 }
 
 TEST_F(ManagedBookmarksTrackerTest, CreateNewNodes) {
-  prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
+  SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
   CreateModel();
 
   // Put all the nodes inside another folder.
-  std::unique_ptr<base::ListValue> updated(new base::ListValue);
-  updated->Append(CreateFolder("Container", CreateTestTree()));
+  base::Value updated(base::Value::Type::LIST);
+  updated.Append(CreateFolder("Container", CreateTestTree()));
 
   EXPECT_CALL(observer_, BookmarkNodeAdded(model_.get(), _, _)).Times(5);
   // The remaining nodes have been pushed to positions 1 and 2; they'll both be
@@ -259,18 +256,17 @@
   const BookmarkNode* parent = managed_node();
   EXPECT_CALL(observer_, BookmarkNodeRemoved(model_.get(), parent, 1, _, _))
       .Times(2);
-  prefs_.SetManagedPref(prefs::kManagedBookmarks,
-                        base::Value::ToUniquePtrValue(updated->Clone()));
+  SetManagedPref(prefs::kManagedBookmarks, updated);
   Mock::VerifyAndClearExpectations(&observer_);
 
   // Verify the final tree.
-  std::unique_ptr<base::DictionaryValue> expected(
+  base::Value expected(
       CreateFolder(GetManagedFolderTitle(), std::move(updated)));
-  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected.get()));
+  EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
 }
 
 TEST_F(ManagedBookmarksTrackerTest, RemoveAll) {
-  prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
+  SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
   CreateModel();
   EXPECT_TRUE(managed_node()->IsVisible());
 
@@ -286,7 +282,7 @@
 }
 
 TEST_F(ManagedBookmarksTrackerTest, IsManaged) {
-  prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
+  SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
   CreateModel();
 
   EXPECT_FALSE(IsManaged(model_->root_node()));
@@ -307,7 +303,7 @@
 }
 
 TEST_F(ManagedBookmarksTrackerTest, RemoveAllUserBookmarksDoesntRemoveManaged) {
-  prefs_.SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
+  SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
   CreateModel();
   EXPECT_EQ(2u, managed_node()->children().size());
 
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc
index 8bf744f..7a25f63 100644
--- a/components/browser_sync/profile_sync_components_factory_impl.cc
+++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -39,6 +39,7 @@
 #include "components/sync/base/sync_prefs.h"
 #include "components/sync/driver/data_type_manager_impl.h"
 #include "components/sync/driver/glue/sync_engine_impl.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/model_type_controller.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/driver/syncable_service_based_model_type_controller.h"
diff --git a/components/browser_ui/widget/android/java/res/layout/selectable_list_layout.xml b/components/browser_ui/widget/android/java/res/layout/selectable_list_layout.xml
index 561eefb..0b7d928 100644
--- a/components/browser_ui/widget/android/java/res/layout/selectable_list_layout.xml
+++ b/components/browser_ui/widget/android/java/res/layout/selectable_list_layout.xml
@@ -36,15 +36,15 @@
             android:scrollbars="vertical" />
 
 
-        <FrameLayout
-            style="@style/Card"
+        <org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow
             android:id="@+id/empty_view_wrapper"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center"
             android:layout_marginStart="@dimen/default_list_row_padding"
             android:layout_marginEnd="@dimen/default_list_row_padding"
-            android:visibility="gone">
+            android:visibility="gone"
+            style="@style/MaterialCardStyle">
 
             <org.chromium.ui.widget.TextViewWithLeading
                 android:id="@+id/empty_view"
@@ -57,7 +57,7 @@
                 android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
                 app:leading="@dimen/text_size_medium_leading" />
 
-        </FrameLayout>
+        </org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow>
 
         <org.chromium.ui.widget.LoadingView
             android:id="@+id/loading_view"
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
index affe5cd..62816a7 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -241,7 +241,7 @@
     } else if (days_since_last_update < -1) {
       // Erase all entries if the system went backwards in time by more than
       // a day.
-      update_->Clear();
+      update_->ClearList();
 
       days_since_last_update = kNumDaysInHistory;
     }
@@ -464,8 +464,8 @@
       GetList(prefs::kDailyHttpOriginalContentLength);
   base::ListValue* received_update =
       GetList(prefs::kDailyHttpReceivedContentLength);
-  original_update->Clear();
-  received_update->Clear();
+  original_update->ClearList();
+  received_update->ClearList();
   for (size_t i = 0; i < kNumDaysInHistory; ++i) {
     original_update->AppendString(base::NumberToString(0));
     received_update->AppendString(base::NumberToString(0));
@@ -610,7 +610,7 @@
 
   for (auto iter = list_pref_map_.begin(); iter != list_pref_map_.end();
        ++iter) {
-    iter->second->Clear();
+    iter->second->ClearList();
   }
 
   RecordSavingsClearedMetric(reason);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
index 40f58e4..ba1060c 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -166,7 +166,7 @@
           i, std::make_unique<base::Value>(base::NumberToString(i)));
     }
 
-    received_daily_content_length_list->Clear();
+    received_daily_content_length_list->ClearList();
     for (size_t i = 0; i < kNumDaysInHistory / 2; ++i) {
       received_daily_content_length_list->AppendString(base::NumberToString(i));
     }
diff --git a/components/download/internal/background_service/logger_impl.cc b/components/download/internal/background_service/logger_impl.cc
index 6553cec..c2bb58e 100644
--- a/components/download/internal/background_service/logger_impl.cc
+++ b/components/download/internal/background_service/logger_impl.cc
@@ -143,48 +143,44 @@
   }
 }
 
-std::unique_ptr<base::DictionaryValue> DriverEntryToValue(
-    const DriverEntry& entry) {
-  std::unique_ptr<base::DictionaryValue> serialized_entry =
-      std::make_unique<base::DictionaryValue>();
-  serialized_entry->SetString("state", DriverEntryStateToString(entry.state));
-  serialized_entry->SetBoolean("paused", entry.paused);
-  serialized_entry->SetBoolean("done", entry.done);
+base::Value DriverEntryToValue(const DriverEntry& entry) {
+  base::Value serialized_entry(base::Value::Type::DICTIONARY);
+  serialized_entry.SetStringKey("state", DriverEntryStateToString(entry.state));
+  serialized_entry.SetBoolKey("paused", entry.paused);
+  serialized_entry.SetBoolKey("done", entry.done);
   return serialized_entry;
 }
 
-std::unique_ptr<base::DictionaryValue> EntryToValue(
+base::Value EntryToValue(
     const Entry& entry,
     const absl::optional<DriverEntry>& driver,
     const absl::optional<CompletionType>& completion_type) {
-  std::unique_ptr<base::DictionaryValue> serialized_entry =
-      std::make_unique<base::DictionaryValue>();
-  serialized_entry->SetString("client", ClientToString(entry.client));
-  serialized_entry->SetString("state", EntryStateToString(entry.state));
-  serialized_entry->SetString("guid", entry.guid);
+  base::Value serialized_entry(base::Value::Type::DICTIONARY);
+  serialized_entry.SetStringKey("client", ClientToString(entry.client));
+  serialized_entry.SetStringKey("state", EntryStateToString(entry.state));
+  serialized_entry.SetStringKey("guid", entry.guid);
 
   // Convert the URL to a proper logging format.
   GURL::Replacements replacements;
   replacements.ClearQuery();
 
-  serialized_entry->SetString(
+  serialized_entry.SetStringKey(
       "url", entry.request_params.url.ReplaceComponents(replacements).spec());
-  serialized_entry->SetString("file_path",
-                              entry.target_file_path.MaybeAsASCII());
+  serialized_entry.SetStringKey("file_path",
+                                entry.target_file_path.MaybeAsASCII());
 
   if (driver.has_value()) {
-    serialized_entry->SetDouble("bytes_downloaded", driver->bytes_downloaded);
-    serialized_entry->SetDictionary("driver",
-                                    DriverEntryToValue(driver.value()));
+    serialized_entry.SetDoubleKey("bytes_downloaded", driver->bytes_downloaded);
+    serialized_entry.SetKey("driver", DriverEntryToValue(driver.value()));
   } else {
-    serialized_entry->SetDouble("bytes_downloaded", entry.bytes_downloaded);
+    serialized_entry.SetDoubleKey("bytes_downloaded", entry.bytes_downloaded);
   }
 
   if (completion_type.has_value()) {
-    serialized_entry->SetString(
+    serialized_entry.SetStringKey(
         "result", CompletionTypeToString(completion_type.value()));
   } else if (entry.state == Entry::State::COMPLETE) {
-    serialized_entry->SetString(
+    serialized_entry.SetStringKey(
         "result", CompletionTypeToString(CompletionType::SUCCEED));
   }
   return serialized_entry;
@@ -210,28 +206,29 @@
 }
 
 base::Value LoggerImpl::GetServiceStatus() {
-  base::DictionaryValue service_status;
+  base::Value service_status(base::Value::Type::DICTIONARY);
 
   if (!log_source_)
-    return std::move(service_status);
+    return service_status;
 
   Controller::State state = log_source_->GetControllerState();
   const StartupStatus& status = log_source_->GetStartupStatus();
 
-  service_status.SetString("serviceState", ControllerStateToString(state));
-  service_status.SetString("modelStatus", OptBoolToString(status.model_ok));
-  service_status.SetString("driverStatus", OptBoolToString(status.driver_ok));
-  service_status.SetString("fileMonitorStatus",
-                           OptBoolToString(status.file_monitor_ok));
+  service_status.SetStringKey("serviceState", ControllerStateToString(state));
+  service_status.SetStringKey("modelStatus", OptBoolToString(status.model_ok));
+  service_status.SetStringKey("driverStatus",
+                              OptBoolToString(status.driver_ok));
+  service_status.SetStringKey("fileMonitorStatus",
+                              OptBoolToString(status.file_monitor_ok));
 
-  return std::move(service_status);
+  return service_status;
 }
 
 base::Value LoggerImpl::GetServiceDownloads() {
-  base::ListValue serialized_entries;
+  base::Value serialized_entries(base::Value::Type::LIST);
 
   if (!log_source_)
-    return std::move(serialized_entries);
+    return serialized_entries;
 
   auto entries = log_source_->GetServiceDownloads();
   for (auto& entry : entries) {
@@ -239,7 +236,7 @@
         EntryToValue(*entry.first, entry.second, absl::nullopt));
   }
 
-  return std::move(serialized_entries);
+  return serialized_entries;
 }
 
 void LoggerImpl::OnServiceStatusChanged() {
@@ -273,7 +270,7 @@
                             absl::nullopt);
 
   for (auto& observer : observers_)
-    observer.OnServiceDownloadChanged(*entry);
+    observer.OnServiceDownloadChanged(entry);
 }
 
 void LoggerImpl::OnServiceDownloadFailed(CompletionType completion_type,
@@ -285,7 +282,7 @@
 
   auto serialized_entry = EntryToValue(entry, absl::nullopt, completion_type);
   for (auto& observer : observers_)
-    observer.OnServiceDownloadFailed(*serialized_entry);
+    observer.OnServiceDownloadFailed(serialized_entry);
 }
 
 void LoggerImpl::OnServiceRequestMade(
@@ -295,10 +292,10 @@
   if (observers_.empty())
     return;
 
-  base::DictionaryValue serialized_request;
-  serialized_request.SetString("client", ClientToString(client));
-  serialized_request.SetString("guid", guid);
-  serialized_request.SetString("result", StartResultToString(start_result));
+  base::Value serialized_request(base::Value::Type::DICTIONARY);
+  serialized_request.SetStringKey("client", ClientToString(client));
+  serialized_request.SetStringKey("guid", guid);
+  serialized_request.SetStringKey("result", StartResultToString(start_result));
   for (auto& observer : observers_)
     observer.OnServiceRequestMade(serialized_request);
 }
diff --git a/components/flags_ui/pref_service_flags_storage.cc b/components/flags_ui/pref_service_flags_storage.cc
index 007ed343..82dd60c7 100644
--- a/components/flags_ui/pref_service_flags_storage.cc
+++ b/components/flags_ui/pref_service_flags_storage.cc
@@ -40,9 +40,9 @@
   ListPrefUpdate update(prefs_, prefs::kAboutFlagsEntries);
   base::ListValue* experiments_list = update.Get();
 
-  experiments_list->Clear();
-  for (auto it = flags.begin(); it != flags.end(); ++it) {
-    experiments_list->AppendString(*it);
+  experiments_list->ClearList();
+  for (const auto& item : flags) {
+    experiments_list->AppendString(item);
   }
 
   return true;
diff --git a/components/full_restore/full_restore_save_handler.cc b/components/full_restore/full_restore_save_handler.cc
index ed72eb4..02b51b8c 100644
--- a/components/full_restore/full_restore_save_handler.cc
+++ b/components/full_restore/full_restore_save_handler.cc
@@ -62,6 +62,7 @@
     if (arc_save_handler_)
       arc_save_handler_->OnWindowInitialized(window);
 
+    ++window_count_;
     return;
   }
 
@@ -69,6 +70,7 @@
   if (!SessionID::IsValidValue(window_id))
     return;
 
+  ++window_count_;
   observed_windows_.AddObservation(window);
 
   std::string* app_id_str = window->GetProperty(::full_restore::kAppIdKey);
diff --git a/components/full_restore/full_restore_save_handler.h b/components/full_restore/full_restore_save_handler.h
index 87caef7..e14992f 100644
--- a/components/full_restore/full_restore_save_handler.h
+++ b/components/full_restore/full_restore_save_handler.h
@@ -144,6 +144,8 @@
   // nullptr if there is no such RestoreData.
   const RestoreData* GetRestoreData(const base::FilePath& profile_path);
 
+  int window_count() const { return window_count_; }
+
   base::OneShotTimer* GetTimerForTesting() { return &save_timer_; }
 
   // Since this is a singleton, tests may need to clear it between tests.
@@ -212,6 +214,9 @@
 
   std::unique_ptr<ArcSaveHandler> arc_save_handler_;
 
+  // The number of window created. This is used for metrics only.
+  int window_count_ = 0;
+
   base::ScopedObservation<aura::Env, aura::EnvObserver> env_observer_{this};
 
   base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
diff --git a/components/metrics/unsent_log_store.cc b/components/metrics/unsent_log_store.cc
index bc8139d..ff50718 100644
--- a/components/metrics/unsent_log_store.cc
+++ b/components/metrics/unsent_log_store.cc
@@ -334,7 +334,7 @@
 }
 
 void UnsentLogStore::WriteLogsToPrefList(base::ListValue* list_value) const {
-  list_value->Clear();
+  list_value->ClearList();
 
   base::HistogramBase::Count unsent_samples_count = 0;
   size_t unsent_persisted_size = 0;
diff --git a/components/page_load_metrics/browser/BUILD.gn b/components/page_load_metrics/browser/BUILD.gn
index 4b31ec7..bd7176f 100644
--- a/components/page_load_metrics/browser/BUILD.gn
+++ b/components/page_load_metrics/browser/BUILD.gn
@@ -26,6 +26,8 @@
     "observers/layout_page_load_metrics_observer.h",
     "observers/prerender_features_page_load_metrics_observer.cc",
     "observers/prerender_features_page_load_metrics_observer.h",
+    "observers/prerender_page_load_metrics_observer.cc",
+    "observers/prerender_page_load_metrics_observer.h",
     "observers/use_counter/ukm_features.cc",
     "observers/use_counter_page_load_metrics_observer.cc",
     "observers/use_counter_page_load_metrics_observer.h",
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
index c814156..d85e774 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -699,11 +699,11 @@
 
   if (navigation_handle->IsServedFromBackForwardCache()) {
     committed_load_->OnRestoreFromBackForwardCache(navigation_handle);
-    for (auto& observer : testing_observers_)
-      observer.OnRestoredFromBackForwardCache(committed_load_.get());
   } else if (navigation_handle->IsPrerenderedPageActivation()) {
     committed_load_->DidActivatePrerenderedPage(navigation_handle);
   }
+  for (auto& observer : testing_observers_)
+    observer.OnActivate(committed_load_.get());
 
   return true;
 }
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.h b/components/page_load_metrics/browser/metrics_web_contents_observer.h
index 99114478..f3259e6 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.h
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.h
@@ -75,7 +75,9 @@
     // fine.
     virtual void OnCommit(PageLoadTracker* tracker) {}
 
-    virtual void OnRestoredFromBackForwardCache(PageLoadTracker* tracker) {}
+    // This is called both for prerender activation and restoration from
+    // the back/forward cache.
+    virtual void OnActivate(PageLoadTracker* tracker) {}
 
     // Returns the observer delegate for the committed load associated with
     // the MetricsWebContentsObserver, or null if the observer has gone away
diff --git a/components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.cc b/components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.cc
new file mode 100644
index 0000000..ee9f30a
--- /dev/null
+++ b/components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.cc
@@ -0,0 +1,132 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.h"
+
+#include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
+#include "components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h"
+#include "components/page_load_metrics/browser/page_load_metrics_util.h"
+#include "content/public/browser/web_contents.h"
+
+namespace internal {
+
+const char kHistogramPrerenderNavigationToActivation[] =
+    "PageLoad.Clients.Prerender.NavigationToActivation";
+const char kHistogramPrerenderActivationToFirstPaint[] =
+    "PageLoad.Clients.Prerender.PaintTiming.ActivationToFirstPaint";
+const char kHistogramPrerenderActivationToFirstContentfulPaint[] =
+    "PageLoad.Clients.Prerender.PaintTiming.ActivationToFirstContentfulPaint";
+const char kHistogramPrerenderActivationToLargestContentfulPaint2[] =
+    "PageLoad.Clients.Prerender.PaintTiming."
+    "ActivationToLargestContentfulPaint2";
+const char kHistogramPrerenderFirstInputDelay4[] =
+    "PageLoad.Clients.Prerender.InteractiveTiming.FirstInputDelay4";
+const char kHistogramPrerenderCumulativeShiftScore[] =
+    "PageLoad.Clients.Prerender.LayoutInstability.CumulativeShiftScore";
+const char kHistogramPrerenderCumulativeShiftScoreMainFrame[] =
+    "PageLoad.Clients.Prerender.LayoutInstability.CumulativeShiftScore."
+    "MainFrame";
+
+}  // namespace internal
+
+page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+PrerenderPageLoadMetricsObserver::OnPrerenderStart(
+    content::NavigationHandle* navigation_handle,
+    const GURL& currently_committed_url) {
+  return CONTINUE_OBSERVING;
+}
+
+page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+PrerenderPageLoadMetricsObserver::OnStart(
+    content::NavigationHandle* navigation_handle,
+    const GURL& currently_committed_url,
+    bool started_in_foreground) {
+  return STOP_OBSERVING;
+}
+
+void PrerenderPageLoadMetricsObserver::DidActivatePrerenderedPage(
+    content::NavigationHandle* navigation_handle) {
+  // |navigation_handle| here is for the activation navigation, while
+  // |GetDelegate().GetNavigationStart()| is the start time of initial prerender
+  // navigation.
+  PAGE_LOAD_HISTOGRAM(internal::kHistogramPrerenderNavigationToActivation,
+                      navigation_handle->NavigationStart() -
+                          GetDelegate().GetNavigationStart());
+}
+
+void PrerenderPageLoadMetricsObserver::OnFirstPaintInPage(
+    const page_load_metrics::mojom::PageLoadTiming& timing) {
+  if (!WasActivatedInForegroundOptionalEventInForeground(
+          timing.paint_timing->first_paint, GetDelegate())) {
+    return;
+  }
+  PAGE_LOAD_HISTOGRAM(internal::kHistogramPrerenderActivationToFirstPaint,
+                      timing.paint_timing->first_paint.value() -
+                          timing.activation_start.value());
+}
+
+void PrerenderPageLoadMetricsObserver::OnFirstContentfulPaintInPage(
+    const page_load_metrics::mojom::PageLoadTiming& timing) {
+  if (!WasActivatedInForegroundOptionalEventInForeground(
+          timing.paint_timing->first_contentful_paint, GetDelegate())) {
+    return;
+  }
+  PAGE_LOAD_HISTOGRAM(
+      internal::kHistogramPrerenderActivationToFirstContentfulPaint,
+      timing.paint_timing->first_contentful_paint.value() -
+          timing.activation_start.value());
+}
+
+void PrerenderPageLoadMetricsObserver::OnFirstInputInPage(
+    const page_load_metrics::mojom::PageLoadTiming& timing) {
+  if (!WasActivatedInForegroundOptionalEventInForeground(
+          timing.interactive_timing->first_input_timestamp, GetDelegate())) {
+    return;
+  }
+  UMA_HISTOGRAM_CUSTOM_TIMES(
+      internal::kHistogramPrerenderFirstInputDelay4,
+      timing.interactive_timing->first_input_delay.value(),
+      base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(60),
+      50);
+}
+
+void PrerenderPageLoadMetricsObserver::OnComplete(
+    const page_load_metrics::mojom::PageLoadTiming& timing) {
+  RecordSessionEndHistograms(timing);
+}
+
+page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+PrerenderPageLoadMetricsObserver::FlushMetricsOnAppEnterBackground(
+    const page_load_metrics::mojom::PageLoadTiming& timing) {
+  RecordSessionEndHistograms(timing);
+  return STOP_OBSERVING;
+}
+
+void PrerenderPageLoadMetricsObserver::RecordSessionEndHistograms(
+    const page_load_metrics::mojom::PageLoadTiming& main_frame_timing) {
+  if (!GetDelegate().WasPrerenderedThenActivatedInForeground())
+    return;
+
+  const page_load_metrics::ContentfulPaintTimingInfo& largest_contentful_paint =
+      GetDelegate()
+          .GetLargestContentfulPaintHandler()
+          .MergeMainFrameAndSubframes();
+  if (largest_contentful_paint.ContainsValidTime() &&
+      WasActivatedInForegroundOptionalEventInForeground(
+          largest_contentful_paint.Time(), GetDelegate())) {
+    PAGE_LOAD_HISTOGRAM(
+        internal::kHistogramPrerenderActivationToLargestContentfulPaint2,
+        largest_contentful_paint.Time().value() -
+            main_frame_timing.activation_start.value());
+  }
+
+  UMA_HISTOGRAM_COUNTS_100(
+      internal::kHistogramPrerenderCumulativeShiftScore,
+      page_load_metrics::LayoutShiftUmaValue(
+          GetDelegate().GetPageRenderData().layout_shift_score));
+  UMA_HISTOGRAM_COUNTS_100(
+      internal::kHistogramPrerenderCumulativeShiftScoreMainFrame,
+      page_load_metrics::LayoutShiftUmaValue(
+          GetDelegate().GetMainFrameRenderData().layout_shift_score));
+}
diff --git a/components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.h b/components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.h
new file mode 100644
index 0000000..06a320a
--- /dev/null
+++ b/components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.h
@@ -0,0 +1,53 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PAGE_LOAD_METRICS_BROWSER_OBSERVERS_PRERENDER_PAGE_LOAD_METRICS_OBSERVER_H_
+#define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_OBSERVERS_PRERENDER_PAGE_LOAD_METRICS_OBSERVER_H_
+
+#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
+
+namespace internal {
+
+extern const char kHistogramPrerenderNavigationToActivation[];
+extern const char kHistogramPrerenderActivationToFirstPaint[];
+extern const char kHistogramPrerenderActivationToFirstContentfulPaint[];
+extern const char kHistogramPrerenderActivationToLargestContentfulPaint2[];
+extern const char kHistogramPrerenderFirstInputDelay4[];
+extern const char kHistogramPrerenderCumulativeShiftScore[];
+extern const char kHistogramPrerenderCumulativeShiftScoreMainFrame[];
+
+}  // namespace internal
+
+// Prerender2 (content/browser/prerender/README.md):
+// Records custom page load timing metrics for prerendered page loads.
+class PrerenderPageLoadMetricsObserver
+    : public page_load_metrics::PageLoadMetricsObserver {
+ public:
+  PrerenderPageLoadMetricsObserver() = default;
+
+  // page_load_metrics::PageLoadMetricsObserver implementation:
+  ObservePolicy OnStart(content::NavigationHandle* navigation_handle,
+                        const GURL& currently_committed_url,
+                        bool started_in_foreground) override;
+  ObservePolicy OnPrerenderStart(content::NavigationHandle* navigation_handle,
+                                 const GURL& currently_committed_url) override;
+  void DidActivatePrerenderedPage(
+      content::NavigationHandle* navigation_handle) override;
+  void OnFirstPaintInPage(
+      const page_load_metrics::mojom::PageLoadTiming& timing) override;
+  void OnFirstContentfulPaintInPage(
+      const page_load_metrics::mojom::PageLoadTiming& timing) override;
+  void OnFirstInputInPage(
+      const page_load_metrics::mojom::PageLoadTiming& timing) override;
+  void OnComplete(
+      const page_load_metrics::mojom::PageLoadTiming& timing) override;
+  ObservePolicy FlushMetricsOnAppEnterBackground(
+      const page_load_metrics::mojom::PageLoadTiming& timing) override;
+
+ private:
+  void RecordSessionEndHistograms(
+      const page_load_metrics::mojom::PageLoadTiming& main_frame_timing);
+};
+
+#endif  // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_OBSERVERS_PRERENDER_PAGE_LOAD_METRICS_OBSERVER_H_
diff --git a/components/page_load_metrics/browser/page_load_metrics_embedder_base.cc b/components/page_load_metrics/browser/page_load_metrics_embedder_base.cc
index a7343e8..c664a7f 100644
--- a/components/page_load_metrics/browser/page_load_metrics_embedder_base.cc
+++ b/components/page_load_metrics/browser/page_load_metrics_embedder_base.cc
@@ -11,6 +11,7 @@
 #include "components/page_load_metrics/browser/observers/early_hints_page_load_metrics_observer.h"
 #include "components/page_load_metrics/browser/observers/layout_page_load_metrics_observer.h"
 #include "components/page_load_metrics/browser/observers/prerender_features_page_load_metrics_observer.h"
+#include "components/page_load_metrics/browser/observers/prerender_page_load_metrics_observer.h"
 #include "components/page_load_metrics/browser/observers/use_counter_page_load_metrics_observer.h"
 #include "components/page_load_metrics/browser/page_load_tracker.h"
 
@@ -33,6 +34,7 @@
     tracker->AddObserver(std::make_unique<EarlyHintsPageLoadMetricsObserver>());
     tracker->AddObserver(
         std::make_unique<PrerenderFeaturesPageLoadMetricsObserver>());
+    tracker->AddObserver(std::make_unique<PrerenderPageLoadMetricsObserver>());
   }
   // Allow the embedder to register any embedder-specific observers
   RegisterEmbedderObservers(tracker);
diff --git a/components/page_load_metrics/browser/page_load_metrics_observer.h b/components/page_load_metrics/browser/page_load_metrics_observer.h
index 23a871e..60112779 100644
--- a/components/page_load_metrics/browser/page_load_metrics_observer.h
+++ b/components/page_load_metrics/browser/page_load_metrics_observer.h
@@ -560,8 +560,9 @@
   virtual void DidActivatePortal(base::TimeTicks activation_time) {}
 
   // Called when the page tracked was just activated after being prerendered.
-  // TODO(crbug.com/1190112): Add |activation_time| parameter.
-  virtual void DidActivatePrerenderedPage() {}
+  // |navigation_handle| is for the activation navigation.
+  virtual void DidActivatePrerenderedPage(
+      content::NavigationHandle* navigation_handle) {}
 
   // Called when V8 per-frame memory usage updates are available. Each
   // MemoryUpdate consists of a GlobalRenderFrameHostId and a nonzero int64_t
diff --git a/components/page_load_metrics/browser/page_load_metrics_observer_delegate.h b/components/page_load_metrics/browser/page_load_metrics_observer_delegate.h
index 9592f1a..82b9a66 100644
--- a/components/page_load_metrics/browser/page_load_metrics_observer_delegate.h
+++ b/components/page_load_metrics/browser/page_load_metrics_observer_delegate.h
@@ -77,6 +77,10 @@
   // True if the page load started in the foreground.
   virtual bool StartedInForeground() const = 0;
 
+  // True if the page load was a prerender, that was later activated by a
+  // navigation that started in the foreground.
+  virtual bool WasPrerenderedThenActivatedInForeground() const = 0;
+
   // Whether the page load was initiated by a user.
   virtual const UserInitiatedInfo& GetUserInitiatedInfo() const = 0;
 
diff --git a/components/page_load_metrics/browser/page_load_metrics_test_waiter.cc b/components/page_load_metrics/browser/page_load_metrics_test_waiter.cc
index 0495d6e..5b1d354 100644
--- a/components/page_load_metrics/browser/page_load_metrics_test_waiter.cc
+++ b/components/page_load_metrics/browser/page_load_metrics_test_waiter.cc
@@ -330,7 +330,7 @@
   AddObserver(tracker);
 }
 
-void PageLoadMetricsTestWaiter::OnRestoredFromBackForwardCache(
+void PageLoadMetricsTestWaiter::OnActivate(
     page_load_metrics::PageLoadTracker* tracker) {
   // A PageLoadMetricsWaiter should only wait for events from a single page
   // load.
diff --git a/components/page_load_metrics/browser/page_load_metrics_test_waiter.h b/components/page_load_metrics/browser/page_load_metrics_test_waiter.h
index ba4f0be..0166f67 100644
--- a/components/page_load_metrics/browser/page_load_metrics_test_waiter.h
+++ b/components/page_load_metrics/browser/page_load_metrics_test_waiter.h
@@ -274,8 +274,7 @@
 
   void OnCommit(page_load_metrics::PageLoadTracker* tracker) override;
 
-  void OnRestoredFromBackForwardCache(
-      page_load_metrics::PageLoadTracker* tracker) override;
+  void OnActivate(page_load_metrics::PageLoadTracker* tracker) override;
 
   // These methods check whether expectations are satisfied for specific fields
   // inside the State object, by comparing them in expected_ and observed_.
diff --git a/components/page_load_metrics/browser/page_load_metrics_util.cc b/components/page_load_metrics/browser/page_load_metrics_util.cc
index 9699d60..d7c47c33 100644
--- a/components/page_load_metrics/browser/page_load_metrics_util.cc
+++ b/components/page_load_metrics/browser/page_load_metrics_util.cc
@@ -109,6 +109,14 @@
           event.value() <= delegate.GetFirstBackgroundTime().value());
 }
 
+bool WasActivatedInForegroundOptionalEventInForeground(
+    const absl::optional<base::TimeDelta>& event,
+    const PageLoadMetricsObserverDelegate& delegate) {
+  return delegate.WasPrerenderedThenActivatedInForeground() && event &&
+         (!delegate.GetFirstBackgroundTime() ||
+          event.value() <= delegate.GetFirstBackgroundTime().value());
+}
+
 bool WasStartedInForegroundOptionalEventInForegroundAfterBackForwardCacheRestore(
     const absl::optional<base::TimeDelta>& event,
     const PageLoadMetricsObserverDelegate& delegate,
diff --git a/components/page_load_metrics/browser/page_load_metrics_util.h b/components/page_load_metrics/browser/page_load_metrics_util.h
index 8a62958..e2817f38 100644
--- a/components/page_load_metrics/browser/page_load_metrics_util.h
+++ b/components/page_load_metrics/browser/page_load_metrics_util.h
@@ -103,6 +103,15 @@
     const absl::optional<base::TimeDelta>& event,
     const PageLoadMetricsObserverDelegate& delegate);
 
+// Returns true if:
+// - We have timing information for the event.
+// - The page load was prerendered, and was later activated by a navigation that
+//   started in the foreground.
+// - The event occurred prior to the page being moved to the background.
+bool WasActivatedInForegroundOptionalEventInForeground(
+    const absl::optional<base::TimeDelta>& event,
+    const PageLoadMetricsObserverDelegate& delegate);
+
 bool WasStartedInForegroundOptionalEventInForegroundAfterBackForwardCacheRestore(
     const absl::optional<base::TimeDelta>& event,
     const PageLoadMetricsObserverDelegate& delegate,
diff --git a/components/page_load_metrics/browser/page_load_tracker.cc b/components/page_load_metrics/browser/page_load_tracker.cc
index 5070e18..503113f 100644
--- a/components/page_load_metrics/browser/page_load_tracker.cc
+++ b/components/page_load_metrics/browser/page_load_tracker.cc
@@ -456,11 +456,13 @@
 
 void PageLoadTracker::DidActivatePrerenderedPage(
     content::NavigationHandle* navigation_handle) {
-  if (GetWebContents()->GetVisibility() == content::Visibility::VISIBLE)
+  if (GetWebContents()->GetVisibility() == content::Visibility::VISIBLE) {
+    was_prerendered_then_activated_in_foreground_ = true;
     PageShown();
+  }
 
   for (const auto& observer : observers_)
-    observer->DidActivatePrerenderedPage();
+    observer->DidActivatePrerenderedPage(navigation_handle);
 
   base::UmaHistogramEnumeration(
       internal::kPageLoadPrerender2Event,
@@ -901,6 +903,10 @@
   return started_in_foreground_;
 }
 
+bool PageLoadTracker::WasPrerenderedThenActivatedInForeground() const {
+  return was_prerendered_then_activated_in_foreground_;
+}
+
 const UserInitiatedInfo& PageLoadTracker::GetUserInitiatedInfo() const {
   return user_initiated_info_;
 }
diff --git a/components/page_load_metrics/browser/page_load_tracker.h b/components/page_load_metrics/browser/page_load_tracker.h
index 27be5e66..ec2c4000 100644
--- a/components/page_load_metrics/browser/page_load_tracker.h
+++ b/components/page_load_metrics/browser/page_load_tracker.h
@@ -229,6 +229,7 @@
   const BackForwardCacheRestore& GetBackForwardCacheRestore(
       size_t index) const override;
   bool StartedInForeground() const override;
+  bool WasPrerenderedThenActivatedInForeground() const override;
   const UserInitiatedInfo& GetUserInitiatedInfo() const override;
   const GURL& GetUrl() const override;
   const GURL& GetStartUrl() const override;
@@ -462,6 +463,7 @@
   absl::optional<base::TimeDelta> first_foreground_time_;
   std::vector<BackForwardCacheRestore> back_forward_cache_restores_;
   const bool started_in_foreground_;
+  bool was_prerendered_then_activated_in_foreground_ = false;
 
   mojom::PageLoadTimingPtr last_dispatched_merged_page_timing_;
   blink::MobileFriendliness latest_mobile_friendliness_;
diff --git a/components/page_load_metrics/common/page_load_metrics.mojom b/components/page_load_metrics/common/page_load_metrics.mojom
index 121c700..d4be4d07 100644
--- a/components/page_load_metrics/common/page_load_metrics.mojom
+++ b/components/page_load_metrics/common/page_load_metrics.mojom
@@ -158,6 +158,11 @@
   // from the cache.
   array<BackForwardCacheTiming> back_forward_cache_timings;
 
+  // Time relative to navigation_start that the prerender activation navigation
+  // was initiated. This is set for prerendered page loads that were later
+  // activated.
+  mojo_base.mojom.TimeDelta? activation_start;
+
   // Time between user input and navigation start. This is set for navigations
   // where the input start timing is known; currently when the navigation is
   // initiated by a link click in the renderer, or from the desktop omnibox.
diff --git a/components/page_load_metrics/common/page_load_timing.cc b/components/page_load_metrics/common/page_load_timing.cc
index a480ada..0f20de37 100644
--- a/components/page_load_metrics/common/page_load_timing.cc
+++ b/components/page_load_metrics/common/page_load_timing.cc
@@ -18,7 +18,8 @@
       mojom::ParseTiming::New(),
       std::vector<mojo::StructPtr<mojom::BackForwardCacheTiming>>{},
       absl::optional<base::TimeDelta>(), absl::optional<base::TimeDelta>(),
-      absl::optional<base::TimeDelta>(), absl::optional<base::TimeDelta>());
+      absl::optional<base::TimeDelta>(), absl::optional<base::TimeDelta>(),
+      absl::optional<base::TimeDelta>());
 }
 
 bool IsEmpty(const page_load_metrics::mojom::DocumentTiming& timing) {
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
index 248f1f9f..0089ea55 100644
--- a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
+++ b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
@@ -654,6 +654,8 @@
     timing->paint_timing->portal_activated_paint =
         *perf.LastPortalActivatedPaint();
   }
+  if (perf.PrerenderActivationStart().has_value())
+    timing->activation_start = perf.PrerenderActivationStart();
 
   if (perf.UserTimingMarkFullyLoaded().has_value())
     timing->user_timing_mark_fully_loaded = perf.UserTimingMarkFullyLoaded();
diff --git a/components/password_manager/core/browser/mock_password_store.h b/components/password_manager/core/browser/mock_password_store.h
index 1c81c289..92ae4927 100644
--- a/components/password_manager/core/browser/mock_password_store.h
+++ b/components/password_manager/core/browser/mock_password_store.h
@@ -28,14 +28,6 @@
 
   MOCK_METHOD(void, RemoveLogin, (const PasswordForm&), (override));
   MOCK_METHOD(void,
-              RemoveLoginsByURLAndTime,
-              (const base::RepeatingCallback<bool(const GURL&)>&,
-               base::Time,
-               base::Time,
-               base::OnceClosure,
-               base::OnceCallback<void(bool)>),
-              (override));
-  MOCK_METHOD(void,
               Unblocklist,
               (const PasswordFormDigest&, base::OnceClosure),
               (override));
@@ -98,20 +90,10 @@
               (const std::u16string&),
               (override));
   MOCK_METHOD(DatabaseCleanupResult, DeleteUndecryptableLogins, (), (override));
-  void SetUnsyncedCredentialsDeletionNotifier(
-      std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier)
-      override {
-    NOTIMPLEMENTED();
-  }
   MOCK_METHOD(void,
               NotifyLoginsChanged,
               (const PasswordStoreChangeList&),
               (override));
-  void NotifyDeletionsHaveSynced(bool) override { NOTIMPLEMENTED(); }
-  void NotifyUnsyncedCredentialsWillBeDeleted(
-      std::vector<PasswordForm>) override {
-    NOTIMPLEMENTED();
-  }
   MOCK_METHOD(std::vector<InteractionsStats>,
               GetSiteStatsImpl,
               (const GURL& origin_domain),
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 8689914..dba3371 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -377,7 +377,6 @@
   votes_uploader_.UploadPasswordVote(*parsed_submitted_form_,
                                      *parsed_submitted_form_,
                                      autofill::NOT_NEW_PASSWORD, std::string());
-  votes_uploader_.MaybeSendSingleUsernameVote(false /* credentials_saved */);
 }
 
 void PasswordFormManager::OnNeverClicked() {
@@ -386,8 +385,6 @@
   votes_uploader_.UploadPasswordVote(*parsed_submitted_form_,
                                      *parsed_submitted_form_,
                                      autofill::UNKNOWN_TYPE, std::string());
-
-  votes_uploader_.MaybeSendSingleUsernameVote(false /* credentials_saved */);
   Blocklist();
 }
 
@@ -398,8 +395,6 @@
       *parsed_submitted_form_, *parsed_submitted_form_,
       is_update ? autofill::PROBABLY_NEW_PASSWORD : autofill::UNKNOWN_TYPE,
       std::string());
-
-  votes_uploader_.MaybeSendSingleUsernameVote(false /* credentials_saved */);
 }
 
 void PasswordFormManager::Blocklist() {
diff --git a/components/password_manager/core/browser/password_save_manager_impl.cc b/components/password_manager/core/browser/password_save_manager_impl.cc
index 0a87cbe..498e9fb 100644
--- a/components/password_manager/core/browser/password_save_manager_impl.cc
+++ b/components/password_manager/core/browser/password_save_manager_impl.cc
@@ -537,7 +537,7 @@
     votes_uploader_->UploadPasswordVote(
         parsed_submitted_form, parsed_submitted_form, autofill::NEW_PASSWORD,
         FormStructure(pending_credentials_.form_data).FormSignatureAsStr());
-    votes_uploader_->MaybeSendSingleUsernameVote(true /* credentials_saved */);
+    votes_uploader_->MaybeSendSingleUsernameVote();
   }
 
   if (pending_credentials_.times_used == 1) {
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc
index 8198fb11..6b268fd 100644
--- a/components/password_manager/core/browser/password_store.cc
+++ b/components/password_manager/core/browser/password_store.cc
@@ -130,12 +130,10 @@
     base::OnceClosure completion,
     base::OnceCallback<void(bool)> sync_completion) {
   DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
-  // TODO(crbug.com/1226042): Pass NotifyLoginsChanged as a callback since
-  // PasswordStoreImpl won't call PasswordStore::NotifyLoginsChanged directly
-  // after it inherits PasswordStoreSync.
-  backend_->RemoveLoginsByURLAndTimeAsync(
-      base::NullCallback(), url_filter, delete_begin, delete_end,
-      std::move(completion), std::move(sync_completion));
+  ScheduleTask(base::BindOnce(&PasswordStore::RemoveLoginsByURLAndTimeInternal,
+                              this, url_filter, delete_begin, delete_end,
+                              std::move(completion),
+                              std::move(sync_completion)));
 }
 
 void PasswordStore::RemoveLoginsCreatedBetween(base::Time delete_begin,
@@ -397,6 +395,18 @@
           base::Unretained(this)));
 }
 
+void PasswordStore::SetUnsyncedCredentialsDeletionNotifier(
+    std::unique_ptr<PasswordStore::UnsyncedCredentialsDeletionNotifier>
+        notifier) {
+  DCHECK(!deletion_notifier_);
+  DCHECK(notifier);
+  deletion_notifier_ = std::move(notifier);
+}
+
+void PasswordStore::SetSyncTaskTimeoutForTest(base::TimeDelta timeout) {
+  sync_task_timeout_ = timeout;
+}
+
 PasswordStore::~PasswordStore() {
   DCHECK(shutdown_called_);
 }
@@ -416,12 +426,45 @@
   }
 }
 
+void PasswordStore::NotifyDeletionsHaveSynced(bool success) {
+  DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
+  // Either all deletions have been committed to the Sync server, or Sync is
+  // telling us that it won't commit them (because Sync was turned off
+  // permanently). In either case, run the corresponding callbacks now (on the
+  // main task runner).
+  DCHECK(!success || !GetMetadataStore()->HasUnsyncedDeletions());
+  if (!deletions_have_synced_callbacks_.empty()) {
+    base::UmaHistogramBoolean(
+        "PasswordManager.PasswordStoreDeletionsHaveSynced", success);
+  }
+  for (auto& callback : deletions_have_synced_callbacks_) {
+    main_task_runner_->PostTask(FROM_HERE,
+                                base::BindOnce(std::move(callback), success));
+  }
+  deletions_have_synced_timeout_.Cancel();
+  deletions_have_synced_callbacks_.clear();
+}
+
 void PasswordStore::InvokeAndNotifyAboutInsecureCredentialsChange(
     base::OnceCallback<PasswordStoreChangeList()> callback) {
   DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
   NotifyLoginsChanged(std::move(callback).Run());
 }
 
+void PasswordStore::NotifyUnsyncedCredentialsWillBeDeleted(
+    std::vector<PasswordForm> unsynced_credentials) {
+  DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
+  DCHECK(IsAccountStore());
+  // |deletion_notifier_| only gets set for desktop.
+  if (deletion_notifier_) {
+    main_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &PasswordStore::UnsyncedCredentialsDeletionNotifier::Notify,
+            deletion_notifier_->GetWeakPtr(), std::move(unsynced_credentials)));
+  }
+}
+
 void PasswordStore::OnInitCompleted(bool success) {
   DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
   init_status_ = success ? InitStatus::kSuccess : InitStatus::kFailure;
@@ -528,6 +571,43 @@
   CommitTransaction();
 }
 
+void PasswordStore::RemoveLoginsByURLAndTimeInternal(
+    const base::RepeatingCallback<bool(const GURL&)>& url_filter,
+    base::Time delete_begin,
+    base::Time delete_end,
+    base::OnceClosure completion,
+    base::OnceCallback<void(bool)> sync_completion) {
+  DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
+  TRACE_EVENT0("passwords", "PasswordStore::RemoveLoginsByURLAndTimeInternal");
+  BeginTransaction();
+  PasswordStoreChangeList changes =
+      RemoveLoginsByURLAndTimeImpl(url_filter, delete_begin, delete_end);
+  NotifyLoginsChanged(changes);
+  // Sync metadata get updated in NotifyLoginsChanged(). Therefore,
+  // CommitTransaction() must be called after NotifyLoginsChanged(), because
+  // sync codebase needs to update metadata atomically together with the login
+  // data.
+  CommitTransaction();
+
+  if (completion)
+    main_task_runner_->PostTask(FROM_HERE, std::move(completion));
+
+  if (sync_completion) {
+    deletions_have_synced_callbacks_.push_back(std::move(sync_completion));
+    // Start a timeout for sync, or restart it if it was already running.
+    deletions_have_synced_timeout_.Reset(base::BindOnce(
+        &PasswordStore::NotifyDeletionsHaveSynced, this, /*success=*/false));
+    background_task_runner_->PostDelayedTask(
+        FROM_HERE, deletions_have_synced_timeout_.callback(),
+        sync_task_timeout_);
+
+    // Do an immediate check for the case where there are already no unsynced
+    // deletions.
+    if (!GetMetadataStore()->HasUnsyncedDeletions())
+      NotifyDeletionsHaveSynced(/*success=*/true);
+  }
+}
+
 void PasswordStore::RemoveLoginsCreatedBetweenInternal(
     base::Time delete_begin,
     base::Time delete_end,
diff --git a/components/password_manager/core/browser/password_store.h b/components/password_manager/core/browser/password_store.h
index 9fbeb4a1..98c5c01 100644
--- a/components/password_manager/core/browser/password_store.h
+++ b/components/password_manager/core/browser/password_store.h
@@ -197,9 +197,10 @@
   CreateSyncControllerDelegate();
 
   // Sets |deletion_notifier_|. Must not pass a nullptr.
-  virtual void SetUnsyncedCredentialsDeletionNotifier(
-      std::unique_ptr<UnsyncedCredentialsDeletionNotifier>
-          deletion_notifier) = 0;
+  void SetUnsyncedCredentialsDeletionNotifier(
+      std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier);
+
+  void SetSyncTaskTimeoutForTest(base::TimeDelta timeout);
 
  protected:
   using LoginsTask = base::OnceCallback<LoginsResult()>;
@@ -321,6 +322,11 @@
   // been changed.
   void NotifyLoginsChanged(const PasswordStoreChangeList& changes) override;
 
+  void NotifyDeletionsHaveSynced(bool success) override;
+
+  void NotifyUnsyncedCredentialsWillBeDeleted(
+      std::vector<PasswordForm> unsynced_credentials) override;
+
   // Invokes callback and notifies observers if there was a change to the list
   // of insecure passwords. It also informs Sync about the updated password
   // forms to sync up the changes about insecure credentials.
@@ -390,6 +396,12 @@
   void RemoveLoginInternal(const PasswordForm& form);
   void UpdateLoginWithPrimaryKeyInternal(const PasswordForm& new_form,
                                          const PasswordForm& old_primary_key);
+  void RemoveLoginsByURLAndTimeInternal(
+      const base::RepeatingCallback<bool(const GURL&)>& url_filter,
+      base::Time delete_begin,
+      base::Time delete_end,
+      base::OnceClosure completion,
+      base::OnceCallback<void(bool)> sync_completion);
   void RemoveLoginsCreatedBetweenInternal(base::Time delete_begin,
                                           base::Time delete_end,
                                           base::OnceClosure completion);
@@ -492,10 +504,22 @@
 
   PrefService* prefs_ = nullptr;
 
+  std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier_;
+
+  // A list of callbacks that should be run once all pending deletions have been
+  // sent to the Sync server. Note that the vector itself lives on the
+  // background thread, but the callbacks must be run on the main thread!
+  std::vector<base::OnceCallback<void(bool)>> deletions_have_synced_callbacks_;
+  // Timeout closure that runs if sync takes too long to propagate deletions.
+  base::CancelableOnceClosure deletions_have_synced_timeout_;
+
   bool shutdown_called_ = false;
 
   InitStatus init_status_ = InitStatus::kUnknown;
 
+  // This is usually constant, only changed in tests.
+  base::TimeDelta sync_task_timeout_ = base::TimeDelta::FromSeconds(30);
+
   DISALLOW_COPY_AND_ASSIGN(PasswordStore);
 };
 
diff --git a/components/password_manager/core/browser/password_store_backend.h b/components/password_manager/core/browser/password_store_backend.h
index 2a41ddbb..349d3336 100644
--- a/components/password_manager/core/browser/password_store_backend.h
+++ b/components/password_manager/core/browser/password_store_backend.h
@@ -77,9 +77,7 @@
       OptionalStoreChangeListReply callback,
       const base::RepeatingCallback<bool(const GURL&)>& url_filter,
       base::Time delete_begin,
-      base::Time delete_end,
-      base::OnceClosure completion,
-      base::OnceCallback<void(bool)> sync_completion) = 0;
+      base::Time delete_end) {}
   virtual void RemoveLoginsCreatedBetweenAsync(
       OptionalStoreChangeListReply callback,
       base::Time delete_begin,
diff --git a/components/password_manager/core/browser/password_store_impl.cc b/components/password_manager/core/browser/password_store_impl.cc
index 0365f44..55ecfcf 100644
--- a/components/password_manager/core/browser/password_store_impl.cc
+++ b/components/password_manager/core/browser/password_store_impl.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
-#include "base/metrics/histogram_functions.h"
 #include "components/password_manager/core/browser/password_store_change.h"
 #include "components/password_manager/core/browser/sync/password_sync_bridge.h"
 #include "components/prefs/pref_service.h"
@@ -20,8 +19,6 @@
 
 namespace {
 
-constexpr base::TimeDelta kSyncTaskTimeout = base::TimeDelta::FromSeconds(30);
-
 // Generates PasswordStoreChangeList for affected forms during
 // InsecureCredentials update.
 PasswordStoreChangeList BuildPasswordChangeListForInsecureCredentialsUpdate(
@@ -50,14 +47,6 @@
       base::BindOnce(&PasswordStoreImpl::DestroyOnBackgroundSequence, this));
 }
 
-void PasswordStoreImpl::SetUnsyncedCredentialsDeletionNotifier(
-    std::unique_ptr<PasswordStore::UnsyncedCredentialsDeletionNotifier>
-        notifier) {
-  DCHECK(!deletion_notifier_);
-  DCHECK(notifier);
-  deletion_notifier_ = std::move(notifier);
-}
-
 void PasswordStoreImpl::ReportMetricsImpl(const std::string& sync_username,
                                           bool custom_passphrase_sync_enabled,
                                           BulkCheckDone bulk_check_done) {
@@ -354,39 +343,6 @@
     sync_bridge_->ActOnPasswordStoreChanges(changes);
 }
 
-void PasswordStoreImpl::NotifyDeletionsHaveSynced(bool success) {
-  DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
-  // Either all deletions have been committed to the Sync server, or Sync is
-  // telling us that it won't commit them (because Sync was turned off
-  // permanently). In either case, run the corresponding callbacks now (on the
-  // main task runner).
-  DCHECK(!success || !GetMetadataStore()->HasUnsyncedDeletions());
-  if (!deletions_have_synced_callbacks_.empty()) {
-    base::UmaHistogramBoolean(
-        "PasswordManager.PasswordStoreDeletionsHaveSynced", success);
-  }
-  for (auto& callback : deletions_have_synced_callbacks_) {
-    main_task_runner()->PostTask(FROM_HERE,
-                                 base::BindOnce(std::move(callback), success));
-  }
-  deletions_have_synced_timeout_.Cancel();
-  deletions_have_synced_callbacks_.clear();
-}
-
-void PasswordStoreImpl::NotifyUnsyncedCredentialsWillBeDeleted(
-    std::vector<PasswordForm> unsynced_credentials) {
-  DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
-  DCHECK(IsAccountStore());
-  // |deletion_notifier_| only gets set for desktop.
-  if (deletion_notifier_) {
-    main_task_runner()->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            &PasswordStoreImpl::UnsyncedCredentialsDeletionNotifier::Notify,
-            deletion_notifier_->GetWeakPtr(), std::move(unsynced_credentials)));
-  }
-}
-
 bool PasswordStoreImpl::BeginTransaction() {
   if (login_db_)
     return login_db_->BeginTransaction();
@@ -503,23 +459,6 @@
       std::move(callback));
 }
 
-void PasswordStoreImpl::RemoveLoginsByURLAndTimeAsync(
-    OptionalStoreChangeListReply callback,
-    const base::RepeatingCallback<bool(const GURL&)>& url_filter,
-    base::Time delete_begin,
-    base::Time delete_end,
-    base::OnceClosure completion,
-    base::OnceCallback<void(bool)> sync_completion) {
-  // TODO(crbug.com/1226042): Use PostTaskAndReplyWithResult instead of
-  // PostTask.
-  background_task_runner()->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          IgnoreResult(&PasswordStoreImpl::RemoveLoginsByURLAndTimeInternal),
-          this, url_filter, delete_begin, delete_end, std::move(completion),
-          std::move(sync_completion)));
-}
-
 bool PasswordStoreImpl::InitOnBackgroundSequence(
     base::RepeatingClosure sync_enabled_or_disabled_cb) {
   DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
@@ -634,40 +573,4 @@
   return changes;
 }
 
-PasswordStoreChangeList PasswordStoreImpl::RemoveLoginsByURLAndTimeInternal(
-    const base::RepeatingCallback<bool(const GURL&)>& url_filter,
-    base::Time delete_begin,
-    base::Time delete_end,
-    base::OnceClosure completion,
-    base::OnceCallback<void(bool)> sync_completion) {
-  BeginTransaction();
-  PasswordStoreChangeList changes =
-      RemoveLoginsByURLAndTimeImpl(url_filter, delete_begin, delete_end);
-  NotifyLoginsChanged(changes);
-  // Sync metadata get updated in NotifyLoginsChanged(). Therefore,
-  // CommitTransaction() must be called after NotifyLoginsChanged(), because
-  // sync codebase needs to update metadata atomically together with the login
-  // data.
-  CommitTransaction();
-
-  if (completion)
-    main_task_runner()->PostTask(FROM_HERE, std::move(completion));
-
-  if (sync_completion) {
-    deletions_have_synced_callbacks_.push_back(std::move(sync_completion));
-    // Start a timeout for sync, or restart it if it was already running.
-    deletions_have_synced_timeout_.Reset(
-        base::BindOnce(&PasswordStoreImpl::NotifyDeletionsHaveSynced, this,
-                       /*success=*/false));
-    background_task_runner()->PostDelayedTask(
-        FROM_HERE, deletions_have_synced_timeout_.callback(), kSyncTaskTimeout);
-
-    // Do an immediate check for the case where there are already no unsynced
-    // deletions.
-    if (!GetMetadataStore()->HasUnsyncedDeletions())
-      NotifyDeletionsHaveSynced(/*success=*/true);
-  }
-  return changes;
-}
-
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_impl.h b/components/password_manager/core/browser/password_store_impl.h
index 4d52f00..65c19d4 100644
--- a/components/password_manager/core/browser/password_store_impl.h
+++ b/components/password_manager/core/browser/password_store_impl.h
@@ -37,9 +37,6 @@
   ~PasswordStoreImpl() override;
 
   // Implements PasswordStore interface.
-  void SetUnsyncedCredentialsDeletionNotifier(
-      std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier)
-      override;
   void ReportMetricsImpl(const std::string& sync_username,
                          bool custom_passphrase_sync_enabled,
                          BulkCheckDone bulk_check_done) override;
@@ -101,9 +98,6 @@
       base::span<const InsecureCredential> credentials) override;
   PasswordStoreChangeList RemoveLoginSync(const PasswordForm& form) override;
   void NotifyLoginsChanged(const PasswordStoreChangeList& changes) override;
-  void NotifyDeletionsHaveSynced(bool success) override;
-  void NotifyUnsyncedCredentialsWillBeDeleted(
-      std::vector<PasswordForm> unsynced_credentials) override;
   bool BeginTransaction() override;
   void RollbackTransaction() override;
   bool CommitTransaction() override;
@@ -137,13 +131,6 @@
                         const PasswordForm& form) override;
   void RemoveLoginAsync(OptionalStoreChangeListReply callback,
                         const PasswordForm& form) override;
-  void RemoveLoginsByURLAndTimeAsync(
-      OptionalStoreChangeListReply callback,
-      const base::RepeatingCallback<bool(const GURL&)>& url_filter,
-      base::Time delete_begin,
-      base::Time delete_end,
-      base::OnceClosure completion,
-      base::OnceCallback<void(bool)> sync_completion) override;
 
   // Opens |login_db_| and creates |sync_bridge_| on the background sequence.
   bool InitOnBackgroundSequence(
@@ -165,12 +152,6 @@
   PasswordStoreChangeList AddLoginInternal(const PasswordForm& form);
   PasswordStoreChangeList UpdateLoginInternal(const PasswordForm& form);
   PasswordStoreChangeList RemoveLoginInternal(const PasswordForm& form);
-  PasswordStoreChangeList RemoveLoginsByURLAndTimeInternal(
-      const base::RepeatingCallback<bool(const GURL&)>& url_filter,
-      base::Time delete_begin,
-      base::Time delete_end,
-      base::OnceClosure completion,
-      base::OnceCallback<void(bool)> sync_completion);
 
   // The login SQL database. The LoginDatabase instance is received via the
   // in an uninitialized state, so as to allow injecting mocks, then Init() is
@@ -180,15 +161,6 @@
 
   std::unique_ptr<PasswordSyncBridge> sync_bridge_;
 
-  std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier_;
-
-  // A list of callbacks that should be run once all pending deletions have been
-  // sent to the Sync server. Note that the vector itself lives on the
-  // background thread, but the callbacks must be run on the main thread!
-  std::vector<base::OnceCallback<void(bool)>> deletions_have_synced_callbacks_;
-  // Timeout closure that runs if sync takes too long to propagate deletions.
-  base::CancelableOnceClosure deletions_have_synced_timeout_;
-
   DISALLOW_COPY_AND_ASSIGN(PasswordStoreImpl);
 };
 
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc
index 22ec549..094b803 100644
--- a/components/password_manager/core/browser/test_password_store.cc
+++ b/components/password_manager/core/browser/test_password_store.cc
@@ -210,16 +210,6 @@
       std::move(callback));
 }
 
-void TestPasswordStore::RemoveLoginsByURLAndTimeAsync(
-    OptionalStoreChangeListReply callback,
-    const base::RepeatingCallback<bool(const GURL&)>& url_filter,
-    base::Time delete_begin,
-    base::Time delete_end,
-    base::OnceClosure completion,
-    base::OnceCallback<void(bool)> sync_completion) {
-  NOTIMPLEMENTED();
-}
-
 PasswordStoreChangeList TestPasswordStore::AddLoginImpl(
     const PasswordForm& form,
     AddLoginError* error) {
@@ -457,11 +447,6 @@
   NOTIMPLEMENTED();
 }
 
-void TestPasswordStore::SetUnsyncedCredentialsDeletionNotifier(
-    std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier) {
-  NOTIMPLEMENTED();
-}
-
 PasswordStoreChangeList TestPasswordStore::AddLoginSync(
     const PasswordForm& form,
     AddLoginError* error) {
@@ -495,15 +480,6 @@
   return {};
 }
 
-void TestPasswordStore::NotifyDeletionsHaveSynced(bool success) {
-  NOTIMPLEMENTED();
-}
-
-void TestPasswordStore::NotifyUnsyncedCredentialsWillBeDeleted(
-    std::vector<PasswordForm> unsynced_credentials) {
-  NOTIMPLEMENTED();
-}
-
 bool TestPasswordStore::BeginTransaction() {
   return true;
 }
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h
index 2b73922..5a44298 100644
--- a/components/password_manager/core/browser/test_password_store.h
+++ b/components/password_manager/core/browser/test_password_store.h
@@ -96,13 +96,6 @@
                         const PasswordForm& form) override;
   void RemoveLoginAsync(OptionalStoreChangeListReply callback,
                         const PasswordForm& form) override;
-  void RemoveLoginsByURLAndTimeAsync(
-      OptionalStoreChangeListReply callback,
-      const base::RepeatingCallback<bool(const GURL&)>& url_filter,
-      base::Time delete_begin,
-      base::Time delete_end,
-      base::OnceClosure completion,
-      base::OnceCallback<void(bool)> sync_completion) override;
   // PasswordStore interface
   PasswordStoreChangeList AddLoginImpl(const PasswordForm& form,
                                        AddLoginError* error) override;
@@ -149,9 +142,7 @@
   std::vector<FieldInfo> GetAllFieldInfoImpl() override;
   void RemoveFieldInfoByTimeImpl(base::Time remove_begin,
                                  base::Time remove_end) override;
-  void SetUnsyncedCredentialsDeletionNotifier(
-      std::unique_ptr<UnsyncedCredentialsDeletionNotifier> deletion_notifier)
-      override;
+
   // PasswordStoreSync interface.
   // TODO(crbug.bom/1226042): Remove this after PasswordStore no longer
   // inherits PasswordStoreSync.
@@ -165,9 +156,6 @@
       const PasswordForm& form,
       base::span<const InsecureCredential> credentials) override;
   PasswordStoreChangeList RemoveLoginSync(const PasswordForm& form) override;
-  void NotifyDeletionsHaveSynced(bool success) override;
-  void NotifyUnsyncedCredentialsWillBeDeleted(
-      std::vector<PasswordForm> unsynced_credentials) override;
   bool BeginTransaction() override;
   void RollbackTransaction() override;
   bool CommitTransaction() override;
diff --git a/components/password_manager/core/browser/votes_uploader.cc b/components/password_manager/core/browser/votes_uploader.cc
index 9319c5f..d614cbe8 100644
--- a/components/password_manager/core/browser/votes_uploader.cc
+++ b/components/password_manager/core/browser/votes_uploader.cc
@@ -218,7 +218,7 @@
                          autofill::USERNAME,
                          FormStructure(observed).FormSignatureAsStr());
     }
-    MaybeSendSingleUsernameVote(true /* credentials_saved */);
+    MaybeSendSingleUsernameVote();
   } else {
     SendVoteOnCredentialsReuse(observed, submitted_form, pending_credentials);
   }
@@ -463,7 +463,7 @@
   }
 }
 
-void VotesUploader::MaybeSendSingleUsernameVote(bool credentials_saved) {
+void VotesUploader::MaybeSendSingleUsernameVote() {
   if (!single_username_vote_data_)
     return;
 
@@ -497,8 +497,7 @@
         // The vote for this field has been already sent. Don't send again.
         return;
       }
-      type = credentials_saved &&
-                     username_change_state_ == UsernameChangeState::kUnchanged
+      type = username_change_state_ == UsernameChangeState::kUnchanged
                  ? autofill::SINGLE_USERNAME
                  : autofill::NOT_USERNAME;
       if (username_change_state_ == UsernameChangeState::kChangedToKnownValue)
diff --git a/components/password_manager/core/browser/votes_uploader.h b/components/password_manager/core/browser/votes_uploader.h
index dcbb3fa..88a2c27 100644
--- a/components/password_manager/core/browser/votes_uploader.h
+++ b/components/password_manager/core/browser/votes_uploader.h
@@ -125,13 +125,11 @@
       autofill::FormStructure* form_structure);
 
   // Sends single a username vote if |single_username_vote_data_| is set.
-  // |credentials_saved| equals true if credentials with a single username form
-  // were saved, false if they were not saved.
   // If |single_username_vote_data| is set, the vote sent is either
   // SINGLE_USERNAME (if the user saved the credential with the username
-  // captured from |single_username_vote_data|) or NOT_USERNAME (if the user did
-  // not save the credential or modified the username).
-  void MaybeSendSingleUsernameVote(bool credentials_saved);
+  // captured from |single_username_vote_data|) or NOT_USERNAME (if the user
+  // modified the username).
+  void MaybeSendSingleUsernameVote();
 
   void set_generation_popup_was_shown(bool generation_popup_was_shown) {
     generation_popup_was_shown_ = generation_popup_was_shown;
diff --git a/components/password_manager/core/browser/votes_uploader_unittest.cc b/components/password_manager/core/browser/votes_uploader_unittest.cc
index b1305053..c06133e 100644
--- a/components/password_manager/core/browser/votes_uploader_unittest.cc
+++ b/components/password_manager/core/browser/votes_uploader_unittest.cc
@@ -405,7 +405,7 @@
   EXPECT_CALL(mock_autofill_download_manager_,
               StartUploadRequest(_, _, _, _, _, _))
       .Times(0);
-  votes_uploader.MaybeSendSingleUsernameVote(true /* credentials_saved */);
+  votes_uploader.MaybeSendSingleUsernameVote();
 }
 
 TEST_F(VotesUploaderTest, UploadSingleUsername) {
@@ -440,14 +440,13 @@
     votes_uploader.set_single_username_vote_data(kUsernameRendererId,
                                                  form_predictions);
 
-    ServerFieldTypeSet expected_types = {credentials_saved ? SINGLE_USERNAME
-                                                           : NOT_USERNAME};
+    ServerFieldTypeSet expected_types = {SINGLE_USERNAME};
     EXPECT_CALL(mock_autofill_download_manager_,
                 StartUploadRequest(SignatureIs(kFormSignature), false,
                                    expected_types, std::string(), true,
                                    /* pref_service= */ nullptr));
 
-    votes_uploader.MaybeSendSingleUsernameVote(credentials_saved);
+    votes_uploader.MaybeSendSingleUsernameVote();
   }
 }
 
@@ -491,7 +490,7 @@
                            /*login_form_signature=*/"",
                            /*observed_submission=*/true,
                            /*pref_service=*/nullptr));
-    votes_uploader.MaybeSendSingleUsernameVote(/*credentials_saved=*/true);
+    votes_uploader.MaybeSendSingleUsernameVote();
   }
 }
 
@@ -529,7 +528,7 @@
   EXPECT_CALL(client_, GetFieldInfoManager())
       .WillRepeatedly(Return(&field_info_manager));
 
-  votes_uploader.MaybeSendSingleUsernameVote(true /*  credentials_saved */);
+  votes_uploader.MaybeSendSingleUsernameVote();
   task_environment_.RunUntilIdle();
   store->ShutdownOnUIThread();
 }
@@ -562,7 +561,7 @@
   // Expect no upload, since the vote has been already uploaded.
   EXPECT_CALL(mock_autofill_download_manager_, StartUploadRequest).Times(0);
 
-  votes_uploader.MaybeSendSingleUsernameVote(true /*credentials_saved*/);
+  votes_uploader.MaybeSendSingleUsernameVote();
 }
 
 }  // namespace password_manager
diff --git a/components/policy/core/common/proxy_policy_provider.cc b/components/policy/core/common/proxy_policy_provider.cc
index f8e79d31..4e0ccf4 100644
--- a/components/policy/core/common/proxy_policy_provider.cc
+++ b/components/policy/core/common/proxy_policy_provider.cc
@@ -12,7 +12,7 @@
 
 namespace policy {
 
-ProxyPolicyProvider::ProxyPolicyProvider() : delegate_(NULL) {}
+ProxyPolicyProvider::ProxyPolicyProvider() : delegate_(nullptr) {}
 
 ProxyPolicyProvider::~ProxyPolicyProvider() {
   DCHECK(!delegate_);
@@ -36,7 +36,7 @@
   // Just drop the delegate without propagating updates here.
   if (delegate_) {
     delegate_->RemoveObserver(this);
-    delegate_ = NULL;
+    delegate_ = nullptr;
   }
   ConfigurationPolicyProvider::Shutdown();
 }
diff --git a/components/safe_browsing/content/browser/BUILD.gn b/components/safe_browsing/content/browser/BUILD.gn
index efbac60..1be01a3 100644
--- a/components/safe_browsing/content/browser/BUILD.gn
+++ b/components/safe_browsing/content/browser/BUILD.gn
@@ -77,6 +77,21 @@
     "//net:extras",
     "//services/network/public/mojom",
   ]
+  if (safe_browsing_mode > 0) {
+    sources += [
+      "safe_browsing_navigation_observer.cc",
+      "safe_browsing_navigation_observer.h",
+      "safe_browsing_navigation_observer_manager.cc",
+      "safe_browsing_navigation_observer_manager.h",
+    ]
+
+    deps += [
+      ":safe_browsing_service",
+      "//components/content_settings/core/browser",
+      "//components/page_info",
+      "//components/sessions",
+    ]
+  }
 }
 
 source_set("client_side_model_loader") {
@@ -136,6 +151,17 @@
       "//components/safe_browsing/core/common:safe_browsing_prefs",
     ]
   }
+
+  # TODO(sgurun): enable tests for safe_browsing==2.
+  if (safe_browsing_mode == 1) {
+    sources += [ "safe_browsing_navigation_observer_unittest.cc" ]
+  }
+
+  deps += [
+    "//components/content_settings/core/browser",
+    "//components/sessions",
+    "//components/sync_preferences:test_support",
+  ]
 }
 
 source_set("client_side_detection") {
diff --git a/components/safe_browsing/content/browser/DEPS b/components/safe_browsing/content/browser/DEPS
index 5c7e77c..97a3826 100644
--- a/components/safe_browsing/content/browser/DEPS
+++ b/components/safe_browsing/content/browser/DEPS
@@ -1,11 +1,15 @@
 include_rules = [
   "+components/back_forward_cache",
+  "+components/content_settings/core/common",
   "+components/history/core/browser",
+  "+components/page_info",
   "+components/safe_browsing/core/browser",
   "+components/safe_browsing/core/common",
   "+components/security_interstitials/content",
+  "+components/sessions/content",
   "+components/sessions/core/session_id.h",
   "+content/public/browser",
+  "+content/public/test",
   "+crypto/sha2.h",
   "+ipc/ipc_message.h",
   "+net/cookies",
@@ -18,10 +22,5 @@
   "+services/service_manager/public/cpp",
   "+third_party/blink/public/common/loader/url_loader_throttle.h",
   "+third_party/blink/public/mojom/loader",
+  "+ui/base",
 ]
-
-specific_include_rules = {
-  ".*test\.cc": [
-    "+content/public/test/browser_task_environment.h",
-  ],
-}
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer.cc
similarity index 98%
rename from chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
rename to components/safe_browsing/content/browser/safe_browsing_navigation_observer.cc
index fe88782..2f19c42 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
+++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
 
 #include <memory>
 
 #include "base/time/time.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "components/page_info/page_info_ui.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/global_routing_id.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h b/components/safe_browsing/content/browser/safe_browsing_navigation_observer.h
similarity index 95%
rename from chrome/browser/safe_browsing/safe_browsing_navigation_observer.h
rename to components/safe_browsing/content/browser/safe_browsing_navigation_observer.h
index a6c481d..d743230 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h
+++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
-#define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
+#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
+#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
 
 #include <unordered_map>
 
@@ -174,4 +174,4 @@
 
 }  // namespace safe_browsing
 
-#endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
+#endif  // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_H_
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
similarity index 98%
rename from chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
rename to components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
index 4a08421..524a0a4 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
+++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 
 #include <memory>
 
@@ -13,8 +13,8 @@
 #include "base/rand_util.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h
similarity index 97%
rename from chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h
rename to components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h
index 7b29ab0..5c0a4bb 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h
+++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_
-#define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_
+#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_
+#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_
 
 #include <unordered_map>
 
@@ -362,4 +362,4 @@
 };
 }  // namespace safe_browsing
 
-#endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_
+#endif  // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_NAVIGATION_OBSERVER_MANAGER_H_
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc
similarity index 97%
rename from chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
rename to components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc
index ecf6a6d8..0cab96d7 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
+++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_unittest.cc
@@ -2,14 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h"
 
 #include <memory>
 
 #include "base/test/metrics/histogram_tester.h"
-#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
-#include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/browser/web_contents.h"
@@ -24,11 +23,11 @@
 
 namespace safe_browsing {
 
-class SBNavigationObserverTest : public ChromeRenderViewHostTestHarness {
+class SBNavigationObserverTest : public content::RenderViewHostTestHarness {
  public:
   SBNavigationObserverTest() {}
   void SetUp() override {
-    ChromeRenderViewHostTestHarness::SetUp();
+    content::RenderViewHostTestHarness::SetUp();
     NavigateAndCommit(GURL("http://foo/0"));
 
     HostContentSettingsMap::RegisterProfilePrefs(pref_service_.registry());
@@ -46,7 +45,7 @@
   void TearDown() override {
     delete navigation_observer_;
     settings_map_->ShutdownOnUIThread();
-    ChromeRenderViewHostTestHarness::TearDown();
+    content::RenderViewHostTestHarness::TearDown();
   }
   void VerifyNavigationEvent(
       const GURL& expected_source_url,
@@ -500,8 +499,8 @@
 
   ASSERT_EQ(1, referrer_chain.size());
 
-  EXPECT_EQ("http://b.com/",referrer_chain[0].url());
-  EXPECT_EQ("http://a.com/",referrer_chain[0].referrer_url());
+  EXPECT_EQ("http://b.com/", referrer_chain[0].url());
+  EXPECT_EQ("http://a.com/", referrer_chain[0].referrer_url());
   EXPECT_TRUE(referrer_chain[0].is_retargeting());
 }
 
diff --git a/components/services/storage/indexed_db/scopes/varint_coding.cc b/components/services/storage/indexed_db/scopes/varint_coding.cc
index 95ec469..a24d5cf 100644
--- a/components/services/storage/indexed_db/scopes/varint_coding.cc
+++ b/components/services/storage/indexed_db/scopes/varint_coding.cc
@@ -32,11 +32,10 @@
   int shift = 0;
   uint64_t ret = 0;
   do {
-    if (it == from->end())
+    // Shifting 64 or more bits is undefined behavior.
+    if (it == from->end() || shift >= 64)
       return false;
 
-    // Shifting 64 or more bits is undefined behavior.
-    DCHECK_LT(shift, 64);
     unsigned char c = *it;
     ret |= static_cast<uint64_t>(c & 0x7f) << shift;
     shift += 7;
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
index e987413a..3f39f83 100644
--- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
+++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -1099,7 +1099,7 @@
                              AccountTrackerService::MIGRATION_NOT_STARTED);
 
     ListPrefUpdate update(&pref_service_, prefs::kAccountInfo);
-    update->Clear();
+    update->ClearList();
     auto dict = std::make_unique<base::DictionaryValue>();
     dict->SetString("account_id", email);
     dict->SetString("email", email);
@@ -1162,7 +1162,7 @@
                              AccountTrackerService::MIGRATION_NOT_STARTED);
 
     ListPrefUpdate update(&pref_service_, prefs::kAccountInfo);
-    update->Clear();
+    update->ClearList();
     auto dict = std::make_unique<base::DictionaryValue>();
     dict->SetString("account_id", email1);
     dict->SetString("email", email1);
diff --git a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
index 591c63e..55118ce 100644
--- a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
+++ b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
@@ -361,7 +361,7 @@
   client_prefs->SetInteger(prefs::kAccountIdMigrationState,
                            AccountTrackerService::MIGRATION_NOT_STARTED);
   ListPrefUpdate update(client_prefs, prefs::kAccountInfo);
-  update->Clear();
+  update->ClearList();
   auto dict = std::make_unique<base::DictionaryValue>();
   dict->SetString("account_id", email);
   dict->SetString("email", email);
@@ -394,7 +394,7 @@
   client_prefs->SetInteger(prefs::kAccountIdMigrationState,
                            AccountTrackerService::MIGRATION_NOT_STARTED);
   ListPrefUpdate update(client_prefs, prefs::kAccountInfo);
-  update->Clear();
+  update->ClearList();
   auto dict = std::make_unique<base::DictionaryValue>();
   dict->SetString("account_id", email);
   dict->SetString("email", email);
@@ -427,7 +427,7 @@
   client_prefs->SetInteger(prefs::kAccountIdMigrationState,
                            AccountTrackerService::MIGRATION_NOT_STARTED);
   ListPrefUpdate update(client_prefs, prefs::kAccountInfo);
-  update->Clear();
+  update->ClearList();
   auto dict = std::make_unique<base::DictionaryValue>();
   dict->SetString("account_id", email);
   dict->SetString("email", email);
diff --git a/components/soda/soda_installer.cc b/components/soda/soda_installer.cc
index 6252272..1466b4c 100644
--- a/components/soda/soda_installer.cc
+++ b/components/soda/soda_installer.cc
@@ -178,7 +178,7 @@
 
 void SodaInstaller::UnregisterLanguages(PrefService* global_prefs) {
   ListPrefUpdate update(global_prefs, prefs::kSodaRegisteredLanguagePacks);
-  update->Clear();
+  update->ClearList();
 }
 
 bool SodaInstaller::IsAnyFeatureUsingSodaEnabled(PrefService* prefs) {
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn
index 1d80a91..18fc882e 100644
--- a/components/sync/BUILD.gn
+++ b/components/sync/BUILD.gn
@@ -135,6 +135,7 @@
     "driver/backend_migrator_unittest.cc",
     "driver/data_type_manager_impl_unittest.cc",
     "driver/glue/sync_engine_impl_unittest.cc",
+    "driver/glue/sync_transport_data_prefs_unittest.cc",
     "driver/model_load_manager_unittest.cc",
     "driver/model_type_controller_unittest.cc",
     "driver/passphrase_type_metrics_provider_unittest.cc",
diff --git a/components/sync/base/pref_names.cc b/components/sync/base/pref_names.cc
index b9b4ba0..dab45231 100644
--- a/components/sync/base/pref_names.cc
+++ b/components/sync/base/pref_names.cc
@@ -10,17 +10,6 @@
 
 namespace prefs {
 
-// 64-bit integer serialization of the base::Time when the last sync occurred.
-const char kSyncLastSyncedTime[] = "sync.last_synced_time";
-
-// 64-bit integer serialization of the base::Time of the last sync poll.
-const char kSyncLastPollTime[] = "sync.last_poll_time";
-
-// 64-bit integer serialization of base::TimeDelta storing poll intervals
-// received by the server (in seconds). For historic reasons, this is called
-// "short_poll_interval", but it's worth the hassle to rename it.
-const char kSyncPollIntervalSeconds[] = "sync.short_poll_interval";
-
 // Boolean specifying whether the user finished setting up sync at least once.
 const char kSyncFirstSetupComplete[] = "sync.has_setup_completed";
 
@@ -78,25 +67,12 @@
 // startup so that the user doesn't need to provide credentials on each start.
 const char kSyncEncryptionBootstrapToken[] = "sync.encryption_bootstrap_token";
 
-// Same as kSyncEncryptionBootstrapToken, but derived from the keystore key,
-// so we don't have to do a GetKey command at restart.
-const char kSyncKeystoreEncryptionBootstrapToken[] =
-    "sync.keystore_encryption_bootstrap_token";
-
-const char kSyncGaiaId[] = "sync.gaia_id";
-const char kSyncCacheGuid[] = "sync.cache_guid";
-const char kSyncBirthday[] = "sync.birthday";
-const char kSyncBagOfChips[] = "sync.bag_of_chips";
-
 // Stores whether a platform specific passphrase error prompt has been muted by
 // the user (e.g. an Android system notification). Specifically, it stores which
 // major product version was used to mute this error.
 const char kSyncPassphrasePromptMutedProductVersion[] =
     "sync.passphrase_prompt_muted_product_version";
 
-// Dictionary of last seen invalidation versions for each model type.
-const char kSyncInvalidationVersions[] = "sync.invalidation_versions";
-
 // Enabled the local sync backend implemented by the LoopbackServer.
 const char kEnableLocalSyncBackend[] = "sync.enable_local_sync_backend";
 
diff --git a/components/sync/base/pref_names.h b/components/sync/base/pref_names.h
index 85688a5..9538b77 100644
--- a/components/sync/base/pref_names.h
+++ b/components/sync/base/pref_names.h
@@ -12,9 +12,6 @@
 
 namespace prefs {
 
-extern const char kSyncLastSyncedTime[];
-extern const char kSyncLastPollTime[];
-extern const char kSyncPollIntervalSeconds[];
 extern const char kSyncFirstSetupComplete[];
 extern const char kSyncKeepEverythingSynced[];
 
@@ -42,17 +39,8 @@
 extern const char kSyncRequested[];
 
 extern const char kSyncEncryptionBootstrapToken[];
-extern const char kSyncKeystoreEncryptionBootstrapToken[];
-
-extern const char kSyncGaiaId[];
-extern const char kSyncCacheGuid[];
-extern const char kSyncBirthday[];
-extern const char kSyncBagOfChips[];
-
 extern const char kSyncPassphrasePromptMutedProductVersion[];
 
-extern const char kSyncInvalidationVersions[];
-
 extern const char kEnableLocalSyncBackend[];
 extern const char kLocalSyncBackendDir[];
 
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc
index eccaf67..62e8226 100644
--- a/components/sync/base/sync_prefs.cc
+++ b/components/sync/base/sync_prefs.cc
@@ -7,14 +7,11 @@
 #include <utility>
 #include <vector>
 
-#include "base/base64.h"
 #include "base/bind.h"
 #include "base/check_op.h"
 #include "base/files/file_path.h"
 #include "base/notreached.h"
 #include "base/path_service.h"
-#include "base/rand_util.h"
-#include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "build/chromeos_buildflags.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -41,11 +38,6 @@
 
 }  // namespace
 
-SyncTransportDataPrefs::SyncTransportDataPrefs(PrefService* pref_service)
-    : pref_service_(pref_service) {}
-
-SyncTransportDataPrefs::~SyncTransportDataPrefs() = default;
-
 SyncPrefObserver::~SyncPrefObserver() {}
 
 SyncPrefs::SyncPrefs(PrefService* pref_service) : pref_service_(pref_service) {
@@ -97,20 +89,9 @@
   registry->RegisterStringPref(prefs::kSyncEncryptionBootstrapToken,
                                std::string());
 
-  // Internal or bookkeeping prefs.
-  registry->RegisterStringPref(prefs::kSyncGaiaId, std::string());
-  registry->RegisterStringPref(prefs::kSyncCacheGuid, std::string());
-  registry->RegisterStringPref(prefs::kSyncBirthday, std::string());
-  registry->RegisterStringPref(prefs::kSyncBagOfChips, std::string());
-  registry->RegisterInt64Pref(prefs::kSyncLastSyncedTime, 0);
-  registry->RegisterInt64Pref(prefs::kSyncLastPollTime, 0);
-  registry->RegisterInt64Pref(prefs::kSyncPollIntervalSeconds, 0);
   registry->RegisterBooleanPref(prefs::kSyncManaged, false);
-  registry->RegisterStringPref(prefs::kSyncKeystoreEncryptionBootstrapToken,
-                               std::string());
   registry->RegisterIntegerPref(prefs::kSyncPassphrasePromptMutedProductVersion,
                                 0);
-  registry->RegisterDictionaryPref(prefs::kSyncInvalidationVersions);
   registry->RegisterBooleanPref(prefs::kEnableLocalSyncBackend, false);
   registry->RegisterFilePathPref(prefs::kLocalSyncBackendDir, base::FilePath());
 #if defined(OS_ANDROID)
@@ -134,20 +115,6 @@
   sync_pref_observers_.RemoveObserver(sync_pref_observer);
 }
 
-void SyncTransportDataPrefs::ClearAll() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  pref_service_->ClearPref(prefs::kSyncLastSyncedTime);
-  pref_service_->ClearPref(prefs::kSyncLastPollTime);
-  pref_service_->ClearPref(prefs::kSyncPollIntervalSeconds);
-  pref_service_->ClearPref(prefs::kSyncKeystoreEncryptionBootstrapToken);
-  pref_service_->ClearPref(prefs::kSyncInvalidationVersions);
-  pref_service_->ClearPref(prefs::kSyncGaiaId);
-  pref_service_->ClearPref(prefs::kSyncCacheGuid);
-  pref_service_->ClearPref(prefs::kSyncBirthday);
-  pref_service_->ClearPref(prefs::kSyncBagOfChips);
-}
-
 bool SyncPrefs::IsFirstSetupComplete() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return pref_service_->GetBoolean(prefs::kSyncFirstSetupComplete);
@@ -183,40 +150,6 @@
   }
 }
 
-base::Time SyncTransportDataPrefs::GetLastSyncedTime() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return base::Time::FromInternalValue(
-      pref_service_->GetInt64(prefs::kSyncLastSyncedTime));
-}
-
-void SyncTransportDataPrefs::SetLastSyncedTime(base::Time time) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  pref_service_->SetInt64(prefs::kSyncLastSyncedTime, time.ToInternalValue());
-}
-
-base::Time SyncTransportDataPrefs::GetLastPollTime() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return base::Time::FromInternalValue(
-      pref_service_->GetInt64(prefs::kSyncLastPollTime));
-}
-
-void SyncTransportDataPrefs::SetLastPollTime(base::Time time) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  pref_service_->SetInt64(prefs::kSyncLastPollTime, time.ToInternalValue());
-}
-
-base::TimeDelta SyncTransportDataPrefs::GetPollInterval() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return base::TimeDelta::FromSeconds(
-      pref_service_->GetInt64(prefs::kSyncPollIntervalSeconds));
-}
-
-void SyncTransportDataPrefs::SetPollInterval(base::TimeDelta interval) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  pref_service_->SetInt64(prefs::kSyncPollIntervalSeconds,
-                          interval.InSeconds());
-}
-
 bool SyncPrefs::HasKeepEverythingSynced() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced);
@@ -344,18 +277,6 @@
   pref_service_->ClearPref(prefs::kSyncEncryptionBootstrapToken);
 }
 
-std::string SyncTransportDataPrefs::GetKeystoreEncryptionBootstrapToken()
-    const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return pref_service_->GetString(prefs::kSyncKeystoreEncryptionBootstrapToken);
-}
-
-void SyncTransportDataPrefs::SetKeystoreEncryptionBootstrapToken(
-    const std::string& token) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  pref_service_->SetString(prefs::kSyncKeystoreEncryptionBootstrapToken, token);
-}
-
 // static
 const char* SyncPrefs::GetPrefNameForType(UserSelectableType type) {
   switch (type) {
@@ -419,48 +340,6 @@
   registry->RegisterBooleanPref(pref_name, false);
 }
 
-void SyncTransportDataPrefs::SetGaiaId(const std::string& gaia_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  pref_service_->SetString(prefs::kSyncGaiaId, gaia_id);
-}
-
-std::string SyncTransportDataPrefs::GetGaiaId() const {
-  return pref_service_->GetString(prefs::kSyncGaiaId);
-}
-
-void SyncTransportDataPrefs::SetCacheGuid(const std::string& cache_guid) {
-  pref_service_->SetString(prefs::kSyncCacheGuid, cache_guid);
-}
-
-std::string SyncTransportDataPrefs::GetCacheGuid() const {
-  return pref_service_->GetString(prefs::kSyncCacheGuid);
-}
-
-void SyncTransportDataPrefs::SetBirthday(const std::string& birthday) {
-  pref_service_->SetString(prefs::kSyncBirthday, birthday);
-}
-
-std::string SyncTransportDataPrefs::GetBirthday() const {
-  return pref_service_->GetString(prefs::kSyncBirthday);
-}
-
-void SyncTransportDataPrefs::SetBagOfChips(const std::string& bag_of_chips) {
-  // |bag_of_chips| contains a serialized proto which is not utf-8, hence we use
-  // base64 encoding in prefs.
-  std::string encoded;
-  base::Base64Encode(bag_of_chips, &encoded);
-  pref_service_->SetString(prefs::kSyncBagOfChips, encoded);
-}
-
-std::string SyncTransportDataPrefs::GetBagOfChips() const {
-  // |kSyncBagOfChips| gets stored in base64 because it represents a serialized
-  // proto which is not utf-8 encoding.
-  const std::string encoded = pref_service_->GetString(prefs::kSyncBagOfChips);
-  std::string decoded;
-  base::Base64Decode(encoded, &decoded);
-  return decoded;
-}
-
 #if defined(OS_ANDROID)
 void SyncPrefs::SetDecoupledFromAndroidMasterSync() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -473,37 +352,6 @@
 }
 #endif  // defined(OS_ANDROID)
 
-std::map<ModelType, int64_t> SyncTransportDataPrefs::GetInvalidationVersions()
-    const {
-  std::map<ModelType, int64_t> invalidation_versions;
-  const base::DictionaryValue* invalidation_dictionary =
-      pref_service_->GetDictionary(prefs::kSyncInvalidationVersions);
-  for (ModelType type : ProtocolTypes()) {
-    std::string key = ModelTypeToString(type);
-    std::string version_str;
-    if (!invalidation_dictionary->GetString(key, &version_str))
-      continue;
-    int64_t version = 0;
-    if (!base::StringToInt64(version_str, &version))
-      continue;
-    invalidation_versions[type] = version;
-  }
-  return invalidation_versions;
-}
-
-void SyncTransportDataPrefs::UpdateInvalidationVersions(
-    const std::map<ModelType, int64_t>& invalidation_versions) {
-  std::unique_ptr<base::DictionaryValue> invalidation_dictionary(
-      new base::DictionaryValue());
-  for (const auto& map_iter : invalidation_versions) {
-    std::string version_str = base::NumberToString(map_iter.second);
-    invalidation_dictionary->SetString(ModelTypeToString(map_iter.first),
-                                       version_str);
-  }
-  pref_service_->Set(prefs::kSyncInvalidationVersions,
-                     *invalidation_dictionary);
-}
-
 bool SyncPrefs::IsLocalSyncEnabled() const {
   return local_sync_enabled_;
 }
diff --git a/components/sync/base/sync_prefs.h b/components/sync/base/sync_prefs.h
index 1bf0374..95b3eb5 100644
--- a/components/sync/base/sync_prefs.h
+++ b/components/sync/base/sync_prefs.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include <map>
 #include <memory>
 #include <string>
 
@@ -15,11 +14,9 @@
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/sequence_checker.h"
-#include "base/time/time.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "components/prefs/pref_member.h"
-#include "components/sync/base/model_type.h"
 #include "components/sync/base/user_selectable_type.h"
 
 class PrefRegistrySimple;
@@ -38,61 +35,6 @@
   virtual ~SyncPrefObserver();
 };
 
-// Thin wrapper for "bookkeeping" sync preferences, such as the last synced
-// time, whether the last shutdown was clean, etc. Does *NOT* include sync
-// preferences which are directly user-controlled, such as the set of selected
-// types.
-//
-// In order to use this class SyncPrefs::RegisterProfilePrefs() needs to be
-// invoked first.
-// TODO(crbug.com/938894): Move to dedicated file, possibly next to
-// SyncEngineImpl and introduce a separate pref registration function.
-class SyncTransportDataPrefs {
- public:
-  // |pref_service| must not be null and must outlive this object.
-  explicit SyncTransportDataPrefs(PrefService* pref_service);
-  SyncTransportDataPrefs(const SyncTransportDataPrefs&) = delete;
-  SyncTransportDataPrefs& operator=(const SyncTransportDataPrefs&) = delete;
-  ~SyncTransportDataPrefs();
-
-  // Clears all preferences in this class.
-  void ClearAll();
-
-  void SetGaiaId(const std::string& gaia_id);
-  std::string GetGaiaId() const;
-  void SetCacheGuid(const std::string& cache_guid);
-  std::string GetCacheGuid() const;
-  void SetBirthday(const std::string& birthday);
-  std::string GetBirthday() const;
-  void SetBagOfChips(const std::string& bag_of_chips);
-  std::string GetBagOfChips() const;
-
-  base::Time GetLastSyncedTime() const;
-  void SetLastSyncedTime(base::Time time);
-
-  base::Time GetLastPollTime() const;
-  void SetLastPollTime(base::Time time);
-
-  base::TimeDelta GetPollInterval() const;
-  void SetPollInterval(base::TimeDelta interval);
-
-  // Use this keystore bootstrap token if we're not using an explicit
-  // passphrase.
-  std::string GetKeystoreEncryptionBootstrapToken() const;
-  void SetKeystoreEncryptionBootstrapToken(const std::string& token);
-
-  // Get/set for the last known sync invalidation versions.
-  std::map<ModelType, int64_t> GetInvalidationVersions() const;
-  void UpdateInvalidationVersions(
-      const std::map<ModelType, int64_t>& invalidation_versions);
-
- private:
-  // Never null.
-  PrefService* const pref_service_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
 // SyncPrefs is a helper class that manages getting, setting, and persisting
 // global sync preferences. It is not thread-safe, and lives on the UI thread.
 class SyncPrefs {
diff --git a/components/sync/base/sync_prefs_unittest.cc b/components/sync/base/sync_prefs_unittest.cc
index ec2b2de..b998f763 100644
--- a/components/sync/base/sync_prefs_unittest.cc
+++ b/components/sync/base/sync_prefs_unittest.cc
@@ -6,10 +6,8 @@
 
 #include <memory>
 
-#include "base/command_line.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
-#include "base/time/time.h"
 #include "build/chromeos_buildflags.h"
 #include "components/prefs/pref_notifier_impl.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -44,50 +42,6 @@
   std::unique_ptr<SyncPrefs> sync_prefs_;
 };
 
-class SyncTransportDataPrefsTest : public testing::Test {
- protected:
-  SyncTransportDataPrefsTest() {
-    SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
-    sync_prefs_ = std::make_unique<SyncTransportDataPrefs>(&pref_service_);
-  }
-
-  base::test::SingleThreadTaskEnvironment task_environment_;
-  TestingPrefServiceSimple pref_service_;
-  std::unique_ptr<SyncTransportDataPrefs> sync_prefs_;
-};
-
-// Verify that invalidation versions are persisted and loaded correctly.
-TEST_F(SyncTransportDataPrefsTest, InvalidationVersions) {
-  std::map<ModelType, int64_t> versions;
-  versions[BOOKMARKS] = 10;
-  versions[SESSIONS] = 20;
-  versions[PREFERENCES] = 30;
-
-  sync_prefs_->UpdateInvalidationVersions(versions);
-
-  std::map<ModelType, int64_t> versions2 =
-      sync_prefs_->GetInvalidationVersions();
-
-  EXPECT_EQ(versions.size(), versions2.size());
-  for (auto map_iter : versions2) {
-    EXPECT_EQ(versions[map_iter.first], map_iter.second);
-  }
-}
-
-TEST_F(SyncTransportDataPrefsTest, PollInterval) {
-  EXPECT_TRUE(sync_prefs_->GetPollInterval().is_zero());
-  sync_prefs_->SetPollInterval(base::TimeDelta::FromMinutes(30));
-  EXPECT_FALSE(sync_prefs_->GetPollInterval().is_zero());
-  EXPECT_EQ(sync_prefs_->GetPollInterval().InMinutes(), 30);
-}
-
-TEST_F(SyncTransportDataPrefsTest, LastSyncTime) {
-  EXPECT_EQ(base::Time(), sync_prefs_->GetLastSyncedTime());
-  const base::Time now = base::Time::Now();
-  sync_prefs_->SetLastSyncedTime(now);
-  EXPECT_EQ(now, sync_prefs_->GetLastSyncedTime());
-}
-
 TEST_F(SyncPrefsTest, EncryptionBootstrapToken) {
   EXPECT_TRUE(sync_prefs_->GetEncryptionBootstrapToken().empty());
   sync_prefs_->SetEncryptionBootstrapToken("token");
@@ -151,20 +105,6 @@
 }
 #endif
 
-TEST_F(SyncTransportDataPrefsTest, ClearAll) {
-  sync_prefs_->SetLastSyncedTime(base::Time::Now());
-  sync_prefs_->SetKeystoreEncryptionBootstrapToken("keystore_token");
-
-  ASSERT_NE(base::Time(), sync_prefs_->GetLastSyncedTime());
-  ASSERT_EQ("keystore_token",
-            sync_prefs_->GetKeystoreEncryptionBootstrapToken());
-
-  sync_prefs_->ClearAll();
-
-  EXPECT_EQ(base::Time(), sync_prefs_->GetLastSyncedTime());
-  EXPECT_TRUE(sync_prefs_->GetKeystoreEncryptionBootstrapToken().empty());
-}
-
 TEST_F(SyncPrefsTest, Basic) {
   EXPECT_FALSE(sync_prefs_->IsFirstSetupComplete());
   sync_prefs_->SetFirstSetupComplete();
diff --git a/components/sync/driver/BUILD.gn b/components/sync/driver/BUILD.gn
index 1d02961..60b8b30 100644
--- a/components/sync/driver/BUILD.gn
+++ b/components/sync/driver/BUILD.gn
@@ -25,6 +25,8 @@
     "glue/sync_engine_backend.h",
     "glue/sync_engine_impl.cc",
     "glue/sync_engine_impl.h",
+    "glue/sync_transport_data_prefs.cc",
+    "glue/sync_transport_data_prefs.h",
     "model_load_manager.cc",
     "model_load_manager.h",
     "model_type_controller.cc",
diff --git a/components/sync/driver/data_type_manager_impl.h b/components/sync/driver/data_type_manager_impl.h
index c0793c0..4586eb0 100644
--- a/components/sync/driver/data_type_manager_impl.h
+++ b/components/sync/driver/data_type_manager_impl.h
@@ -172,12 +172,12 @@
   State state_ = DataTypeManager::STOPPED;
 
   // The set of types whose initial download of sync data has completed.
-  // TODO(crbug.com/1170318): This class does not actually handle control types
-  // (i.e. NIGORI) - |controllers_| doesn't contain an entry for NIGORI.
-  // However, we have to pretend that NIGORI is already downloaded (which it
-  // is, but this class doesn't know that) to prevent a re-download on every
-  // browser startup. It would be cleaner to remove all NIGORI/ControlTypes()
-  // handling from this class.
+  // Note: This class mostly doesn't handle control types (i.e. NIGORI) -
+  // |controllers_| doesn't contain an entry for NIGORI, and by the time this
+  // class gets instantiated, NIGORI is already up and running. It still has to
+  // be maintained as part of |downloaded_types_|, however, since in some edge
+  // cases (notably PurgeForMigration()), this class might have to trigger a
+  // re-download of NIGORI data.
   ModelTypeSet downloaded_types_ = ControlTypes();
 
   // Types that requested in current configuration cycle.
diff --git a/components/sync/driver/glue/sync_engine_impl.cc b/components/sync/driver/glue/sync_engine_impl.cc
index e9a8db1..dfa96bb 100644
--- a/components/sync/driver/glue/sync_engine_impl.cc
+++ b/components/sync/driver/glue/sync_engine_impl.cc
@@ -26,6 +26,7 @@
 #include "components/sync/base/sync_prefs.h"
 #include "components/sync/driver/active_devices_provider.h"
 #include "components/sync/driver/glue/sync_engine_backend.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/engine/data_type_activation_response.h"
 #include "components/sync/engine/engine_components_factory.h"
diff --git a/components/sync/driver/glue/sync_engine_impl_unittest.cc b/components/sync/driver/glue/sync_engine_impl_unittest.cc
index 78213ec..2fce1cd 100644
--- a/components/sync/driver/glue/sync_engine_impl_unittest.cc
+++ b/components/sync/driver/glue/sync_engine_impl_unittest.cc
@@ -30,8 +30,8 @@
 #include "components/prefs/testing_pref_service.h"
 #include "components/sync/base/invalidation_helper.h"
 #include "components/sync/base/model_type.h"
-#include "components/sync/base/sync_prefs.h"
 #include "components/sync/driver/active_devices_provider.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/engine/net/http_bridge.h"
 #include "components/sync/engine/sync_manager_factory.h"
@@ -182,7 +182,7 @@
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
-    SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
+    SyncTransportDataPrefs::RegisterProfilePrefs(pref_service_.registry());
 
     ON_CALL(invalidator_, UpdateInterestedTopics)
         .WillByDefault(testing::Return(true));
diff --git a/components/sync/driver/glue/sync_transport_data_prefs.cc b/components/sync/driver/glue/sync_transport_data_prefs.cc
new file mode 100644
index 0000000..9aa9032
--- /dev/null
+++ b/components/sync/driver/glue/sync_transport_data_prefs.cc
@@ -0,0 +1,208 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
+
+#include <utility>
+
+#include "base/base64.h"
+#include "base/rand_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+
+namespace syncer {
+
+namespace {
+
+// 64-bit integer serialization of the base::Time when the last sync occurred.
+const char kSyncLastSyncedTime[] = "sync.last_synced_time";
+
+// 64-bit integer serialization of the base::Time of the last sync poll.
+const char kSyncLastPollTime[] = "sync.last_poll_time";
+
+// 64-bit integer serialization of base::TimeDelta storing poll intervals
+// received by the server (in seconds). For historic reasons, this is called
+// "short_poll_interval", but it's not worth the hassle to rename it.
+const char kSyncPollIntervalSeconds[] = "sync.short_poll_interval";
+
+// Same as kSyncEncryptionBootstrapToken, but derived from the keystore key,
+// so we don't have to do a GetKey command at restart.
+const char kSyncKeystoreEncryptionBootstrapToken[] =
+    "sync.keystore_encryption_bootstrap_token";
+
+const char kSyncGaiaId[] = "sync.gaia_id";
+const char kSyncCacheGuid[] = "sync.cache_guid";
+const char kSyncBirthday[] = "sync.birthday";
+const char kSyncBagOfChips[] = "sync.bag_of_chips";
+
+// Dictionary of last seen invalidation versions for each model type.
+const char kSyncInvalidationVersions[] = "sync.invalidation_versions";
+
+}  // namespace
+
+SyncTransportDataPrefs::SyncTransportDataPrefs(PrefService* pref_service)
+    : pref_service_(pref_service) {}
+
+SyncTransportDataPrefs::~SyncTransportDataPrefs() = default;
+
+// static
+void SyncTransportDataPrefs::RegisterProfilePrefs(
+    PrefRegistrySimple* registry) {
+  registry->RegisterStringPref(kSyncGaiaId, std::string());
+  registry->RegisterStringPref(kSyncCacheGuid, std::string());
+  registry->RegisterStringPref(kSyncBirthday, std::string());
+  registry->RegisterStringPref(kSyncBagOfChips, std::string());
+  registry->RegisterInt64Pref(kSyncLastSyncedTime, 0);
+  registry->RegisterInt64Pref(kSyncLastPollTime, 0);
+  registry->RegisterInt64Pref(kSyncPollIntervalSeconds, 0);
+  registry->RegisterStringPref(kSyncKeystoreEncryptionBootstrapToken,
+                               std::string());
+  registry->RegisterDictionaryPref(kSyncInvalidationVersions);
+}
+
+void SyncTransportDataPrefs::ClearAll() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  pref_service_->ClearPref(kSyncLastSyncedTime);
+  pref_service_->ClearPref(kSyncLastPollTime);
+  pref_service_->ClearPref(kSyncPollIntervalSeconds);
+  pref_service_->ClearPref(kSyncKeystoreEncryptionBootstrapToken);
+  pref_service_->ClearPref(kSyncInvalidationVersions);
+  pref_service_->ClearPref(kSyncGaiaId);
+  pref_service_->ClearPref(kSyncCacheGuid);
+  pref_service_->ClearPref(kSyncBirthday);
+  pref_service_->ClearPref(kSyncBagOfChips);
+}
+
+base::Time SyncTransportDataPrefs::GetLastSyncedTime() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return base::Time::FromDeltaSinceWindowsEpoch(
+      base::TimeDelta::FromMicroseconds(
+          pref_service_->GetInt64(kSyncLastSyncedTime)));
+}
+
+void SyncTransportDataPrefs::SetLastSyncedTime(base::Time time) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  pref_service_->SetInt64(kSyncLastSyncedTime,
+                          time.ToDeltaSinceWindowsEpoch().InMicroseconds());
+}
+
+base::Time SyncTransportDataPrefs::GetLastPollTime() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return base::Time::FromDeltaSinceWindowsEpoch(
+      base::TimeDelta::FromMicroseconds(
+          pref_service_->GetInt64(kSyncLastPollTime)));
+}
+
+void SyncTransportDataPrefs::SetLastPollTime(base::Time time) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  pref_service_->SetInt64(kSyncLastPollTime,
+                          time.ToDeltaSinceWindowsEpoch().InMicroseconds());
+}
+
+base::TimeDelta SyncTransportDataPrefs::GetPollInterval() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return base::TimeDelta::FromSeconds(
+      pref_service_->GetInt64(kSyncPollIntervalSeconds));
+}
+
+void SyncTransportDataPrefs::SetPollInterval(base::TimeDelta interval) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  pref_service_->SetInt64(kSyncPollIntervalSeconds, interval.InSeconds());
+}
+
+std::string SyncTransportDataPrefs::GetKeystoreEncryptionBootstrapToken()
+    const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return pref_service_->GetString(kSyncKeystoreEncryptionBootstrapToken);
+}
+
+void SyncTransportDataPrefs::SetKeystoreEncryptionBootstrapToken(
+    const std::string& token) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  pref_service_->SetString(kSyncKeystoreEncryptionBootstrapToken, token);
+}
+
+void SyncTransportDataPrefs::SetGaiaId(const std::string& gaia_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  pref_service_->SetString(kSyncGaiaId, gaia_id);
+}
+
+std::string SyncTransportDataPrefs::GetGaiaId() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return pref_service_->GetString(kSyncGaiaId);
+}
+
+void SyncTransportDataPrefs::SetCacheGuid(const std::string& cache_guid) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  pref_service_->SetString(kSyncCacheGuid, cache_guid);
+}
+
+std::string SyncTransportDataPrefs::GetCacheGuid() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return pref_service_->GetString(kSyncCacheGuid);
+}
+
+void SyncTransportDataPrefs::SetBirthday(const std::string& birthday) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  pref_service_->SetString(kSyncBirthday, birthday);
+}
+
+std::string SyncTransportDataPrefs::GetBirthday() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return pref_service_->GetString(kSyncBirthday);
+}
+
+void SyncTransportDataPrefs::SetBagOfChips(const std::string& bag_of_chips) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // |bag_of_chips| contains a serialized proto which is not utf-8, hence we use
+  // base64 encoding in prefs.
+  std::string encoded;
+  base::Base64Encode(bag_of_chips, &encoded);
+  pref_service_->SetString(kSyncBagOfChips, encoded);
+}
+
+std::string SyncTransportDataPrefs::GetBagOfChips() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // |kSyncBagOfChips| gets stored in base64 because it represents a serialized
+  // proto which is not utf-8 encoding.
+  const std::string encoded = pref_service_->GetString(kSyncBagOfChips);
+  std::string decoded;
+  base::Base64Decode(encoded, &decoded);
+  return decoded;
+}
+
+std::map<ModelType, int64_t> SyncTransportDataPrefs::GetInvalidationVersions()
+    const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  std::map<ModelType, int64_t> invalidation_versions;
+  const base::DictionaryValue* invalidation_dictionary =
+      pref_service_->GetDictionary(kSyncInvalidationVersions);
+  for (ModelType type : ProtocolTypes()) {
+    std::string key = ModelTypeToString(type);
+    std::string version_str;
+    if (!invalidation_dictionary->GetString(key, &version_str))
+      continue;
+    int64_t version = 0;
+    if (!base::StringToInt64(version_str, &version))
+      continue;
+    invalidation_versions[type] = version;
+  }
+  return invalidation_versions;
+}
+
+void SyncTransportDataPrefs::UpdateInvalidationVersions(
+    const std::map<ModelType, int64_t>& invalidation_versions) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  auto invalidation_dictionary = std::make_unique<base::DictionaryValue>();
+  for (const auto& map_iter : invalidation_versions) {
+    std::string version_str = base::NumberToString(map_iter.second);
+    invalidation_dictionary->SetString(ModelTypeToString(map_iter.first),
+                                       version_str);
+  }
+  pref_service_->Set(kSyncInvalidationVersions, *invalidation_dictionary);
+}
+
+}  // namespace syncer
diff --git a/components/sync/driver/glue/sync_transport_data_prefs.h b/components/sync/driver/glue/sync_transport_data_prefs.h
new file mode 100644
index 0000000..ecb26a3
--- /dev/null
+++ b/components/sync/driver/glue/sync_transport_data_prefs.h
@@ -0,0 +1,77 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SYNC_DRIVER_GLUE_SYNC_TRANSPORT_DATA_PREFS_H_
+#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_TRANSPORT_DATA_PREFS_H_
+
+#include <map>
+#include <string>
+
+#include "base/sequence_checker.h"
+#include "base/time/time.h"
+#include "components/prefs/pref_member.h"
+#include "components/sync/base/model_type.h"
+
+class PrefRegistrySimple;
+class PrefService;
+
+namespace syncer {
+
+// Thin wrapper for "bookkeeping" sync preferences, such as the last synced
+// time, whether the last shutdown was clean, etc. Does *NOT* include sync
+// preferences which are directly user-controlled, such as the set of selected
+// types.
+//
+// In order to use this class RegisterProfilePrefs() needs to be invoked first.
+class SyncTransportDataPrefs {
+ public:
+  static void RegisterProfilePrefs(PrefRegistrySimple* registry);
+
+  // |pref_service| must not be null and must outlive this object.
+  explicit SyncTransportDataPrefs(PrefService* pref_service);
+  SyncTransportDataPrefs(const SyncTransportDataPrefs&) = delete;
+  SyncTransportDataPrefs& operator=(const SyncTransportDataPrefs&) = delete;
+  ~SyncTransportDataPrefs();
+
+  // Clears all preferences in this class.
+  void ClearAll();
+
+  void SetGaiaId(const std::string& gaia_id);
+  std::string GetGaiaId() const;
+  void SetCacheGuid(const std::string& cache_guid);
+  std::string GetCacheGuid() const;
+  void SetBirthday(const std::string& birthday);
+  std::string GetBirthday() const;
+  void SetBagOfChips(const std::string& bag_of_chips);
+  std::string GetBagOfChips() const;
+
+  base::Time GetLastSyncedTime() const;
+  void SetLastSyncedTime(base::Time time);
+
+  base::Time GetLastPollTime() const;
+  void SetLastPollTime(base::Time time);
+
+  base::TimeDelta GetPollInterval() const;
+  void SetPollInterval(base::TimeDelta interval);
+
+  // Use this keystore bootstrap token if we're not using an explicit
+  // passphrase.
+  std::string GetKeystoreEncryptionBootstrapToken() const;
+  void SetKeystoreEncryptionBootstrapToken(const std::string& token);
+
+  // Get/set for the last known sync invalidation versions.
+  std::map<ModelType, int64_t> GetInvalidationVersions() const;
+  void UpdateInvalidationVersions(
+      const std::map<ModelType, int64_t>& invalidation_versions);
+
+ private:
+  // Never null.
+  PrefService* const pref_service_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+};
+
+}  // namespace syncer
+
+#endif  // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_TRANSPORT_DATA_PREFS_H_
diff --git a/components/sync/driver/glue/sync_transport_data_prefs_unittest.cc b/components/sync/driver/glue/sync_transport_data_prefs_unittest.cc
new file mode 100644
index 0000000..0120e51c
--- /dev/null
+++ b/components/sync/driver/glue/sync_transport_data_prefs_unittest.cc
@@ -0,0 +1,77 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
+
+#include <memory>
+
+#include "base/time/time.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace syncer {
+
+namespace {
+
+class SyncTransportDataPrefsTest : public testing::Test {
+ protected:
+  SyncTransportDataPrefsTest() {
+    SyncTransportDataPrefs::RegisterProfilePrefs(pref_service_.registry());
+    sync_prefs_ = std::make_unique<SyncTransportDataPrefs>(&pref_service_);
+  }
+
+  TestingPrefServiceSimple pref_service_;
+  std::unique_ptr<SyncTransportDataPrefs> sync_prefs_;
+};
+
+// Verify that invalidation versions are persisted and loaded correctly.
+TEST_F(SyncTransportDataPrefsTest, InvalidationVersions) {
+  std::map<ModelType, int64_t> versions;
+  versions[BOOKMARKS] = 10;
+  versions[SESSIONS] = 20;
+  versions[PREFERENCES] = 30;
+
+  sync_prefs_->UpdateInvalidationVersions(versions);
+
+  std::map<ModelType, int64_t> versions2 =
+      sync_prefs_->GetInvalidationVersions();
+
+  EXPECT_EQ(versions.size(), versions2.size());
+  for (auto map_iter : versions2) {
+    EXPECT_EQ(versions[map_iter.first], map_iter.second);
+  }
+}
+
+TEST_F(SyncTransportDataPrefsTest, PollInterval) {
+  EXPECT_TRUE(sync_prefs_->GetPollInterval().is_zero());
+  sync_prefs_->SetPollInterval(base::TimeDelta::FromMinutes(30));
+  EXPECT_FALSE(sync_prefs_->GetPollInterval().is_zero());
+  EXPECT_EQ(sync_prefs_->GetPollInterval().InMinutes(), 30);
+}
+
+TEST_F(SyncTransportDataPrefsTest, LastSyncTime) {
+  EXPECT_EQ(base::Time(), sync_prefs_->GetLastSyncedTime());
+  const base::Time now = base::Time::Now();
+  sync_prefs_->SetLastSyncedTime(now);
+  EXPECT_EQ(now, sync_prefs_->GetLastSyncedTime());
+}
+
+TEST_F(SyncTransportDataPrefsTest, ClearAll) {
+  sync_prefs_->SetLastSyncedTime(base::Time::Now());
+  sync_prefs_->SetKeystoreEncryptionBootstrapToken("keystore_token");
+
+  ASSERT_NE(base::Time(), sync_prefs_->GetLastSyncedTime());
+  ASSERT_EQ("keystore_token",
+            sync_prefs_->GetKeystoreEncryptionBootstrapToken());
+
+  sync_prefs_->ClearAll();
+
+  EXPECT_EQ(base::Time(), sync_prefs_->GetLastSyncedTime());
+  EXPECT_TRUE(sync_prefs_->GetKeystoreEncryptionBootstrapToken().empty());
+}
+
+}  // namespace
+
+}  // namespace syncer
diff --git a/components/sync/driver/sync_service_utils.cc b/components/sync/driver/sync_service_utils.cc
index c1fe172..66284c2 100644
--- a/components/sync/driver/sync_service_utils.cc
+++ b/components/sync/driver/sync_service_utils.cc
@@ -74,7 +74,7 @@
   return UploadState::NOT_ACTIVE;
 }
 
-void RecordKeyRetrievalTrigger(KeyRetrievalTriggerForUMA trigger) {
+void RecordKeyRetrievalTrigger(TrustedVaultUserActionTriggerForUMA trigger) {
   base::UmaHistogramEnumeration("Sync.TrustedVaultKeyRetrievalTrigger",
                                 trigger);
 }
diff --git a/components/sync/driver/sync_service_utils.h b/components/sync/driver/sync_service_utils.h
index 50126cb..11a0134b 100644
--- a/components/sync/driver/sync_service_utils.h
+++ b/components/sync/driver/sync_service_utils.h
@@ -40,7 +40,7 @@
 // Used for UMA histogram, do not reorder. Represents the UI elements which
 // contain trusted vault error button.
 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.sync
-enum class KeyRetrievalTriggerForUMA {
+enum class TrustedVaultUserActionTriggerForUMA {
   // Settings pages, used on all platforms except ChromeOS.
   kSettings,
   // Used on desktop platform only.
@@ -60,7 +60,7 @@
 UploadState GetUploadToGoogleState(const SyncService* sync_service,
                                    ModelType type);
 
-void RecordKeyRetrievalTrigger(KeyRetrievalTriggerForUMA trigger);
+void RecordKeyRetrievalTrigger(TrustedVaultUserActionTriggerForUMA trigger);
 
 // Whether the user should be offered to opt in to trusted vault encryption.
 bool ShouldOfferTrustedVaultOptIn(const SyncService* service);
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index a1fd14a..2fa9eba 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -1007,7 +1007,7 @@
     const AccountId& account_id,
     bool notify) {
   ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsersPref);
-  prefs_users_update->Clear();
+  prefs_users_update->ClearList();
   User* user = nullptr;
   for (UserList::iterator it = users_.begin(); it != users_.end();) {
     if ((*it)->GetAccountId() == account_id) {
diff --git a/components/variations/BUILD.gn b/components/variations/BUILD.gn
index 5a86672..e7fe68a77 100644
--- a/components/variations/BUILD.gn
+++ b/components/variations/BUILD.gn
@@ -178,6 +178,7 @@
     "field_trial_config:field_trial_config",
     "proto",
     "//base/test:test_support",
+    "//third_party/zlib/google:compression_utils",
   ]
 }
 
diff --git a/components/variations/variations_test_utils.cc b/components/variations/variations_test_utils.cc
index af1620c..577f2ef 100644
--- a/components/variations/variations_test_utils.cc
+++ b/components/variations/variations_test_utils.cc
@@ -10,6 +10,7 @@
 #include "components/variations/proto/client_variations.pb.h"
 #include "components/variations/variations_associated_data.h"
 #include "components/variations/variations_switches.h"
+#include "third_party/zlib/google/compression_utils.h"
 
 namespace variations {
 
@@ -24,6 +25,20 @@
     "MEQCIDD1IVxjzWYncun+9IGzqYjZvqxxujQEayJULTlbTGA/AiAr0oVmEgVUQZBYq5VLOSvy"
     "96JkMYgzTkHPwbv7K/CmgA==";
 
+const char kTestSeedStudyName[] = "UMA-Uniformity-Trial-10-Percent";
+
+std::string GetTestSeedForPrefs() {
+  std::string serialized_seed;
+  base::Base64Decode(kUncompressedBase64TestSeedData, &serialized_seed);
+
+  std::string compressed_seed_data;
+  compression::GzipCompress(serialized_seed, &compressed_seed_data);
+
+  std::string base64_seed_data;
+  base::Base64Encode(compressed_seed_data, &base64_seed_data);
+  return base64_seed_data;
+}
+
 void DisableTestingConfig() {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       switches::kDisableFieldTrialTestingConfig);
diff --git a/components/variations/variations_test_utils.h b/components/variations/variations_test_utils.h
index 5e8d20e..3dc343f 100644
--- a/components/variations/variations_test_utils.h
+++ b/components/variations/variations_test_utils.h
@@ -16,9 +16,15 @@
 
 // The below seed and signature pair were generated using the server's private
 // key.
-// TODO(crbug/1220163): Describe the contents of the test seed.
+//
+// The seed contains one study, "UMA-Uniformity-Trial-10-Percent", and ten
+// equally weighted groups: "default" and "group_01" through "group_09".
 extern const char kUncompressedBase64TestSeedData[];
 extern const char kBase64TestSeedSignature[];
+extern const char kTestSeedStudyName[];
+
+// Returns a base64-encoded compressed serialized form of a VariationsSeed.
+std::string GetTestSeedForPrefs();
 
 // Disables the use of the field trial testing config to exercise
 // VariationsFieldTrialCreator::CreateTrialsFromSeed().
diff --git a/content/BUILD.gn b/content/BUILD.gn
index b8a3d36..7ca3a8d 100644
--- a/content/BUILD.gn
+++ b/content/BUILD.gn
@@ -120,6 +120,7 @@
   ]
   deps = [
     "//gpu/ipc/common:vulkan_interface_webui_js",
+    "//ui/gfx/geometry/mojom:mojom_js",
     "//url/mojom:url_mojom_origin_js",
     "//url/mojom:url_mojom_origin_webui_js",
   ]
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 458bed2..56f159a 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -274,6 +274,7 @@
   MDDH_INVALID_ALL_ORIGINS_PERMITTED = 246,
   MDDH_INVALID_PERMITTED_ORIGIN = 247,
   MDDH_NOT_TOP_LEVEL = 248,
+  RFH_DID_CHANGE_IFRAME_ATTRIBUTE = 249,
 
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/client_hints/client_hints.cc b/content/browser/client_hints/client_hints.cc
index a46d524..0f47772 100644
--- a/content/browser/client_hints/client_hints.cc
+++ b/content/browser/client_hints/client_hints.cc
@@ -748,7 +748,7 @@
 }
 
 absl::optional<std::vector<network::mojom::WebClientHintsType>>
-ParseAndPersistAcceptCHForNagivation(
+ParseAndPersistAcceptCHForNavigation(
     const GURL& url,
     const ::network::mojom::ParsedHeadersPtr& headers,
     BrowserContext* context,
diff --git a/content/browser/client_hints/client_hints.h b/content/browser/client_hints/client_hints.h
index 13f1a2d..9c0bccd1 100644
--- a/content/browser/client_hints/client_hints.h
+++ b/content/browser/client_hints/client_hints.h
@@ -83,7 +83,7 @@
 // policy is off and there is no valid Accept-CH-Lifetime, where the header
 // still applies locally within frame.
 CONTENT_EXPORT absl::optional<std::vector<network::mojom::WebClientHintsType>>
-ParseAndPersistAcceptCHForNagivation(
+ParseAndPersistAcceptCHForNavigation(
     const GURL& url,
     const ::network::mojom::ParsedHeadersPtr& headers,
     BrowserContext* context,
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index e54cd0c..87761ef 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1444,9 +1444,6 @@
     case WebSchedulerTrackedFeature::kOutstandingIndexedDBTransaction:
       return Page::BackForwardCacheNotRestoredReasonEnum::
           OutstandingIndexedDBTransaction;
-    case WebSchedulerTrackedFeature::kRequestedGeolocationPermission:
-      return Page::BackForwardCacheNotRestoredReasonEnum::
-          RequestedGeolocationPermission;
     case WebSchedulerTrackedFeature::kRequestedNotificationsPermission:
       return Page::BackForwardCacheNotRestoredReasonEnum::
           RequestedNotificationsPermission;
@@ -1592,7 +1589,6 @@
     case WebSchedulerTrackedFeature::kContainsPlugins:
     case WebSchedulerTrackedFeature::kOutstandingNetworkRequestOthers:
     case WebSchedulerTrackedFeature::kOutstandingIndexedDBTransaction:
-    case WebSchedulerTrackedFeature::kRequestedGeolocationPermission:
     case WebSchedulerTrackedFeature::kRequestedNotificationsPermission:
     case WebSchedulerTrackedFeature::kRequestedMIDIPermission:
     case WebSchedulerTrackedFeature::kRequestedAudioCapturePermission:
diff --git a/content/browser/media/media_internals.cc b/content/browser/media/media_internals.cc
index 80d5d2b..c98cf6e 100644
--- a/content/browser/media/media_internals.cc
+++ b/content/browser/media/media_internals.cc
@@ -540,7 +540,7 @@
                                  media::VideoCaptureFormats>>&
         descriptors_and_formats) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  video_capture_capabilities_cached_data_.Clear();
+  video_capture_capabilities_cached_data_.ClearList();
 
   for (const auto& device_format_pair : descriptors_and_formats) {
     base::ListValue control_support;
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
index 095a93f..12a029d 100644
--- a/content/browser/navigation_browsertest.cc
+++ b/content/browser/navigation_browsertest.cc
@@ -5691,4 +5691,122 @@
   EXPECT_EQ(redirection_url, web_contents()->GetLastCommittedURL());
 }
 
+class NavigationBrowserTestAnonymousIframe : public NavigationBrowserTest {
+ public:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    NavigationBrowserTest::SetUpCommandLine(command_line);
+
+    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
+                                    "AnonymousIframe");
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTestAnonymousIframe,
+                       AnonymousAttributeIsHonoredByNavigation) {
+  GURL main_url = embedded_test_server()->GetURL("/page_with_iframe.html");
+  GURL iframe_url_1 = embedded_test_server()->GetURL("/title1.html");
+  GURL iframe_url_2 = embedded_test_server()->GetURL("/title2.html");
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  // The main page has a child iframe with url `iframe_url_1`.
+  EXPECT_EQ(1U, main_frame()->child_count());
+  FrameTreeNode* child = main_frame()->child_at(0);
+  EXPECT_EQ(iframe_url_1, child->current_url());
+  EXPECT_FALSE(child->anonymous());
+  EXPECT_FALSE(child->current_frame_host()->anonymous());
+
+  // Changes to the iframe 'anonymous' attribute are propagated to the
+  // FrameTreeNode. The RenderFrameHost, however, is updated only on navigation.
+  EXPECT_TRUE(
+      ExecJs(main_frame(),
+             "document.getElementById('test_iframe').anonymous = true;"));
+  EXPECT_TRUE(child->anonymous());
+  EXPECT_FALSE(child->current_frame_host()->anonymous());
+
+  // Create a grandchild iframe.
+  EXPECT_TRUE(ExecJs(
+      child, JsReplace("let grandchild = document.createElement('iframe');"
+                       "grandchild.src = $1;"
+                       "document.body.appendChild(grandchild);",
+                       iframe_url_2)));
+  WaitForLoadStop(web_contents());
+  EXPECT_EQ(1U, child->child_count());
+  FrameTreeNode* grandchild = child->child_at(0);
+
+  // The grandchild FrameTreeNode does not set the 'anonymous' attribute. The
+  // grandchild RenderFrameHost is not anonymous, since its parent
+  // RenderFrameHost is not anonymous.
+  EXPECT_FALSE(grandchild->anonymous());
+  EXPECT_FALSE(grandchild->current_frame_host()->anonymous());
+
+  // Navigate the child iframe same-document. This does not change anything.
+  EXPECT_TRUE(ExecJs(main_frame(),
+                     JsReplace("document.getElementById('test_iframe')"
+                               "        .contentWindow.location.href = $1;",
+                               iframe_url_1.Resolve("#here").spec())));
+  WaitForLoadStop(web_contents());
+  EXPECT_TRUE(child->anonymous());
+  EXPECT_FALSE(child->current_frame_host()->anonymous());
+
+  // Now navigate the child iframe cross-document.
+  EXPECT_TRUE(ExecJs(
+      main_frame(), JsReplace("document.getElementById('test_iframe').src = $1",
+                              iframe_url_2)));
+  WaitForLoadStop(web_contents());
+  EXPECT_TRUE(child->anonymous());
+  EXPECT_TRUE(child->current_frame_host()->anonymous());
+
+  // Create a grandchild iframe.
+  EXPECT_TRUE(ExecJs(
+      child, JsReplace("let grandchild = document.createElement('iframe');"
+                       "grandchild.id = 'grandchild_iframe';"
+                       "document.body.appendChild(grandchild);",
+                       iframe_url_1)));
+  EXPECT_EQ(1U, child->child_count());
+  grandchild = child->child_at(0);
+
+  // The grandchild does not set the 'anonymous' attribute, but the grandchild
+  // document is anonymous.
+  EXPECT_FALSE(grandchild->anonymous());
+  EXPECT_TRUE(grandchild->current_frame_host()->anonymous());
+
+  // Now navigate the grandchild iframe.
+  EXPECT_TRUE(ExecJs(
+      child, JsReplace("document.getElementById('grandchild_iframe').src = $1",
+                       iframe_url_2)));
+  WaitForLoadStop(web_contents());
+  EXPECT_TRUE(grandchild->current_frame_host()->anonymous());
+
+  // Remove the 'anonymous' attribute from the iframe. This propagates to the
+  // FrameTreeNode. The RenderFrameHost, however, is updated only on navigation.
+  EXPECT_TRUE(
+      ExecJs(main_frame(),
+             "document.getElementById('test_iframe').anonymous = false;"));
+  EXPECT_FALSE(child->anonymous());
+  EXPECT_TRUE(child->current_frame_host()->anonymous());
+
+  // Create another grandchild iframe. Even if the parent iframe element does
+  // not have the 'anonymous' attribute anymore, the grandchild document is
+  // still loaded inside of an anonymous RenderFrameHost, so it will be
+  // anonymous.
+  EXPECT_TRUE(ExecJs(
+      child, JsReplace("let grandchild2 = document.createElement('iframe');"
+                       "document.body.appendChild(grandchild2);",
+                       iframe_url_1)));
+  EXPECT_EQ(2U, child->child_count());
+  FrameTreeNode* grandchild2 = child->child_at(1);
+  EXPECT_FALSE(grandchild2->anonymous());
+  EXPECT_TRUE(grandchild2->current_frame_host()->anonymous());
+
+  // Navigate the child iframe. Since the iframe element does not set the
+  // 'anonymous' attribute, the resulting RenderFrameHost will not be anonymous.
+  EXPECT_TRUE(
+      ExecJs(main_frame(),
+             JsReplace("document.getElementById('test_iframe').src = $1;",
+                       iframe_url_2)));
+  WaitForLoadStop(web_contents());
+  EXPECT_FALSE(child->anonymous());
+  EXPECT_FALSE(child->current_frame_host()->anonymous());
+}
+
 }  // namespace content
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc
index 0e08735..7254aad 100644
--- a/content/browser/permissions/permission_controller_impl.cc
+++ b/content/browser/permissions/permission_controller_impl.cc
@@ -25,9 +25,6 @@
 absl::optional<blink::scheduler::WebSchedulerTrackedFeature>
 PermissionToSchedulingFeature(PermissionType permission_name) {
   switch (permission_name) {
-    case PermissionType::GEOLOCATION:
-      return blink::scheduler::WebSchedulerTrackedFeature::
-          kRequestedGeolocationPermission;
     case PermissionType::NOTIFICATIONS:
       return blink::scheduler::WebSchedulerTrackedFeature::
           kRequestedNotificationsPermission;
@@ -68,6 +65,7 @@
     case PermissionType::FONT_ACCESS:
     case PermissionType::DISPLAY_CAPTURE:
     case PermissionType::FILE_HANDLING:
+    case PermissionType::GEOLOCATION:
       return absl::nullopt;
   }
 }
diff --git a/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc b/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
index fb946d6e..d82151b3 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
+++ b/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
@@ -629,9 +629,6 @@
         resolve.bind(this, "failure"))
       });
   )"));
-  EXPECT_TRUE(main_frame->scheduler_tracked_features().Has(
-      blink::scheduler::WebSchedulerTrackedFeature::
-          kRequestedGeolocationPermission));
 }
 
 class RecordBackForwardCacheMetricsWithoutEnabling
diff --git a/content/browser/renderer_host/frame_tree_browsertest.cc b/content/browser/renderer_host/frame_tree_browsertest.cc
index 8eafc67c..03efd65a 100644
--- a/content/browser/renderer_host/frame_tree_browsertest.cc
+++ b/content/browser/renderer_host/frame_tree_browsertest.cc
@@ -1425,4 +1425,54 @@
             DepictFrameTree(*root));
 }
 
+class FrameTreeAnonymousIframeBrowserTest : public FrameTreeBrowserTest {
+ public:
+  FrameTreeAnonymousIframeBrowserTest() = default;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
+                                    "AnonymousIframe");
+  }
+};
+
+// Tests the mojo propagation of the 'anonymous' attribute to the browser.
+IN_PROC_BROWSER_TEST_F(FrameTreeAnonymousIframeBrowserTest,
+                       AttributeIsPropagatedToBrowser) {
+  GURL main_url(embedded_test_server()->GetURL("/hello.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+
+  // Not setting the attribute => the iframe is not anonymous.
+  EXPECT_TRUE(ExecJs(root,
+                     "var f = document.createElement('iframe');"
+                     "document.body.appendChild(f);"));
+  EXPECT_EQ(1U, root->child_count());
+  EXPECT_FALSE(root->child_at(0)->anonymous());
+
+  // Setting the attribute on the iframe element makes the iframe anonymous.
+  EXPECT_TRUE(ExecJs(root,
+                     "var d = document.createElement('div');"
+                     "d.innerHTML = '<iframe anonymous></iframe>';"
+                     "document.body.appendChild(d);"));
+  EXPECT_EQ(2U, root->child_count());
+  EXPECT_TRUE(root->child_at(1)->anonymous());
+
+  // Setting the attribute via javascript works.
+  EXPECT_TRUE(ExecJs(root,
+                     "var g = document.createElement('iframe');"
+                     "g.anonymous = true;"
+                     "document.body.appendChild(g);"));
+  EXPECT_EQ(3U, root->child_count());
+  EXPECT_TRUE(root->child_at(2)->anonymous());
+
+  EXPECT_TRUE(ExecJs(root, "g.anonymous = false;"));
+  EXPECT_FALSE(root->child_at(2)->anonymous());
+
+  EXPECT_TRUE(ExecJs(root, "g.anonymous = true;"));
+  EXPECT_TRUE(root->child_at(2)->anonymous());
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/frame_tree_node.h b/content/browser/renderer_host/frame_tree_node.h
index 8b05319..1cfba9e 100644
--- a/content/browser/renderer_host/frame_tree_node.h
+++ b/content/browser/renderer_host/frame_tree_node.h
@@ -285,6 +285,11 @@
     csp_attribute_ = std::move(parsed_csp_attribute);
   }
 
+  // Reflects the 'anonymous' attribute of the corresponding iframe html
+  // element.
+  bool anonymous() const { return anonymous_; }
+  void set_anonymous(bool anonymous) { anonymous_ = anonymous; }
+
   bool HasSameOrigin(const FrameTreeNode& node) const {
     return replication_state_->origin.IsSameOriginWith(
         node.replication_state_->origin);
@@ -643,6 +648,10 @@
   // Contains the current parsed value of the 'csp' attribute of this frame.
   network::mojom::ContentSecurityPolicyPtr csp_attribute_;
 
+  // Reflects the 'anonymous' attribute of the corresponding iframe html
+  // element.
+  bool anonymous_ = false;
+
   // Owns an ongoing NavigationRequest until it is ready to commit. It will then
   // be reset and a RenderFrameHost will be responsible for the navigation.
   std::unique_ptr<NavigationRequest> navigation_request_;
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 6c8194c4..4656725d 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -1238,6 +1238,12 @@
       initiator_frame_token_(begin_params_->initiator_frame_token),
       initiator_process_id_(initiator_process_id),
       was_opener_suppressed_(was_opener_suppressed),
+      // The document to commit will be anonymous if either the iframe element
+      // has the 'anonymous' attribute set or the parent document is anonymous.
+      anonymous_(frame_tree_node->anonymous() ||
+                 (frame_tree_node->parent()
+                      ? frame_tree_node->parent()->anonymous()
+                      : false)),
       previous_page_ukm_source_id_(
           frame_tree_node_->current_frame_host()->GetPageUkmSourceId()) {
   DCHECK(browser_initiated || common_params_->initiator_origin.has_value());
@@ -3693,7 +3699,7 @@
       browser_context->GetClientHintsControllerDelegate();
   if (client_hints_delegate) {
     net::HttpRequestHeaders client_hints_extra_headers;
-    ParseAndPersistAcceptCHForNagivation(
+    ParseAndPersistAcceptCHForNavigation(
         commit_params_->redirects.back(),
         commit_params_->redirect_response.back()->parsed_headers,
         browser_context, client_hints_delegate, frame_tree_node_);
@@ -4088,7 +4094,7 @@
     absl::optional<std::vector<network::mojom::WebClientHintsType>>
         opt_in_hints_from_response;
     if (response()) {
-      opt_in_hints_from_response = ParseAndPersistAcceptCHForNagivation(
+      opt_in_hints_from_response = ParseAndPersistAcceptCHForNavigation(
           common_params_->url, response()->parsed_headers, browser_context,
           client_hints_delegate, frame_tree_node_);
     }
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 8d7f0b3..398aa8e6 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -684,6 +684,8 @@
   void SetRequiredCSP(network::mojom::ContentSecurityPolicyPtr csp);
   network::mojom::ContentSecurityPolicyPtr TakeRequiredCSP();
 
+  bool anonymous() const { return anonymous_; }
+
   // Returns a pointer to the policies copied from the navigation initiator.
   // Returns nullptr if this navigation had no initiator.
   const PolicyContainerPolicies* GetInitiatorPolicyContainerPolicies() const;
@@ -1780,6 +1782,11 @@
   // the RenderFrameHost at DidCommitNavigation time.
   network::mojom::ContentSecurityPolicyPtr required_csp_;
 
+  // Whether the document loaded by this navigation will be committed inside an
+  // anonymous iframe. Documents loaded inside anonymous iframes get partitioned
+  // storage and use a transient NetworkIsolationKey.
+  const bool anonymous_;
+
   // Non-nullopt from construction until |TakePolicyContainerHost()| is called.
   absl::optional<PolicyContainerNavigationBundle>
       policy_container_navigation_bundle_;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 0b14bf1..ddbaf4b2 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -1466,7 +1466,8 @@
           BrowserContext::CreateRandomMediaDeviceIDSalt()),
       document_associated_data_(
           std::make_unique<DocumentAssociatedData>(*this)),
-      lifecycle_state_(lifecycle_state) {
+      lifecycle_state_(lifecycle_state),
+      anonymous_(parent_ ? parent_->anonymous() : false) {
   DCHECK(delegate_);
   DCHECK(lifecycle_state_ == LifecycleStateImpl::kSpeculative ||
          lifecycle_state_ == LifecycleStateImpl::kPrerendering ||
@@ -5988,9 +5989,10 @@
                                                       GetSiteInstance());
 }
 
-void RenderFrameHostImpl::DidChangeCSPAttribute(
+void RenderFrameHostImpl::DidChangeIframeAttributes(
     const blink::FrameToken& child_frame_token,
-    network::mojom::ContentSecurityPolicyPtr parsed_csp_attribute) {
+    network::mojom::ContentSecurityPolicyPtr parsed_csp_attribute,
+    bool anonymous) {
   if (parsed_csp_attribute &&
       !ValidateCSPAttribute(parsed_csp_attribute->header->header_value)) {
     bad_message::ReceivedBadMessage(GetProcess(),
@@ -5998,12 +6000,13 @@
     return;
   }
 
-  auto* child =
-      FindAndVerifyChild(child_frame_token, bad_message::RFH_CSP_ATTRIBUTE);
+  auto* child = FindAndVerifyChild(
+      child_frame_token, bad_message::RFH_DID_CHANGE_IFRAME_ATTRIBUTE);
   if (!child)
     return;
 
   child->frame_tree_node()->set_csp_attribute(std::move(parsed_csp_attribute));
+  child->frame_tree_node()->set_anonymous(anonymous);
 }
 
 void RenderFrameHostImpl::DidChangeFramePolicy(
@@ -10140,6 +10143,7 @@
   // Store the required CSP (it will be used by the AncestorThrottle if
   // this frame embeds a subframe when that subframe navigates).
   required_csp_ = navigation_request->TakeRequiredCSP();
+  anonymous_ = navigation_request->anonymous();
 
   coep_reporter_ = navigation_request->TakeCoepReporter();
   if (coep_reporter_) {
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 2727e4a..3b6b483 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -1763,6 +1763,8 @@
     return required_csp_.get();
   }
 
+  bool anonymous() const { return anonymous_; }
+
   PolicyContainerHost* policy_container_host() {
     return policy_container_host_.get();
   }
@@ -2012,9 +2014,10 @@
       blink::mojom::FrameOwnerPropertiesPtr frame_owner_properties) override;
   void DidChangeOpener(
       const absl::optional<blink::LocalFrameToken>& opener_frame) override;
-  void DidChangeCSPAttribute(
+  void DidChangeIframeAttributes(
       const blink::FrameToken& child_frame_token,
-      network::mojom::ContentSecurityPolicyPtr parsed_csp_attribute) override;
+      network::mojom::ContentSecurityPolicyPtr parsed_csp_attribute,
+      bool anonymous) override;
   void DidChangeFramePolicy(const blink::FrameToken& child_frame_token,
                             const blink::FramePolicy& frame_policy) override;
   void CapturePaintPreviewOfSubframe(
@@ -3827,6 +3830,10 @@
   // stored when the frame commits the navigation.
   network::mojom::ContentSecurityPolicyPtr required_csp_;
 
+  // Whether the current document is loaded inside an anonymous iframe. Updated
+  // on every cross-document navigation.
+  bool anonymous_;
+
   // The PolicyContainerHost for the current document, containing security
   // policies that apply to it. It should never be null if the RenderFrameHost
   // is displaying a document. Its lifetime should coincide with the lifetime of
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
index ccfb5ad..0effa4a 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -5821,4 +5821,23 @@
   }
 }
 
+// This test checks that the initial empty document in an anonymous iframe whose
+// parent document is not anonymous is also not anonymous.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+                       InitialEmptyDocumentInAnonymousIframe) {
+  GURL main_url = embedded_test_server()->GetURL("/title1.html");
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  RenderFrameHostImpl* main_rfh = web_contents()->GetMainFrame();
+
+  // Create an empty iframe
+  EXPECT_TRUE(ExecJs(main_rfh,
+                     "let child = document.createElement('iframe');"
+                     "child.anonymous = true;"
+                     "document.body.appendChild(child);"));
+  WaitForLoadStop(web_contents());
+  EXPECT_EQ(1U, main_rfh->child_count());
+  EXPECT_FALSE(main_rfh->child_at(0)->anonymous());
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl_unittest.cc b/content/browser/renderer_host/render_frame_host_impl_unittest.cc
index d9afed5..a0aa59c0 100644
--- a/content/browser/renderer_host/render_frame_host_impl_unittest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_unittest.cc
@@ -294,4 +294,31 @@
   EXPECT_EQ(0u, contents()->GetFaviconURLs().size());
 }
 
+TEST_F(RenderFrameHostImplTest, ChildOfAnonymousIsAnonymous) {
+  EXPECT_FALSE(main_test_rfh()->anonymous());
+
+  auto* child_frame = static_cast<TestRenderFrameHost*>(
+      content::RenderFrameHostTester::For(main_test_rfh())
+          ->AppendChild("child"));
+  EXPECT_FALSE(child_frame->anonymous());
+
+  child_frame->frame_tree_node()->set_anonymous(true);
+  EXPECT_FALSE(child_frame->anonymous());
+
+  // A navigation in the anonymous iframe commits an anonymous RFH.
+  std::unique_ptr<NavigationSimulator> navigation =
+      NavigationSimulator::CreateRendererInitiated(
+          GURL("https://example.com/navigation.html"), child_frame);
+  navigation->Commit();
+  child_frame =
+      static_cast<TestRenderFrameHost*>(navigation->GetFinalRenderFrameHost());
+  EXPECT_TRUE(child_frame->anonymous());
+
+  // A child of an anonymous RFH is anonymous.
+  auto* grandchild_frame = static_cast<TestRenderFrameHost*>(
+      content::RenderFrameHostTester::For(child_frame)
+          ->AppendChild("grandchild"));
+  EXPECT_TRUE(grandchild_frame->anonymous());
+}
+
 }  // namespace content
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc
index 1cfb3a48..f3296d04 100644
--- a/content/browser/webui/shared_resources_data_source.cc
+++ b/content/browser/webui/shared_resources_data_source.cc
@@ -37,6 +37,7 @@
 
 const std::set<int> GetContentResourceIds() {
   return std::set<int>{
+      IDR_GEOMETRY_MOJOM_WEBUI_JS,
       IDR_ORIGIN_MOJO_HTML,
       IDR_ORIGIN_MOJO_JS,
       IDR_ORIGIN_MOJO_WEBUI_JS,
diff --git a/content/browser/webui/web_ui_message_handler_unittest.cc b/content/browser/webui/web_ui_message_handler_unittest.cc
index 8a3dffa..919842fd 100644
--- a/content/browser/webui/web_ui_message_handler_unittest.cc
+++ b/content/browser/webui/web_ui_message_handler_unittest.cc
@@ -26,27 +26,27 @@
   list.AppendInteger(zero_value);
   EXPECT_TRUE(WebUIMessageHandler::ExtractIntegerValue(&list, &value));
   EXPECT_EQ(value, zero_value);
-  list.Clear();
+  list.ClearList();
 
   list.AppendInteger(neg_value);
   EXPECT_TRUE(WebUIMessageHandler::ExtractIntegerValue(&list, &value));
   EXPECT_EQ(value, neg_value);
-  list.Clear();
+  list.ClearList();
 
   list.AppendInteger(pos_value);
   EXPECT_TRUE(WebUIMessageHandler::ExtractIntegerValue(&list, &value));
   EXPECT_EQ(value, pos_value);
-  list.Clear();
+  list.ClearList();
 
   list.AppendString(zero_string);
   EXPECT_TRUE(WebUIMessageHandler::ExtractIntegerValue(&list, &value));
   EXPECT_EQ(value, zero_value);
-  list.Clear();
+  list.ClearList();
 
   list.AppendString(neg_string);
   EXPECT_TRUE(WebUIMessageHandler::ExtractIntegerValue(&list, &value));
   EXPECT_EQ(value, neg_value);
-  list.Clear();
+  list.ClearList();
 
   list.AppendString(pos_string);
   EXPECT_TRUE(WebUIMessageHandler::ExtractIntegerValue(&list, &value));
@@ -66,27 +66,27 @@
   list.Append(zero_value);
   EXPECT_TRUE(WebUIMessageHandler::ExtractDoubleValue(&list, &value));
   EXPECT_DOUBLE_EQ(value, zero_value);
-  list.Clear();
+  list.ClearList();
 
   list.Append(neg_value);
   EXPECT_TRUE(WebUIMessageHandler::ExtractDoubleValue(&list, &value));
   EXPECT_DOUBLE_EQ(value, neg_value);
-  list.Clear();
+  list.ClearList();
 
   list.Append(pos_value);
   EXPECT_TRUE(WebUIMessageHandler::ExtractDoubleValue(&list, &value));
   EXPECT_DOUBLE_EQ(value, pos_value);
-  list.Clear();
+  list.ClearList();
 
   list.AppendString(zero_string);
   EXPECT_TRUE(WebUIMessageHandler::ExtractDoubleValue(&list, &value));
   EXPECT_DOUBLE_EQ(value, zero_value);
-  list.Clear();
+  list.ClearList();
 
   list.AppendString(neg_string);
   EXPECT_TRUE(WebUIMessageHandler::ExtractDoubleValue(&list, &value));
   EXPECT_DOUBLE_EQ(value, neg_value);
-  list.Clear();
+  list.ClearList();
 
   list.AppendString(pos_string);
   EXPECT_TRUE(WebUIMessageHandler::ExtractDoubleValue(&list, &value));
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc
index 6a2e75e..f6a57e56 100644
--- a/content/browser/worker_host/dedicated_worker_host.cc
+++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -100,6 +100,9 @@
 }
 
 DedicatedWorkerHost::~DedicatedWorkerHost() {
+  // This DedicatedWorkerHost is destroyed via either the mojo disconnection
+  // or RenderProcessHostObserver. This destruction should be called before
+  // the observed render process host (`worker_process_host_`) is destroyed.
   service_->NotifyBeforeWorkerDestroyed(token_, ancestor_render_frame_host_id_);
 }
 
@@ -139,6 +142,18 @@
   delete this;
 }
 
+void DedicatedWorkerHost::RenderProcessHostDestroyed(
+    RenderProcessHost* render_process_host) {
+  DCHECK_EQ(worker_process_host_, render_process_host);
+
+  // In --single-process mode, RenderProcessExited() is not called, so we must
+  // also listen to RenderProcessHostDestroyed() to know to delete `this` and
+  // preserve the invariant that RenderProcessHostImpl outlives `this`.
+  DCHECK(RenderProcessHost::run_renderer_in_process());
+
+  delete this;
+}
+
 void DedicatedWorkerHost::StartScriptLoad(
     const GURL& script_url,
     network::mojom::CredentialsMode credentials_mode,
diff --git a/content/browser/worker_host/dedicated_worker_host.h b/content/browser/worker_host/dedicated_worker_host.h
index 010b407..e79c5f3 100644
--- a/content/browser/worker_host/dedicated_worker_host.h
+++ b/content/browser/worker_host/dedicated_worker_host.h
@@ -158,6 +158,7 @@
   // RenderProcessHostObserver:
   void RenderProcessExited(RenderProcessHost* render_process_host,
                            const ChildProcessTerminationInfo& info) override;
+  void RenderProcessHostDestroyed(RenderProcessHost* host) override;
 
   // Called from WorkerScriptFetchInitiator. Continues starting the dedicated
   // worker in the renderer process.
@@ -214,12 +215,18 @@
 
   base::WeakPtr<CrossOriginEmbedderPolicyReporter> GetWorkerCoepReporter();
 
+  // This outlives `this` as follows:
+  //  - StoragePartitionImpl owns DedicatedWorkerServiceImpl until its dtor.
+  //  - StoragePartitionImpl outlives RenderProcessHostImpl.
+  //  - RenderProcessHostImpl outlives DedicatedWorkerHost.
+  // As the conclusion of the above, DedicatedWorkerServiceImpl outlives
+  // DedicatedWorkerHost.
   DedicatedWorkerServiceImpl* const service_;
 
   // The renderer generated ID of this worker, unique across all processes.
   const blink::DedicatedWorkerToken token_;
 
-  // The RenderProcessHost that hosts this worker.
+  // The RenderProcessHost that hosts this worker. This outlives `this`.
   RenderProcessHost* const worker_process_host_;
 
   base::ScopedObservation<RenderProcessHost, RenderProcessHostObserver>
diff --git a/content/content_resources.grd b/content/content_resources.grd
index 96b0cef..e136cf35 100644
--- a/content/content_resources.grd
+++ b/content/content_resources.grd
@@ -24,6 +24,7 @@
       <include name="IDR_DEVTOOLS_PINCH_CURSOR_ICON_2X" file="browser/resources/devtools/devtools_pinch_cursor_2x.png" type="BINDATA" />
       <include name="IDR_DEVTOOLS_TOUCH_CURSOR_ICON" file="browser/resources/devtools/devtools_touch_cursor.png" type="BINDATA" />
       <include name="IDR_DEVTOOLS_TOUCH_CURSOR_ICON_2X" file="browser/resources/devtools/devtools_touch_cursor_2x.png" type="BINDATA" />
+      <include name="IDR_GEOMETRY_MOJOM_WEBUI_JS" file="${root_gen_dir}/mojom-webui/ui/gfx/geometry/mojom/geometry.mojom-webui.js" resource_path="mojo/ui/gfx/geometry/mojom/geometry.mojom-webui.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_HISTOGRAMS_INTERNALS_HTML" file="browser/resources/histograms/histograms_internals.html" type="BINDATA" />
       <include name="IDR_HISTOGRAMS_INTERNALS_JS" file="browser/resources/histograms/histograms_internals.js" type="BINDATA" />
       <include name="IDR_HISTOGRAMS_INTERNALS_CSS" file="browser/resources/histograms/histograms_internals.css" type="BINDATA" />
diff --git a/content/public/browser/render_process_host_observer.h b/content/public/browser/render_process_host_observer.h
index c2400b5..349b760 100644
--- a/content/public/browser/render_process_host_observer.h
+++ b/content/public/browser/render_process_host_observer.h
@@ -39,6 +39,8 @@
   // active renderer process for the top-level frame; for code that needs to be
   // a WebContentsObserver anyway, consider whether that API might be a better
   // choice.
+  //
+  // This is not called in --single-process mode.
   virtual void RenderProcessExited(RenderProcessHost* host,
                                    const ChildProcessTerminationInfo& info) {}
 
diff --git a/device/fido/aoa/android_accessory_device.cc b/device/fido/aoa/android_accessory_device.cc
index 7c2ec08..e907cb7 100644
--- a/device/fido/aoa/android_accessory_device.cc
+++ b/device/fido/aoa/android_accessory_device.cc
@@ -74,7 +74,7 @@
 void AndroidAccessoryDevice::OnReadLengthComplete(
     DeviceCallback callback,
     mojom::UsbTransferStatus result,
-    const std::vector<uint8_t>& payload) {
+    base::span<const uint8_t> payload) {
   if (result != mojom::UsbTransferStatus::COMPLETED ||
       payload.size() != 1 + sizeof(uint32_t)) {
     FIDO_LOG(ERROR) << "Failed to read reply from USB device ("
@@ -113,11 +113,10 @@
                      weak_factory_.GetWeakPtr(), std::move(callback), length));
 }
 
-void AndroidAccessoryDevice::OnReadComplete(
-    DeviceCallback callback,
-    const uint32_t length,
-    mojom::UsbTransferStatus result,
-    const std::vector<uint8_t>& payload) {
+void AndroidAccessoryDevice::OnReadComplete(DeviceCallback callback,
+                                            const uint32_t length,
+                                            mojom::UsbTransferStatus result,
+                                            base::span<const uint8_t> payload) {
   if (result != mojom::UsbTransferStatus::COMPLETED ||
       payload.size() + buffer_.size() > length) {
     FIDO_LOG(ERROR) << "Failed to read from USB device ("
diff --git a/device/fido/aoa/android_accessory_device.h b/device/fido/aoa/android_accessory_device.h
index 6760074..89ac54a 100644
--- a/device/fido/aoa/android_accessory_device.h
+++ b/device/fido/aoa/android_accessory_device.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "base/containers/span.h"
 #include "base/memory/weak_ptr.h"
 #include "device/fido/fido_device.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -43,11 +44,11 @@
                        device::mojom::UsbTransferStatus result);
   void OnReadLengthComplete(DeviceCallback callback,
                             device::mojom::UsbTransferStatus result,
-                            const std::vector<uint8_t>& payload);
+                            base::span<const uint8_t> payload);
   void OnReadComplete(DeviceCallback callback,
                       const uint32_t length,
                       device::mojom::UsbTransferStatus result,
-                      const std::vector<uint8_t>& payload);
+                      base::span<const uint8_t> payload);
 
   mojo::Remote<device::mojom::UsbDevice> device_;
   const uint8_t in_endpoint_;
diff --git a/device/fido/aoa/android_accessory_discovery.cc b/device/fido/aoa/android_accessory_discovery.cc
index 4987ae8f..58e0009 100644
--- a/device/fido/aoa/android_accessory_discovery.cc
+++ b/device/fido/aoa/android_accessory_discovery.cc
@@ -304,7 +304,7 @@
     InterfaceInfo interface_info,
     std::array<uint8_t, kSyncNonceLength> nonce,
     mojom::UsbTransferStatus result,
-    const std::vector<uint8_t>& payload) {
+    base::span<const uint8_t> payload) {
   // BABBLE results if the message from the USB peer was longer than expected.
   // That's fine because we're expecting potentially discard some messages in
   // order to find the sync message.
@@ -362,7 +362,7 @@
 void AndroidAccessoryDiscovery::OnVersionReply(
     mojo::Remote<device::mojom::UsbDevice> device,
     device::mojom::UsbTransferStatus status,
-    const std::vector<uint8_t>& payload) {
+    base::span<const uint8_t> payload) {
   if (status != mojom::UsbTransferStatus::COMPLETED || payload.size() != 2) {
     RecordEvent(AOADiscoveryEvent::kVersionFailed);
     FIDO_LOG(DEBUG) << "Android AOA version request failed with status: "
diff --git a/device/fido/aoa/android_accessory_discovery.h b/device/fido/aoa/android_accessory_discovery.h
index 6ab5a75..cf22a43 100644
--- a/device/fido/aoa/android_accessory_discovery.h
+++ b/device/fido/aoa/android_accessory_discovery.h
@@ -12,6 +12,7 @@
 
 #include "base/callback.h"
 #include "base/component_export.h"
+#include "base/containers/span.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "device/fido/fido_device_discovery.h"
@@ -74,7 +75,7 @@
               device::mojom::UsbOpenDeviceError error);
   void OnVersionReply(mojo::Remote<device::mojom::UsbDevice> device,
                       device::mojom::UsbTransferStatus status,
-                      const std::vector<uint8_t>& payload);
+                      base::span<const uint8_t> payload);
   void OnConfigurationStepComplete(
       mojo::Remote<device::mojom::UsbDevice> device,
       unsigned step,
@@ -97,7 +98,7 @@
                       InterfaceInfo interface_info,
                       std::array<uint8_t, kSyncNonceLength> nonce,
                       mojom::UsbTransferStatus result,
-                      const std::vector<uint8_t>& payload);
+                      base::span<const uint8_t> payload);
   void OnAccessoryInterfaceClaimed(
       mojo::Remote<device::mojom::UsbDevice> device,
       InterfaceInfo interface_info,
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
index 3d7ac6f..77b6913 100644
--- a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
+++ b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -124,7 +124,7 @@
   EXPECT_FALSE(attribute_exclude->IsFulfilled(WebRequestData(
       &request_info, ON_HEADERS_RECEIVED, response_headers.get())));
 
-  content_types.Clear();
+  content_types.ClearList();
   content_types.AppendString("something/invalid");
   scoped_refptr<const WebRequestConditionAttribute> attribute_unincluded =
       WebRequestConditionAttribute::Create(
diff --git a/extensions/browser/api/usb/usb_api.cc b/extensions/browser/api/usb/usb_api.cc
index 0f60520..71f597f863 100644
--- a/extensions/browser/api/usb/usb_api.cc
+++ b/extensions/browser/api/usb/usb_api.cc
@@ -490,7 +490,7 @@
 
 void UsbTransferFunction::OnTransferInCompleted(
     UsbTransferStatus status,
-    const std::vector<uint8_t>& data) {
+    base::span<const uint8_t> data) {
   base::Value transfer_info(base::Value::Type::DICTIONARY);
   transfer_info.SetIntKey(kResultCodeKey, static_cast<int>(status));
   transfer_info.SetKey(kDataKey, base::Value(data));
@@ -1274,7 +1274,7 @@
 }
 
 void UsbIsochronousTransferFunction::OnTransferInCompleted(
-    const std::vector<uint8_t>& data,
+    base::span<const uint8_t> data,
     std::vector<UsbIsochronousPacketPtr> packets) {
   size_t length = std::accumulate(packets.begin(), packets.end(), 0,
                                   [](const size_t& a, const auto& packet) {
diff --git a/extensions/browser/api/usb/usb_api.h b/extensions/browser/api/usb/usb_api.h
index 92d94a336..9b32b0c 100644
--- a/extensions/browser/api/usb/usb_api.h
+++ b/extensions/browser/api/usb/usb_api.h
@@ -12,6 +12,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/span.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "extensions/browser/api/api_resource_manager.h"
@@ -74,7 +75,7 @@
   void OnCompleted(device::mojom::UsbTransferStatus status,
                    std::unique_ptr<base::DictionaryValue> transfer_info);
   void OnTransferInCompleted(device::mojom::UsbTransferStatus status,
-                             const std::vector<uint8_t>& data);
+                             base::span<const uint8_t> data);
   void OnTransferOutCompleted(device::mojom::UsbTransferStatus status);
   void OnDisconnect();
 };
@@ -379,7 +380,7 @@
   ResponseAction Run() override;
 
   void OnTransferInCompleted(
-      const std::vector<uint8_t>& data,
+      base::span<const uint8_t> data,
       std::vector<device::mojom::UsbIsochronousPacketPtr> packets);
   void OnTransferOutCompleted(
       std::vector<device::mojom::UsbIsochronousPacketPtr> packets);
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc
index fa460ea..9b5ca3f 100644
--- a/extensions/browser/extension_prefs.cc
+++ b/extensions/browser/extension_prefs.cc
@@ -2385,7 +2385,7 @@
     const ExtensionIdContainer& strings) {
   ListPrefUpdate update(prefs_, pref);
   base::ListValue* list_of_values = update.Get();
-  list_of_values->Clear();
+  list_of_values->ClearList();
   for (auto iter = strings.cbegin(); iter != strings.cend(); ++iter) {
     list_of_values->AppendString(*iter);
   }
diff --git a/extensions/common/file_util_unittest.cc b/extensions/common/file_util_unittest.cc
index db1b1cd..2d58fc0 100644
--- a/extensions/common/file_util_unittest.cc
+++ b/extensions/common/file_util_unittest.cc
@@ -400,7 +400,7 @@
             error);
   EXPECT_EQ(0U, warnings.size());
 
-  scripts->Clear();
+  scripts->ClearList();
   scripts->AppendString("http://google.com/foo.js");
 
   extension = LoadExtensionManifest(*value, temp.GetPath(),
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc
index dbab9f46..d92f410 100644
--- a/gpu/ipc/service/gpu_channel.cc
+++ b/gpu/ipc/service/gpu_channel.cc
@@ -657,7 +657,7 @@
           *params->get_command_buffer_request();
       CommandBufferStub* stub = LookupCommandBuffer(request.routing_id);
       if (!stub || !stub->IsScheduled()) {
-        DLOG(ERROR) << "Invalid routing ID in deferred request";
+        DVLOG(1) << "Invalid routing ID in deferred request";
         return;
       }
 
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm
index b74ff8d5..239812d 100644
--- a/ios/chrome/browser/prefs/browser_prefs.mm
+++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -45,6 +45,7 @@
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/strings/grit/components_locale_settings.h"
 #include "components/sync/base/sync_prefs.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync_device_info/device_info_prefs.h"
 #include "components/sync_sessions/session_sync_prefs.h"
 #include "components/translate/core/browser/translate_pref_names.h"
@@ -206,6 +207,7 @@
   sync_sessions::SessionSyncPrefs::RegisterProfilePrefs(registry);
   syncer::DeviceInfoPrefs::RegisterProfilePrefs(registry);
   syncer::SyncPrefs::RegisterProfilePrefs(registry);
+  syncer::SyncTransportDataPrefs::RegisterProfilePrefs(registry);
   TemplateURLPrepopulateData::RegisterProfilePrefs(registry);
   translate::TranslatePrefs::RegisterProfilePrefs(registry);
   unified_consent::UnifiedConsentService::RegisterPrefs(registry);
diff --git a/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm b/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
index c2dae2f..272c4afd8 100644
--- a/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
@@ -13,6 +13,8 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/signin/authentication_service.h"
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
+#import "ios/chrome/browser/signin/chrome_account_manager_service.h"
+#import "ios/chrome/browser/signin/chrome_account_manager_service_factory.h"
 #include "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
 #import "ios/chrome/browser/ui/authentication/resized_avatar_cache.h"
@@ -113,12 +115,14 @@
   NSMutableDictionary<NSString*, CollectionViewItem*>* mutableIdentityMap =
       [[NSMutableDictionary alloc] init];
 
+  ChromeAccountManagerService* accountManagerService =
+      ChromeAccountManagerServiceFactory::GetForBrowserState(_browserState);
+
   signin::IdentityManager* identityManager =
       IdentityManagerFactory::GetForBrowserState(_browserState);
   for (const auto& account : identityManager->GetAccountsWithRefreshTokens()) {
-    ChromeIdentity* identity = ios::GetChromeBrowserProvider()
-                                   .GetChromeIdentityService()
-                                   ->GetIdentityWithGaiaID(account.gaia);
+    ChromeIdentity* identity =
+        accountManagerService->GetIdentityWithGaiaID(account.gaia);
 
     // If the account with a refresh token is invalidated during this operation
     // then |identity| will be nil. Do not process it in this case.
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.h b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.h
index dec26651..25a5c00 100644
--- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.h
+++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.h
@@ -16,7 +16,7 @@
 class Browser;
 @class ChromeIdentity;
 namespace syncer {
-enum class KeyRetrievalTriggerForUMA;
+enum class TrustedVaultUserActionTriggerForUMA;
 }  // namespace syncer
 namespace user_prefs {
 class PrefRegistrySyncable;
@@ -115,11 +115,11 @@
                                                           browser:
                                                               (Browser*)browser
                                                            intent:
-                                                (SigninTrustedVaultDialogIntent)
+                                                               (SigninTrustedVaultDialogIntent)
                                                                    intent
                                                           trigger:
                                                               (syncer::
-                                                      KeyRetrievalTriggerForUMA)
+                                                                   TrustedVaultUserActionTriggerForUMA)
                                                                   trigger;
 
 // Returns a coordinator to display the account consistency promo with a list
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm
index 6b7d569a..ff1520b5 100644
--- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm
@@ -133,11 +133,11 @@
                                                           browser:
                                                               (Browser*)browser
                                                            intent:
-                                                (SigninTrustedVaultDialogIntent)
+                                                               (SigninTrustedVaultDialogIntent)
                                                                    intent
                                                           trigger:
                                                               (syncer::
-                                                      KeyRetrievalTriggerForUMA)
+                                                                   TrustedVaultUserActionTriggerForUMA)
                                                                   trigger {
   return [[TrustedVaultReauthenticationCoordinator alloc]
       initWithBaseViewController:viewController
diff --git a/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.h b/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.h
index b2e4d30..0c7d699 100644
--- a/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.h
+++ b/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.h
@@ -8,7 +8,7 @@
 #import "ios/chrome/browser/ui/authentication/signin/signin_coordinator.h"
 
 namespace syncer {
-enum class KeyRetrievalTriggerForUMA;
+enum class TrustedVaultUserActionTriggerForUMA;
 }  // namespace syncer
 
 // Coordinates the Trusted Vault re-authentication dialog. Trusted Valut is
@@ -26,7 +26,8 @@
     initWithBaseViewController:(UIViewController*)viewController
                        browser:(Browser*)browser
                         intent:(SigninTrustedVaultDialogIntent)intent
-                       trigger:(syncer::KeyRetrievalTriggerForUMA)trigger
+                       trigger:
+                           (syncer::TrustedVaultUserActionTriggerForUMA)trigger
     NS_DESIGNATED_INITIALIZER;
 
 @end
diff --git a/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.mm
index ed170cd..0ec2ea1 100644
--- a/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.mm
@@ -39,7 +39,8 @@
     initWithBaseViewController:(UIViewController*)viewController
                        browser:(Browser*)browser
                         intent:(SigninTrustedVaultDialogIntent)intent
-                       trigger:(syncer::KeyRetrievalTriggerForUMA)trigger {
+                       trigger:(syncer::TrustedVaultUserActionTriggerForUMA)
+                                   trigger {
   self = [super initWithBaseViewController:viewController browser:browser];
   if (self) {
     syncer::RecordKeyRetrievalTrigger(trigger);
diff --git a/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator_unittest.mm b/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator_unittest.mm
index 0f7e499..59605b9 100644
--- a/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator_unittest.mm
@@ -74,8 +74,8 @@
 // Opens the trusted vault reauth dialog, and simulate a user cancel.
 TEST_F(TrustedVaultReauthenticationCoordinatorTest, TestCancel) {
   // Create sign-in coordinator.
-  syncer::KeyRetrievalTriggerForUMA trigger =
-      syncer::KeyRetrievalTriggerForUMA::kSettings;
+  syncer::TrustedVaultUserActionTriggerForUMA trigger =
+      syncer::TrustedVaultUserActionTriggerForUMA::kSettings;
   SigninCoordinator* signinCoordinator = [SigninCoordinator
       trustedVaultReAuthenticationCoordinatorWithBaseViewController:
           base_view_controller_
@@ -110,8 +110,8 @@
 // Opens the trusted vault reauth dialog, and simulate a user cancel.
 TEST_F(TrustedVaultReauthenticationCoordinatorTest, TestInterrupt) {
   // Create sign-in coordinator.
-  syncer::KeyRetrievalTriggerForUMA trigger =
-      syncer::KeyRetrievalTriggerForUMA::kSettings;
+  syncer::TrustedVaultUserActionTriggerForUMA trigger =
+      syncer::TrustedVaultUserActionTriggerForUMA::kSettings;
   SigninCoordinator* signinCoordinator = [SigninCoordinator
       trustedVaultReAuthenticationCoordinatorWithBaseViewController:
           base_view_controller_
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 6f5bc90..2ee4e70 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -5385,14 +5385,14 @@
 }
 
 - (void)showTrustedVaultReauthForFetchKeysWithTrigger:
-    (syncer::KeyRetrievalTriggerForUMA)trigger {
+    (syncer::TrustedVaultUserActionTriggerForUMA)trigger {
   [self.dispatcher
       showTrustedVaultReauthForFetchKeysFromViewController:self
                                                    trigger:trigger];
 }
 
 - (void)showTrustedVaultReauthForDegradedRecoverabilityWithTrigger:
-    (syncer::KeyRetrievalTriggerForUMA)trigger {
+    (syncer::TrustedVaultUserActionTriggerForUMA)trigger {
   [self.dispatcher
       showTrustedVaultReauthForDegradedRecoverabilityFromViewController:self
                                                                 trigger:
diff --git a/ios/chrome/browser/ui/commands/application_commands.h b/ios/chrome/browser/ui/commands/application_commands.h
index 8bf3661b..2738ddb5 100644
--- a/ios/chrome/browser/ui/commands/application_commands.h
+++ b/ios/chrome/browser/ui/commands/application_commands.h
@@ -15,7 +15,7 @@
 @class StartVoiceSearchCommand;
 @class UIViewController;
 namespace syncer {
-enum class KeyRetrievalTriggerForUMA;
+enum class TrustedVaultUserActionTriggerForUMA;
 }  // namespace syncer
 
 // This protocol groups commands that are part of ApplicationCommands, but
@@ -102,7 +102,7 @@
         (UIViewController*)baseViewController
                                                  trigger:
                                                      (syncer::
-                                                          KeyRetrievalTriggerForUMA)
+                                                          TrustedVaultUserActionTriggerForUMA)
                                                          trigger;
 
 // Presents the Trusted Vault degraded recoverability (to enroll additional
@@ -114,7 +114,7 @@
         (UIViewController*)baseViewController
                                                               trigger:
                                                                   (syncer::
-                                                                       KeyRetrievalTriggerForUMA)
+                                                                       TrustedVaultUserActionTriggerForUMA)
                                                                       trigger;
 
 // Starts a voice search on the current BVC.
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index ee7473b..b6303664 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -1540,7 +1540,7 @@
         (UIViewController*)viewController
                                                  trigger:
                                                      (syncer::
-                                                          KeyRetrievalTriggerForUMA)
+                                                          TrustedVaultUserActionTriggerForUMA)
                                                          trigger {
   [self
       showTrustedVaultDialogFromViewController:viewController
@@ -1554,7 +1554,7 @@
         (UIViewController*)viewController
                                                               trigger:
                                                                   (syncer::
-                                                                       KeyRetrievalTriggerForUMA)
+                                                                       TrustedVaultUserActionTriggerForUMA)
                                                                       trigger {
   [self
       showTrustedVaultDialogFromViewController:viewController
@@ -2611,8 +2611,10 @@
     showTrustedVaultDialogFromViewController:(UIViewController*)viewController
                                       intent:
                                           (SigninTrustedVaultDialogIntent)intent
-                                     trigger:(syncer::KeyRetrievalTriggerForUMA)
-                                                 trigger {
+                                     trigger:
+                                         (syncer::
+                                              TrustedVaultUserActionTriggerForUMA)
+                                             trigger {
   DCHECK(!self.signinCoordinator);
   Browser* mainBrowser = self.mainInterface.browser;
   self.signinCoordinator = [SigninCoordinator
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
index 63c3917c..cff6a851 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -1380,13 +1380,13 @@
 }
 
 - (void)showTrustedVaultReauthForFetchKeysWithTrigger:
-    (syncer::KeyRetrievalTriggerForUMA)trigger {
+    (syncer::TrustedVaultUserActionTriggerForUMA)trigger {
   [self.handler showTrustedVaultReauthForFetchKeysFromViewController:self
                                                              trigger:trigger];
 }
 
 - (void)showTrustedVaultReauthForDegradedRecoverabilityWithTrigger:
-    (syncer::KeyRetrievalTriggerForUMA)trigger {
+    (syncer::TrustedVaultUserActionTriggerForUMA)trigger {
   [self.handler
       showTrustedVaultReauthForDegradedRecoverabilityFromViewController:self
                                                                 trigger:
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
index 438c86f..4b34a11 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
@@ -257,7 +257,7 @@
           self.googleServicesSettingsViewController
                                                    trigger:
                                                        syncer::
-                                                           KeyRetrievalTriggerForUMA::
+                                                           TrustedVaultUserActionTriggerForUMA::
                                                                kSettings];
 }
 
@@ -269,7 +269,7 @@
       showTrustedVaultReauthForDegradedRecoverabilityFromViewController:
           self.viewController
                                                                 trigger:
-                                                                    syncer::KeyRetrievalTriggerForUMA::
+                                                                    syncer::TrustedVaultUserActionTriggerForUMA::
                                                                         kSettings];
 }
 
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
index 2205d156..ee1aa4b 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
@@ -287,7 +287,7 @@
       showTrustedVaultReauthForFetchKeysFromViewController:self.viewController
                                                    trigger:
                                                        syncer::
-                                                           KeyRetrievalTriggerForUMA::
+                                                           TrustedVaultUserActionTriggerForUMA::
                                                                kSettings];
 }
 
@@ -299,7 +299,7 @@
       showTrustedVaultReauthForDegradedRecoverabilityFromViewController:
           self.viewController
                                                                 trigger:
-                                                                    syncer::KeyRetrievalTriggerForUMA::
+                                                                    syncer::TrustedVaultUserActionTriggerForUMA::
                                                                         kSettings];
 }
 
diff --git a/ios/chrome/browser/ui/settings/sync/utils/sync_error_infobar_delegate.mm b/ios/chrome/browser/ui/settings/sync/utils/sync_error_infobar_delegate.mm
index 9b2353a..eb349790 100644
--- a/ios/chrome/browser/ui/settings/sync/utils/sync_error_infobar_delegate.mm
+++ b/ios/chrome/browser/ui/settings/sync/utils/sync_error_infobar_delegate.mm
@@ -105,12 +105,14 @@
     [presenter_ showSyncPassphraseSettings];
   } else if (error_state_ ==
              SyncSetupService::kSyncServiceNeedsTrustedVaultKey) {
-    [presenter_ showTrustedVaultReauthForFetchKeysWithTrigger:
-                    syncer::KeyRetrievalTriggerForUMA::kNewTabPageInfobar];
+    [presenter_
+        showTrustedVaultReauthForFetchKeysWithTrigger:
+            syncer::TrustedVaultUserActionTriggerForUMA::kNewTabPageInfobar];
   } else if (error_state_ ==
              SyncSetupService::kSyncServiceTrustedVaultRecoverabilityDegraded) {
-    [presenter_ showTrustedVaultReauthForDegradedRecoverabilityWithTrigger:
-                    syncer::KeyRetrievalTriggerForUMA::kNewTabPageInfobar];
+    [presenter_
+        showTrustedVaultReauthForDegradedRecoverabilityWithTrigger:
+            syncer::TrustedVaultUserActionTriggerForUMA::kNewTabPageInfobar];
   }
   return false;
 }
diff --git a/ios/chrome/browser/ui/settings/sync/utils/sync_error_infobar_delegate_unittest.mm b/ios/chrome/browser/ui/settings/sync/utils/sync_error_infobar_delegate_unittest.mm
index 79d1e611..87c611b 100644
--- a/ios/chrome/browser/ui/settings/sync/utils/sync_error_infobar_delegate_unittest.mm
+++ b/ios/chrome/browser/ui/settings/sync/utils/sync_error_infobar_delegate_unittest.mm
@@ -108,7 +108,7 @@
   id presenter = OCMStrictProtocolMock(@protocol(SyncPresenter));
   [[presenter expect]
       showTrustedVaultReauthForFetchKeysWithTrigger:
-          syncer::KeyRetrievalTriggerForUMA::kNewTabPageInfobar];
+          syncer::TrustedVaultUserActionTriggerForUMA::kNewTabPageInfobar];
   std::unique_ptr<SyncErrorInfoBarDelegate> delegate(
       new SyncErrorInfoBarDelegate(chrome_browser_state_.get(), presenter));
 
@@ -126,7 +126,7 @@
   id presenter = OCMStrictProtocolMock(@protocol(SyncPresenter));
   [[presenter expect]
       showTrustedVaultReauthForDegradedRecoverabilityWithTrigger:
-          syncer::KeyRetrievalTriggerForUMA::kNewTabPageInfobar];
+          syncer::TrustedVaultUserActionTriggerForUMA::kNewTabPageInfobar];
   std::unique_ptr<SyncErrorInfoBarDelegate> delegate(
       new SyncErrorInfoBarDelegate(chrome_browser_state_.get(), presenter));
 
diff --git a/ios/chrome/browser/ui/settings/sync/utils/sync_presenter.h b/ios/chrome/browser/ui/settings/sync/utils/sync_presenter.h
index afc36fe..96c4c8e 100644
--- a/ios/chrome/browser/ui/settings/sync/utils/sync_presenter.h
+++ b/ios/chrome/browser/ui/settings/sync/utils/sync_presenter.h
@@ -8,7 +8,7 @@
 #import <Foundation/Foundation.h>
 
 namespace syncer {
-enum class KeyRetrievalTriggerForUMA;
+enum class TrustedVaultUserActionTriggerForUMA;
 }  // namespace syncer
 
 // Protocol used to display sync-related UI.
@@ -29,13 +29,13 @@
 // Presents the Trusted Vault reauthentication dialog.
 // |trigger| UI elements where the trusted vault reauth has been triggered.
 - (void)showTrustedVaultReauthForFetchKeysWithTrigger:
-    (syncer::KeyRetrievalTriggerForUMA)trigger;
+    (syncer::TrustedVaultUserActionTriggerForUMA)trigger;
 
 // Presents the Trusted Vault degraded recoverability dialog (to enroll
 // additional recovery factors).
 // |trigger| UI elements where the trusted vault reauth has been triggered.
 - (void)showTrustedVaultReauthForDegradedRecoverabilityWithTrigger:
-    (syncer::KeyRetrievalTriggerForUMA)trigger;
+    (syncer::TrustedVaultUserActionTriggerForUMA)trigger;
 
 @end
 
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
index 7d65452..ccd4e94 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-cc482b4524485f999a8c929986ff788ee744dee7
\ No newline at end of file
+cc337f31543e49f86e0b9803217347bf947cf5ce
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
index c4e000b..d22e806 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-de097571c176cf0521b993942b9a482d26c93bb5
\ No newline at end of file
+6aea8a4ab0d2a24fe2790dcce1e114b9bcff778a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
index 0cde53d6..1a128b2 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-912070b573387e15cea1121dc7b7a18682524805
\ No newline at end of file
+33c9c77b9f0c0a63872fa71c50e9cc33e2d5ef64
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
index 0e54a6a..ce06451 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-4caeac41c94ab0abd1ff1793336124eb028efc5c
\ No newline at end of file
+2911969fa4caab0e99dcbd96dfb812506e36d83a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
index 34100f1..e63f13c4 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-60e247f7237275343a719e3741d7d9759baddb3c
\ No newline at end of file
+45a69bc363b4ee87bcb22bab3de9eadf7c88297e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
index bbfc75a..e77be76 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-83fa018ebc80412f12612aefc4f9327c080d1b87
\ No newline at end of file
+09b02270405a1ece9dfab6e7d44de09e74ccd85b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
index e1726a3..1d06a7b 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-f7163acab632fdb908d916115571b16112aa1839
\ No newline at end of file
+be2a67431c1677711a36dc219ae2cbd0590d35b9
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
index 728ea0cb..c1d28573 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-f37b22dc8cde2fa86266ec49211200bb5190e02b
\ No newline at end of file
+7f4cdf5ab5b693a7cd8131f6716827bbb0416a9e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
index 40555806..0671098 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-5aac8df9003c93052674c99ae319e822ab699937
\ No newline at end of file
+dfebc194fd798a663b728a332641001bdb87a625
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
index b03a046..3733ece 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-9d5e4526737335aa0772e0d22b2249b7c961f2f1
\ No newline at end of file
+ad24f9c131870e905413436971bdcf80c7fcae6e
\ No newline at end of file
diff --git a/ios/web_view/internal/web_view_browser_state.mm b/ios/web_view/internal/web_view_browser_state.mm
index d3a0832..cd3ce45 100644
--- a/ios/web_view/internal/web_view_browser_state.mm
+++ b/ios/web_view/internal/web_view_browser_state.mm
@@ -27,6 +27,7 @@
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/sync/base/pref_names.h"
 #include "components/sync/base/sync_prefs.h"
+#include "components/sync/driver/glue/sync_transport_data_prefs.h"
 #include "components/sync_device_info/device_info_prefs.h"
 #include "components/translate/core/browser/translate_pref_names.h"
 #include "components/translate/core/browser/translate_prefs.h"
@@ -178,6 +179,7 @@
   autofill::prefs::RegisterProfilePrefs(pref_registry);
   password_manager::PasswordManager::RegisterProfilePrefs(pref_registry);
   syncer::SyncPrefs::RegisterProfilePrefs(pref_registry);
+  syncer::SyncTransportDataPrefs::RegisterProfilePrefs(pref_registry);
   syncer::DeviceInfoPrefs::RegisterProfilePrefs(pref_registry);
   safe_browsing::RegisterProfilePrefs(pref_registry);
   unified_consent::UnifiedConsentService::RegisterPrefs(pref_registry);
diff --git a/media/gpu/chromeos/chromeos_video_decoder_factory.cc b/media/gpu/chromeos/chromeos_video_decoder_factory.cc
index 6c84173..538fcca 100644
--- a/media/gpu/chromeos/chromeos_video_decoder_factory.cc
+++ b/media/gpu/chromeos/chromeos_video_decoder_factory.cc
@@ -68,9 +68,9 @@
       std::move(client_task_runner), std::move(frame_pool),
       std::move(frame_converter), std::move(media_log),
 #if BUILDFLAG(USE_VAAPI)
-      base::BindRepeating(&VaapiVideoDecoder::Create)
+      base::BindOnce(&VaapiVideoDecoder::Create)
 #elif BUILDFLAG(USE_V4L2_CODEC)
-      base::BindRepeating(&V4L2VideoDecoder::Create)
+      base::BindOnce(&V4L2VideoDecoder::Create)
 #endif
   );
 }
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
index 72b44cf7..6150da2 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -224,21 +224,19 @@
   client_output_cb_ = std::move(output_cb);
   waiting_cb_ = std::move(waiting_cb);
 
-  // Initialize() and correspondingly InitializeTask(), are called both on first
-  // initialization and on subsequent stream |config| changes, e.g. change of
-  // resolution. Subsequent initializations are marked by |decoder_| already
-  // existing.
+  // |decoder_| may be Initialize()d multiple times (e.g. on |config| changes)
+  // but can only be created once.
+  if (!decoder_ && !create_decoder_function_cb_.is_null()) {
+    decoder_ = std::move(create_decoder_function_cb_)
+                   .Run(decoder_task_runner_, decoder_weak_this_);
+  }
+  // Note: |decoder_| might fail to be created, e.g. on V4L2 platforms.
   if (!decoder_) {
-    decoder_ = create_decoder_function_cb_.Run(decoder_task_runner_,
-                                               decoder_weak_this_);
-
-    if (!decoder_) {
-      DVLOGF(2) << "|decoder_| creation failed.";
-      client_task_runner_->PostTask(
-          FROM_HERE, base::BindOnce(std::move(init_cb),
-                                    StatusCode::kDecoderFailedCreation));
-      return;
-    }
+    OnError("|decoder_| creation failed.");
+    client_task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(std::move(init_cb), StatusCode::kDecoderFailedCreation));
+    return;
   }
 
   decoder_->Initialize(
diff --git a/media/gpu/chromeos/video_decoder_pipeline.h b/media/gpu/chromeos/video_decoder_pipeline.h
index ddb2f015..4dd1cd0 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.h
+++ b/media/gpu/chromeos/video_decoder_pipeline.h
@@ -141,7 +141,7 @@
                                               public DecoderInterface::Client {
  public:
   using CreateDecoderFunctionCB =
-      base::RepeatingCallback<std::unique_ptr<DecoderInterface>(
+      base::OnceCallback<std::unique_ptr<DecoderInterface>(
           scoped_refptr<base::SequencedTaskRunner>,
           base::WeakPtr<DecoderInterface::Client>)>;
 
diff --git a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
index 2efbbf62..b076524 100644
--- a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
@@ -111,7 +111,11 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 struct DecoderPipelineTestParams {
-  VideoDecoderPipeline::CreateDecoderFunctionCB create_decoder_function_cb;
+  // GTest params need to be copyable; hence we need here a RepeatingCallback
+  // version of VideoDecoderPipeline::CreateDecoderFunctionCB.
+  using RepeatingCreateDecoderFunctionCB = base::RepeatingCallback<
+      VideoDecoderPipeline::CreateDecoderFunctionCB::RunType>;
+  RepeatingCreateDecoderFunctionCB create_decoder_function_cb;
   StatusCode status_code;
 };
 
@@ -136,8 +140,8 @@
             std::move(pool_),
             std::move(converter_),
             // This callback needs to be configured in the individual tests.
-            base::BindRepeating(
-                &VideoDecoderPipelineTest::CreateNullMockDecoder))) {}
+            base::BindOnce(&VideoDecoderPipelineTest::CreateNullMockDecoder))) {
+  }
   ~VideoDecoderPipelineTest() override = default;
 
   void TearDown() override {
@@ -161,7 +165,7 @@
       VideoDecoderPipeline::CreateDecoderFunctionCB create_decoder_function_cb,
       StatusCode status_code,
       CdmContext* cdm_context = nullptr) {
-    SetCreateDecoderFunctionCB(create_decoder_function_cb);
+    SetCreateDecoderFunctionCB(std::move(create_decoder_function_cb));
 
     base::RunLoop run_loop;
     EXPECT_CALL(*this, OnInit(MatchesStatusCode(status_code)))
@@ -194,7 +198,7 @@
         .WillOnce(
             Return(ByMove(std::make_unique<FakeCdmContextRef>(&cdm_context_))));
     InitializeDecoder(
-        base::BindRepeating(
+        base::BindOnce(
             &VideoDecoderPipelineTest::CreateGoodMockTranscryptDecoder),
         StatusCode::kOk, &cdm_context_);
     testing::Mock::VerifyAndClearExpectations(&chromeos_cdm_context_);
@@ -283,7 +287,7 @@
 
 // Verifies the status code for several typical CreateDecoderFunctionCB cases.
 TEST_P(VideoDecoderPipelineTest, Initialize) {
-  InitializeDecoder(GetParam().create_decoder_function_cb,
+  InitializeDecoder(base::BindOnce(GetParam().create_decoder_function_cb),
                     GetParam().status_code);
 
   EXPECT_EQ(GetParam().status_code == StatusCode::kOk,
@@ -322,7 +326,7 @@
 // Verifies the Reset sequence.
 TEST_F(VideoDecoderPipelineTest, Reset) {
   InitializeDecoder(
-      base::BindRepeating(&VideoDecoderPipelineTest::CreateGoodMockDecoder),
+      base::BindOnce(&VideoDecoderPipelineTest::CreateGoodMockDecoder),
       StatusCode::kOk);
 
   // When we call Reset(), we expect GetUnderlyingDecoder()'s Reset() method to
diff --git a/media/gpu/vaapi/vaapi_jpeg_decoder.cc b/media/gpu/vaapi/vaapi_jpeg_decoder.cc
index 94d1eca..3f8fe43 100644
--- a/media/gpu/vaapi/vaapi_jpeg_decoder.cc
+++ b/media/gpu/vaapi/vaapi_jpeg_decoder.cc
@@ -333,8 +333,9 @@
   // can report the size that clients should be using to read the contents.
   scoped_va_context_and_surface_.reset(
       vaapi_wrapper_
-          ->CreateContextAndScopedVASurface(picture_va_rt_format,
-                                            new_coded_size, new_visible_size)
+          ->CreateContextAndScopedVASurface(
+              picture_va_rt_format, new_coded_size,
+              {VaapiWrapper::SurfaceUsageHint::kGeneric}, new_visible_size)
           .release());
   if (!scoped_va_context_and_surface_) {
     VLOGF(1) << "CreateContextAndScopedVASurface() failed";
diff --git a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
index f1a7853a..eed73a5f 100644
--- a/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_jpeg_encode_accelerator.cc
@@ -157,8 +157,8 @@
 
     std::vector<VASurfaceID> va_surfaces;
     if (!vaapi_wrapper_->CreateContextAndSurfaces(
-            va_format, input_size, VaapiWrapper::SurfaceUsageHint::kGeneric, 1,
-            &va_surfaces)) {
+            va_format, input_size, {VaapiWrapper::SurfaceUsageHint::kGeneric},
+            1, &va_surfaces)) {
       VLOGF(1) << "Failed to create VA surface";
       notify_error_cb_.Run(task_id, PLATFORM_FAILURE);
       return;
@@ -377,7 +377,7 @@
     std::vector<VASurfaceID> va_surfaces;
     if (!vaapi_wrapper_->CreateContextAndSurfaces(
             VA_RT_FORMAT_YUV420, input_size,
-            VaapiWrapper::SurfaceUsageHint::kGeneric, 1, &va_surfaces)) {
+            {VaapiWrapper::SurfaceUsageHint::kGeneric}, 1, &va_surfaces)) {
       VLOGF(1) << "Failed to create VA surface";
       notify_error_cb_.Run(task_id, PLATFORM_FAILURE);
       return;
diff --git a/media/gpu/vaapi/vaapi_unittest.cc b/media/gpu/vaapi/vaapi_unittest.cc
index 3e53a8a..10279cc 100644
--- a/media/gpu/vaapi/vaapi_unittest.cc
+++ b/media/gpu/vaapi/vaapi_unittest.cc
@@ -420,11 +420,15 @@
   ASSERT_NE(va_rt_format_out, kInvalidVaRtFormat);
 
   std::unique_ptr<ScopedVASurface> scoped_surface_in =
-      wrapper->CreateScopedVASurface(va_rt_format_in, kInputSize);
+      wrapper->CreateScopedVASurface(
+          va_rt_format_in, kInputSize,
+          {VaapiWrapper::SurfaceUsageHint::kGeneric});
   ASSERT_TRUE(!!scoped_surface_in);
 
   std::unique_ptr<ScopedVASurface> scoped_surface_out =
-      wrapper->CreateScopedVASurface(va_rt_format_out, kOutputSize);
+      wrapper->CreateScopedVASurface(
+          va_rt_format_out, kOutputSize,
+          {VaapiWrapper::SurfaceUsageHint::kGeneric});
   ASSERT_TRUE(!!scoped_surface_out);
 
   scoped_refptr<VASurface> surface_in = base::MakeRefCounted<VASurface>(
diff --git a/media/gpu/vaapi/vaapi_utils_unittest.cc b/media/gpu/vaapi/vaapi_utils_unittest.cc
index db435d2..3cf51ca 100644
--- a/media/gpu/vaapi/vaapi_utils_unittest.cc
+++ b/media/gpu/vaapi/vaapi_utils_unittest.cc
@@ -81,7 +81,9 @@
   std::vector<VASurfaceID> va_surfaces;
   const gfx::Size coded_size(64, 64);
   ASSERT_TRUE(vaapi_wrapper_->CreateContextAndSurfaces(
-      VA_RT_FORMAT_YUV420, coded_size, VaapiWrapper::SurfaceUsageHint::kGeneric,
+      VA_RT_FORMAT_YUV420, coded_size,
+      std::vector<VaapiWrapper::SurfaceUsageHint>{
+          VaapiWrapper::SurfaceUsageHint::kGeneric},
       1, &va_surfaces));
   ASSERT_EQ(va_surfaces.size(), 1u);
 
@@ -151,7 +153,8 @@
 TEST_F(VaapiUtilsTest, ScopedVASurface) {
   const gfx::Size coded_size(64, 64);
   auto scoped_va_surface = vaapi_wrapper_->CreateContextAndScopedVASurface(
-      VA_RT_FORMAT_YUV420, coded_size);
+      VA_RT_FORMAT_YUV420, coded_size,
+      {VaapiWrapper::SurfaceUsageHint::kGeneric});
 
   ASSERT_TRUE(scoped_va_surface);
   EXPECT_TRUE(scoped_va_surface->IsValid());
@@ -166,7 +169,8 @@
   const gfx::Size coded_size(64, 64);
   const gfx::Size visible_size(60, 60);
   auto scoped_va_surface = vaapi_wrapper_->CreateContextAndScopedVASurface(
-      VA_RT_FORMAT_YUV420, coded_size, visible_size);
+      VA_RT_FORMAT_YUV420, coded_size,
+      {VaapiWrapper::SurfaceUsageHint::kGeneric}, visible_size);
 
   ASSERT_TRUE(scoped_va_surface);
   EXPECT_TRUE(scoped_va_surface->IsValid());
@@ -180,7 +184,8 @@
 TEST_F(VaapiUtilsTest, ScopedVASurfaceInvalidSizeRequest) {
   const gfx::Size invalid_size(0, 0);
   EXPECT_FALSE(vaapi_wrapper_->CreateContextAndScopedVASurface(
-      VA_RT_FORMAT_YUV420, invalid_size));
+      VA_RT_FORMAT_YUV420, invalid_size,
+      {VaapiWrapper::SurfaceUsageHint::kGeneric}));
 }
 
 // This test exercises the creation of a ScopedVASurface with an invalid
@@ -188,7 +193,8 @@
 TEST_F(VaapiUtilsTest, ScopedVASurfaceInvalidRTFormatRequest) {
   const gfx::Size coded_size(64, 64);
   EXPECT_FALSE(vaapi_wrapper_->CreateContextAndScopedVASurface(
-      kInvalidVaRtFormat, coded_size));
+      kInvalidVaRtFormat, coded_size,
+      {VaapiWrapper::SurfaceUsageHint::kGeneric}));
 }
 
 }  // namespace media
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
index 9dccd60..98fbb54 100644
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -790,7 +790,7 @@
     RETURN_AND_NOTIFY_ON_FAILURE(
         vaapi_wrapper_->CreateContextAndSurfaces(
             va_surface_format_, requested_pic_size_,
-            VaapiWrapper::SurfaceUsageHint::kVideoDecoder,
+            {VaapiWrapper::SurfaceUsageHint::kVideoDecoder},
             requested_num_surfaces, &va_surface_ids),
         "Failed creating VA Surfaces", PLATFORM_FAILURE, );
 
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
index 0a9abad7..5b9a5433 100644
--- a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
+++ b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
@@ -74,7 +74,7 @@
   MOCK_METHOD5(CreateContextAndSurfaces,
                bool(unsigned int,
                     const gfx::Size&,
-                    SurfaceUsageHint,
+                    const std::vector<SurfaceUsageHint>&,
                     size_t,
                     std::vector<VASurfaceID>*));
   MOCK_METHOD1(CreateContext, bool(const gfx::Size&));
@@ -305,11 +305,12 @@
           vda_.buffer_allocation_mode_,
           VaapiVideoDecodeAccelerator::BufferAllocationMode::kSuperReduced);
       const size_t kNumReferenceFrames = 1 + num_pictures / 2;
-      EXPECT_CALL(
-          *mock_vaapi_wrapper_,
-          CreateContextAndSurfaces(
-              _, picture_size, VaapiWrapper::SurfaceUsageHint::kVideoDecoder,
-              kNumReferenceFrames, _))
+      EXPECT_CALL(*mock_vaapi_wrapper_,
+                  CreateContextAndSurfaces(
+                      _, picture_size,
+                      std::vector<VaapiWrapper::SurfaceUsageHint>{
+                          VaapiWrapper::SurfaceUsageHint::kVideoDecoder},
+                      kNumReferenceFrames, _))
           .WillOnce(DoAll(
               WithArg<4>(Invoke([kNumReferenceFrames](
                                     std::vector<VASurfaceID>* va_surface_ids) {
diff --git a/media/gpu/vaapi/vaapi_video_decoder.cc b/media/gpu/vaapi/vaapi_video_decoder.cc
index 0dc1688..1c56be2 100644
--- a/media/gpu/vaapi/vaapi_video_decoder.cc
+++ b/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -772,6 +772,7 @@
         std::unique_ptr<ScopedVASurface> surface =
             vaapi_wrapper_->CreateScopedVASurface(
                 base::strict_cast<unsigned int>(va_rt_format), decoder_pic_size,
+                {VaapiWrapper::SurfaceUsageHint::kVideoDecoder},
                 /*visible_size=*/absl::nullopt, va_fourcc);
         if (!surface) {
           while (!decode_surface_pool_for_scaling_.empty())
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
index 3940a180..e7d1835a 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -416,7 +416,7 @@
   // native input mode) is the coded size.
   if (!vaapi_wrapper_->CreateContextAndSurfaces(
           kVaSurfaceFormat, encoder_->GetCodedSize(),
-          VaapiWrapper::SurfaceUsageHint::kVideoEncoder,
+          {VaapiWrapper::SurfaceUsageHint::kVideoEncoder},
           (num_frames_in_flight_ + 1) * va_surfaces_per_video_frame_,
           &available_va_surface_ids_)) {
     NOTIFY_ERROR(kPlatformFailureError, "Failed creating VASurfaces");
@@ -559,34 +559,35 @@
     size_t num_va_surfaces) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_);
 
-  if (available_vpp_va_surface_ids_.find(encode_size) ==
-      available_vpp_va_surface_ids_.end()) {
-    // |vpp_vaapi_wrapper_| is filled in advance in unit test for multi spatial
-    // layer encoding.
-    if (!IsConfiguredForTesting()) {
-      DCHECK(!base::Contains(vpp_vaapi_wrapper_, encode_size));
-      auto vpp_va_wrapper = VaapiWrapper::Create(
-          VaapiWrapper::kVideoProcess, VAProfileNone,
-          EncryptionScheme::kUnencrypted,
-          base::BindRepeating(
-              &ReportVaapiErrorToUMA,
-              "Media.VaapiVideoEncodeAccelerator.Vpp.VAAPIError"));
-      if (!vpp_va_wrapper) {
-        NOTIFY_ERROR(kPlatformFailureError,
-                     "Failed to initialize VppVaapiWrapper");
-        return nullptr;
-      }
-
-      vpp_vaapi_wrapper_[encode_size] = std::move(vpp_va_wrapper);
+  if (!vpp_vaapi_wrapper_) {
+    vpp_vaapi_wrapper_ = VaapiWrapper::Create(
+        VaapiWrapper::kVideoProcess, VAProfileNone,
+        EncryptionScheme::kUnencrypted,
+        base::BindRepeating(
+            &ReportVaapiErrorToUMA,
+            "Media.VaapiVideoEncodeAccelerator.Vpp.VAAPIError"));
+    if (!vpp_vaapi_wrapper_) {
+      NOTIFY_ERROR(kPlatformFailureError,
+                   "Failed to initialize VppVaapiWrapper");
+      return nullptr;
     }
 
-    if (!vpp_vaapi_wrapper_[encode_size]->CreateContextAndSurfaces(
+    // VA context for VPP is not associated with a specific resolution.
+    if (!vpp_vaapi_wrapper_->CreateContext(gfx::Size())) {
+      NOTIFY_ERROR(kPlatformFailureError, "Failed creating Context for VPP");
+      return nullptr;
+    }
+  }
+
+  if (!base::Contains(available_vpp_va_surface_ids_, encode_size)) {
+    if (!vpp_vaapi_wrapper_->CreateSurfaces(
             kVaSurfaceFormat, encode_size,
-            VaapiWrapper::SurfaceUsageHint::kVideoProcessWrite, num_va_surfaces,
-            &available_vpp_va_surface_ids_[encode_size])) {
+            {VaapiWrapper::SurfaceUsageHint::kVideoProcessWrite,
+             VaapiWrapper::SurfaceUsageHint::kVideoEncoder},
+            num_va_surfaces, &available_vpp_va_surface_ids_[encode_size])) {
       NOTIFY_ERROR(kPlatformFailureError, "Failed creating VASurfaces");
       return nullptr;
-    };
+    }
 
     vpp_va_surface_release_cb_[encode_size] =
         BindToCurrentLoop(base::BindRepeating(
@@ -594,15 +595,16 @@
             encoder_weak_this_, &available_vpp_va_surface_ids_[encode_size]));
   }
 
+  DCHECK(!available_vpp_va_surface_ids_[encode_size].empty());
   // Scaling the input surface to dest size for K-SVC or simulcast.
   scoped_refptr<VASurface> blit_surface =
       new VASurface(available_vpp_va_surface_ids_[encode_size].back(),
                     encode_size, kVaSurfaceFormat,
                     base::BindOnce(vpp_va_surface_release_cb_[encode_size]));
   available_vpp_va_surface_ids_[encode_size].pop_back();
-  if (!vpp_vaapi_wrapper_[encode_size]->BlitSurface(
-          input_surface, *blit_surface, input_visible_rect,
-          gfx::Rect(encode_size))) {
+  if (!vpp_vaapi_wrapper_->BlitSurface(input_surface, *blit_surface,
+                                       input_visible_rect,
+                                       gfx::Rect(encode_size))) {
     NOTIFY_ERROR(kPlatformFailureError,
                  "Failed BlitSurface on frame size: "
                      << input_surface.size().ToString()
@@ -610,6 +612,7 @@
                      << ") -> encode size: " << encode_size.ToString());
     return nullptr;
   }
+
   return blit_surface;
 }
 
@@ -944,14 +947,16 @@
   // Clean up members that are to be accessed on the encoder thread only.
   if (vaapi_wrapper_)
     vaapi_wrapper_->DestroyContextAndSurfaces(available_va_surface_ids_);
-  for (auto& vpp : vpp_vaapi_wrapper_) {
-    DCHECK(base::Contains(available_vpp_va_surface_ids_, vpp.first));
-    vpp.second->DestroyContextAndSurfaces(
-        available_vpp_va_surface_ids_[vpp.first]);
-  }
-
+  available_va_surface_ids_.clear();
   available_va_buffer_ids_.clear();
 
+  if (vpp_vaapi_wrapper_) {
+    vpp_vaapi_wrapper_->DestroyContext();
+    for (const auto& surfaces : available_vpp_va_surface_ids_)
+      vpp_vaapi_wrapper_->DestroySurfaces(surfaces.second);
+    available_vpp_va_surface_ids_.clear();
+  }
+
   while (!available_bitstream_buffers_.empty())
     available_bitstream_buffers_.pop();
 
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.h b/media/gpu/vaapi/vaapi_video_encode_accelerator.h
index 7b442b089..0ae758c8 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator.h
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.h
@@ -203,9 +203,11 @@
   // Should only be used on |encoder_task_runner_|.
   std::unique_ptr<VaapiVideoEncoderDelegate> encoder_;
 
+  // TODO(crbug.com/1186051): Store ScopedVASurface, not VASurfaceID.
   // VA surfaces available for encoding.
   std::vector<VASurfaceID> available_va_surface_ids_;
   // VA surfaces available for scaling.
+  // TODO(crbug.com/1186051): Use base::small_map.
   std::map<gfx::Size, std::vector<VASurfaceID>, SizeComparator>
       available_vpp_va_surface_ids_;
 
@@ -217,6 +219,7 @@
 
   // Callback via which finished VA surfaces are returned to us.
   base::RepeatingCallback<void(VASurfaceID)> va_surface_release_cb_;
+  // TODO(crbug.com/1186051): Use base::small_map.
   std::map<gfx::Size, base::RepeatingCallback<void(VASurfaceID)>,
       SizeComparator> vpp_va_surface_release_cb_;
 
@@ -246,8 +249,7 @@
 
   // VaapiWrapper for VPP (Video Pre Processing). This is used for scale down
   // for the picture send to vaapi encoder.
-  std::map<gfx::Size, scoped_refptr<VaapiWrapper>, SizeComparator>
-      vpp_vaapi_wrapper_;
+  scoped_refptr<VaapiWrapper> vpp_vaapi_wrapper_;
 
   // The completion callback of the Flush() function.
   FlushCallback flush_callback_;
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc
index 485f9e82..e760e130 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator_unittest.cc
@@ -152,7 +152,7 @@
   MOCK_METHOD5(CreateContextAndSurfaces,
                bool(unsigned int,
                     const gfx::Size&,
-                    SurfaceUsageHint,
+                    const std::vector<SurfaceUsageHint>&,
                     size_t,
                     std::vector<VASurfaceID>*));
   MOCK_METHOD5(BlitSurface,
@@ -173,6 +173,12 @@
                bool(const VideoFrame&, VASurfaceID, const gfx::Size&));
   MOCK_METHOD1(ExecuteAndDestroyPendingBuffers, bool(VASurfaceID));
   MOCK_METHOD0(DestroyContext, void());
+  MOCK_METHOD5(CreateSurfaces,
+               bool(unsigned int,
+                    const gfx::Size&,
+                    const std::vector<SurfaceUsageHint>&,
+                    size_t,
+                    std::vector<VASurfaceID>*));
   MOCK_METHOD1(DestroySurfaces, void(std::vector<VASurfaceID> va_surface_ids));
 
  private:
@@ -281,19 +287,12 @@
     // Scaling is needed only for non highest spatial layer, so here the vpp
     // number is |num_spatial_layers - 1|.
     vpp_svc_va_surfaces_.resize(num_spatial_layers - 1);
-    vpp_svc_mock_vaapi_wrappers_.resize(num_spatial_layers - 1);
+    vpp_svc_mock_vaapi_wrapper_ =
+        base::MakeRefCounted<MockVaapiWrapper>(VaapiWrapper::kVideoProcess);
     auto* vaapi_encoder =
         reinterpret_cast<VaapiVideoEncodeAccelerator*>(encoder_.get());
-    for (size_t i = 0; i < num_spatial_layers - 1; ++i) {
-      vpp_svc_mock_vaapi_wrappers_[i] =
-          base::MakeRefCounted<MockVaapiWrapper>(VaapiWrapper::kVideoProcess);
-      const int denom =
-          kSpatialLayersResolutionDenom[num_spatial_layers - 1][i];
-      gfx::Size layer_size = gfx::Size(kDefaultEncodeSize.width() / denom,
-                                       kDefaultEncodeSize.height() / denom);
-      vaapi_encoder->vpp_vaapi_wrapper_[layer_size] =
-          vpp_svc_mock_vaapi_wrappers_[i];
-    }
+    vaapi_encoder->vpp_vaapi_wrapper_ = vpp_svc_mock_vaapi_wrapper_;
+
     EXPECT_CALL(*mock_encoder_,
                 Initialize(_, MatchesVaapiVideoEncoderDelegateConfig(
                                   kMaxNumOfRefFrames, kBitrateControl)))
@@ -301,7 +300,9 @@
     EXPECT_CALL(*mock_vaapi_wrapper_,
                 CreateContextAndSurfaces(
                     _, kDefaultEncodeSize,
-                    VaapiWrapper::SurfaceUsageHint::kVideoEncoder, _, _))
+                    std::vector<VaapiWrapper::SurfaceUsageHint>{
+                        VaapiWrapper::SurfaceUsageHint::kVideoEncoder},
+                    _, _))
         .WillOnce(WithArgs<3, 4>(
             [&surfaces = this->va_surfaces_](
                 size_t num_surfaces, std::vector<VASurfaceID>* va_surface_ids) {
@@ -470,10 +471,13 @@
       if (i < num_spatial_layers - 1) {
         if (vpp_svc_va_surfaces_[i].empty()) {
           EXPECT_CALL(
-              *vpp_svc_mock_vaapi_wrappers_[i],
-              CreateContextAndSurfaces(
+              *vpp_svc_mock_vaapi_wrapper_,
+              CreateSurfaces(
                   VA_RT_FORMAT_YUV420, layer_size,
-                  VaapiWrapper::SurfaceUsageHint::kVideoProcessWrite, _, _))
+                  std::vector<VaapiWrapper::SurfaceUsageHint>{
+                      VaapiWrapper::SurfaceUsageHint::kVideoProcessWrite,
+                      VaapiWrapper::SurfaceUsageHint::kVideoEncoder},
+                  _, _))
               .WillOnce(
                   WithArgs<3, 4>([&surfaces = this->vpp_svc_va_surfaces_[i]](
                                      size_t num_surfaces,
@@ -487,7 +491,7 @@
 
         absl::optional<gfx::Rect> default_rect = gfx::Rect(kDefaultEncodeSize);
         absl::optional<gfx::Rect> layer_rect = gfx::Rect(layer_size);
-        EXPECT_CALL(*vpp_svc_mock_vaapi_wrappers_[i],
+        EXPECT_CALL(*vpp_svc_mock_vaapi_wrapper_,
                     BlitSurface(_, _, default_rect, layer_rect,
                                 VideoRotation::VIDEO_ROTATION_0))
             .WillOnce(Return(true));
@@ -569,7 +573,7 @@
   // calls Destroy() so that destruction threading is respected.
   std::unique_ptr<VideoEncodeAccelerator> encoder_;
   scoped_refptr<MockVaapiWrapper> mock_vaapi_wrapper_;
-  std::vector<scoped_refptr<MockVaapiWrapper>> vpp_svc_mock_vaapi_wrappers_;
+  scoped_refptr<MockVaapiWrapper> vpp_svc_mock_vaapi_wrapper_;
   MockVP9VaapiVideoEncoderDelegate* mock_encoder_ = nullptr;
 };
 
diff --git a/media/gpu/vaapi/vaapi_webp_decoder.cc b/media/gpu/vaapi/vaapi_webp_decoder.cc
index ef395f914..a20af8f 100644
--- a/media/gpu/vaapi/vaapi_webp_decoder.cc
+++ b/media/gpu/vaapi/vaapi_webp_decoder.cc
@@ -112,7 +112,9 @@
     scoped_va_context_and_surface_.reset();
     scoped_va_context_and_surface_ = ScopedVAContextAndSurface(
         vaapi_wrapper_
-            ->CreateContextAndScopedVASurface(kWebPVARtFormat, new_visible_size)
+            ->CreateContextAndScopedVASurface(
+                kWebPVARtFormat, new_visible_size,
+                {VaapiWrapper::SurfaceUsageHint::kGeneric})
             .release());
     if (!scoped_va_context_and_surface_) {
       VLOGF(1) << "CreateContextAndScopedVASurface() failed";
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc
index b72315cb..1d910d62 100644
--- a/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -1733,7 +1733,7 @@
 bool VaapiWrapper::CreateContextAndSurfaces(
     unsigned int va_format,
     const gfx::Size& size,
-    SurfaceUsageHint surface_usage_hint,
+    const std::vector<SurfaceUsageHint>& surface_usage_hints,
     size_t num_surfaces,
     std::vector<VASurfaceID>* va_surfaces) {
   DVLOG(2) << "Creating " << num_surfaces << " surfaces";
@@ -1745,7 +1745,7 @@
     return false;
   }
 
-  if (!CreateSurfaces(va_format, size, surface_usage_hint, num_surfaces,
+  if (!CreateSurfaces(va_format, size, surface_usage_hints, num_surfaces,
                       va_surfaces)) {
     return false;
   }
@@ -1759,6 +1759,7 @@
 std::unique_ptr<ScopedVASurface> VaapiWrapper::CreateContextAndScopedVASurface(
     unsigned int va_format,
     const gfx::Size& size,
+    const std::vector<SurfaceUsageHint>& usage_hints,
     const absl::optional<gfx::Size>& visible_size) {
   if (va_context_id_ != VA_INVALID_ID) {
     LOG(ERROR) << "The current context should be destroyed before creating a "
@@ -1767,7 +1768,7 @@
   }
 
   std::unique_ptr<ScopedVASurface> scoped_va_surface =
-      CreateScopedVASurface(va_format, size, visible_size);
+      CreateScopedVASurface(va_format, size, usage_hints, visible_size);
   if (!scoped_va_surface)
     return nullptr;
 
@@ -2877,35 +2878,31 @@
   va_context_id_ = VA_INVALID_ID;
 }
 
-bool VaapiWrapper::CreateSurfaces(unsigned int va_format,
-                                  const gfx::Size& size,
-                                  SurfaceUsageHint usage_hint,
-                                  size_t num_surfaces,
-                                  std::vector<VASurfaceID>* va_surfaces) {
+bool VaapiWrapper::CreateSurfaces(
+    unsigned int va_format,
+    const gfx::Size& size,
+    const std::vector<SurfaceUsageHint>& usage_hints,
+    size_t num_surfaces,
+    std::vector<VASurfaceID>* va_surfaces) {
   DVLOG(2) << "Creating " << num_surfaces << " " << size.ToString()
            << " surfaces";
   DCHECK_NE(va_format, kInvalidVaRtFormat);
   DCHECK(va_surfaces->empty());
 
   va_surfaces->resize(num_surfaces);
-  VASurfaceAttrib attribute{};
+  VASurfaceAttrib attribute;
+  memset(&attribute, 0, sizeof(attribute));
   attribute.type = VASurfaceAttribUsageHint;
   attribute.flags = VA_SURFACE_ATTRIB_SETTABLE;
   attribute.value.type = VAGenericValueTypeInteger;
-  switch (usage_hint) {
-    case SurfaceUsageHint::kVideoDecoder:
-      attribute.value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER;
-      break;
-    case SurfaceUsageHint::kVideoEncoder:
-      attribute.value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER;
-      break;
-    case SurfaceUsageHint::kVideoProcessWrite:
-      attribute.value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE;
-      break;
-    case SurfaceUsageHint::kGeneric:
-      attribute.value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC;
-      break;
-  }
+  attribute.value.value.i = 0;
+  for (SurfaceUsageHint usage_hint : usage_hints)
+    attribute.value.value.i |= static_cast<int32_t>(usage_hint);
+  static_assert(std::is_same<decltype(attribute.value.value.i), int32_t>::value,
+                "attribute.value.value.i is not int32_t");
+  static_assert(std::is_same<std::underlying_type<SurfaceUsageHint>::type,
+                             int32_t>::value,
+                "The underlying type of SurfaceUsageHint is not int32_t");
 
   VAStatus va_res;
   {
@@ -2922,6 +2919,7 @@
 std::unique_ptr<ScopedVASurface> VaapiWrapper::CreateScopedVASurface(
     unsigned int va_rt_format,
     const gfx::Size& size,
+    const std::vector<SurfaceUsageHint>& usage_hints,
     const absl::optional<gfx::Size>& visible_size,
     uint32_t va_fourcc) {
   if (kInvalidVaRtFormat == va_rt_format) {
@@ -2934,20 +2932,29 @@
     return nullptr;
   }
 
-  VASurfaceAttrib attrib;
-  memset(&attrib, 0, sizeof(attrib));
+  VASurfaceAttrib attribs[2];
+  unsigned int num_attribs = 1;
+  memset(attribs, 0, sizeof(attribs));
+  attribs[0].type = VASurfaceAttribUsageHint;
+  attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
+  attribs[0].value.type = VAGenericValueTypeInteger;
+  attribs[0].value.value.i = 0;
+  for (SurfaceUsageHint usage_hint : usage_hints)
+    attribs[0].value.value.i |= static_cast<int32_t>(usage_hint);
+
   if (va_fourcc) {
-    attrib.type = VASurfaceAttribPixelFormat;
-    attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
-    attrib.value.type = VAGenericValueTypeInteger;
-    attrib.value.value.i = base::checked_cast<int32_t>(va_fourcc);
+    num_attribs += 1;
+    attribs[1].type = VASurfaceAttribPixelFormat;
+    attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
+    attribs[1].value.type = VAGenericValueTypeInteger;
+    attribs[1].value.value.i = base::checked_cast<int32_t>(va_fourcc);
   }
   base::AutoLock auto_lock(*va_lock_);
   VASurfaceID va_surface_id = VA_INVALID_ID;
   VAStatus va_res = vaCreateSurfaces(
       va_display_, va_rt_format, base::checked_cast<unsigned int>(size.width()),
       base::checked_cast<unsigned int>(size.height()), &va_surface_id, 1u,
-      va_fourcc ? &attrib : nullptr, va_fourcc ? 1 : 0);
+      attribs, num_attribs);
   VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVACreateSurfaces_Allocating,
                        nullptr);
 
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h
index a8da782..b446ea1 100644
--- a/media/gpu/vaapi/vaapi_wrapper.h
+++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -125,11 +125,11 @@
   };
 
   // This is enum associated with VASurfaceAttribUsageHint.
-  enum class SurfaceUsageHint : uint8_t {
-    kVideoDecoder,
-    kVideoEncoder,
-    kVideoProcessWrite,
-    kGeneric,
+  enum class SurfaceUsageHint : int32_t {
+    kGeneric = VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC,
+    kVideoDecoder = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER,
+    kVideoEncoder = VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER,
+    kVideoProcessWrite = VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE,
   };
 
   using InternalFormats = struct {
@@ -244,17 +244,17 @@
   static uint32_t GetProtectedInstanceID();
 
   // Creates |num_surfaces| VASurfaceIDs of |va_format|, |size| and
-  // |surface_usage_hint| and, if successful, creates a |va_context_id_| of the
-  // same size. |surface_usage_hint| may affect an alignment and tiling of the
+  // |surface_usage_hints| and, if successful, creates a |va_context_id_| of the
+  // same size. |surface_usage_hints| may affect an alignment and tiling of the
   // created surface. Returns true if successful, with the created IDs in
   // |va_surfaces|. The client is responsible for destroying |va_surfaces| via
   // DestroyContextAndSurfaces() to free the allocated surfaces.
-  virtual bool CreateContextAndSurfaces(unsigned int va_format,
-                                        const gfx::Size& size,
-                                        SurfaceUsageHint surface_usage_hint,
-                                        size_t num_surfaces,
-                                        std::vector<VASurfaceID>* va_surfaces)
-      WARN_UNUSED_RESULT;
+  virtual bool CreateContextAndSurfaces(
+      unsigned int va_format,
+      const gfx::Size& size,
+      const std::vector<SurfaceUsageHint>& surface_usage_hints,
+      size_t num_surfaces,
+      std::vector<VASurfaceID>* va_surfaces) WARN_UNUSED_RESULT;
 
   // Creates a single ScopedVASurface of |va_format| and |size| and, if
   // successful, creates a |va_context_id_| of the same size. Returns nullptr if
@@ -264,6 +264,7 @@
   std::unique_ptr<ScopedVASurface> CreateContextAndScopedVASurface(
       unsigned int va_format,
       const gfx::Size& size,
+      const std::vector<SurfaceUsageHint>& usage_hints,
       const absl::optional<gfx::Size>& visible_size = absl::nullopt);
 
   // Attempts to create a protected session that will be attached to the
@@ -310,6 +311,7 @@
   std::unique_ptr<ScopedVASurface> CreateScopedVASurface(
       unsigned int va_rt_format,
       const gfx::Size& size,
+      const std::vector<SurfaceUsageHint>& usage_hints,
       const absl::optional<gfx::Size>& visible_size = absl::nullopt,
       uint32_t va_fourcc = 0);
 
@@ -474,6 +476,17 @@
   // Initialize static data before sandbox is enabled.
   static void PreSandboxInitialization();
 
+  // TODO(crbug.com/1186051): Back to private in favor of using
+  // CreateScopedVASurface().
+  // Tries to allocate |num_surfaces| VASurfaceIDs of |size| and |va_format|.
+  // Fills |va_surfaces| and returns true if successful, or returns false.
+  virtual bool CreateSurfaces(unsigned int va_format,
+                              const gfx::Size& size,
+                              const std::vector<SurfaceUsageHint>& usage_hints,
+                              size_t num_surfaces,
+                              std::vector<VASurfaceID>* va_surfaces)
+      WARN_UNUSED_RESULT;
+
   // vaDestroySurfaces() a vector or a single VASurfaceID.
   virtual void DestroySurfaces(std::vector<VASurfaceID> va_surfaces);
   virtual void DestroySurface(VASurfaceID va_surface_id);
@@ -497,14 +510,6 @@
   bool VaInitialize(const ReportErrorToUMACB& report_error_to_uma_cb)
       WARN_UNUSED_RESULT;
 
-  // Tries to allocate |num_surfaces| VASurfaceIDs of |size| and |va_format|.
-  // Fills |va_surfaces| and returns true if successful, or returns false.
-  bool CreateSurfaces(unsigned int va_format,
-                      const gfx::Size& size,
-                      SurfaceUsageHint usage_hint,
-                      size_t num_surfaces,
-                      std::vector<VASurfaceID>* va_surfaces) WARN_UNUSED_RESULT;
-
   // Carries out the vaBeginPicture()-vaRenderPicture()-vaEndPicture() on target
   // |va_surface_id|. Returns false if any of these calls fails.
   bool Execute_Locked(VASurfaceID va_surface_id,
diff --git a/mojo/public/cpp/bindings/tests/remote_unittest.cc b/mojo/public/cpp/bindings/tests/remote_unittest.cc
index 21b8494..1b56fcdb 100644
--- a/mojo/public/cpp/bindings/tests/remote_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/remote_unittest.cc
@@ -1104,7 +1104,8 @@
   EXPECT_EQ(0, next_expected_value);
 }
 
-TEST_P(RemoteTest, DisconnectDuringOffThreadSyncWaitWithUnprocessedTasks) {
+// Flaky on all platforms. https://crbug.com/1224768
+TEST_P(RemoteTest, DISABLED_DisconnectDuringOffThreadSyncWaitWithUnprocessedTasks) {
   // Regression test for https://crbug.com/1223628.
   //
   // This tests a fairly obscure edge case where one or more message tasks is
diff --git a/net/cookies/cookie_inclusion_status.h b/net/cookies/cookie_inclusion_status.h
index ec394b9..454d2bde 100644
--- a/net/cookies/cookie_inclusion_status.h
+++ b/net/cookies/cookie_inclusion_status.h
@@ -5,6 +5,7 @@
 #ifndef NET_COOKIES_COOKIE_INCLUSION_STATUS_H_
 #define NET_COOKIES_COOKIE_INCLUSION_STATUS_H_
 
+#include <ostream>
 #include <string>
 #include <vector>
 
diff --git a/net/dns/host_cache.cc b/net/dns/host_cache.cc
index 9af27e2..74c9588 100644
--- a/net/dns/host_cache.cc
+++ b/net/dns/host_cache.cc
@@ -678,7 +678,7 @@
                                bool include_staleness,
                                SerializationType serialization_type) const {
   DCHECK(entry_list);
-  entry_list->Clear();
+  entry_list->ClearList();
 
   for (const auto& pair : entries_) {
     const Key& key = pair.first;
diff --git a/services/device/public/cpp/test/fake_usb_device.cc b/services/device/public/cpp/test/fake_usb_device.cc
index 9743f97..42d7379 100644
--- a/services/device/public/cpp/test/fake_usb_device.cc
+++ b/services/device/public/cpp/test/fake_usb_device.cc
@@ -231,7 +231,7 @@
 
 void FakeUsbDevice::ControlTransferOut(
     mojom::UsbControlTransferParamsPtr params,
-    const std::vector<uint8_t>& data,
+    base::span<const uint8_t> data,
     uint32_t timeout,
     ControlTransferOutCallback callback) {
   // Go on with mock device for testing.
@@ -292,7 +292,7 @@
 
 void FakeUsbDevice::IsochronousTransferOut(
     uint8_t endpoint_number,
-    const std::vector<uint8_t>& data,
+    base::span<const uint8_t> data,
     const std::vector<uint32_t>& packet_lengths,
     uint32_t timeout,
     IsochronousTransferOutCallback callback) {
diff --git a/services/device/public/cpp/test/fake_usb_device.h b/services/device/public/cpp/test/fake_usb_device.h
index a139495..1bb9cad 100644
--- a/services/device/public/cpp/test/fake_usb_device.h
+++ b/services/device/public/cpp/test/fake_usb_device.h
@@ -64,7 +64,7 @@
                          uint32_t timeout,
                          ControlTransferInCallback callback) override;
   void ControlTransferOut(mojom::UsbControlTransferParamsPtr params,
-                          const std::vector<uint8_t>& data,
+                          base::span<const uint8_t> data,
                           uint32_t timeout,
                           ControlTransferOutCallback callback) override;
   void GenericTransferIn(uint8_t endpoint_number,
@@ -80,7 +80,7 @@
                              uint32_t timeout,
                              IsochronousTransferInCallback callback) override;
   void IsochronousTransferOut(uint8_t endpoint_number,
-                              const std::vector<uint8_t>& data,
+                              base::span<const uint8_t> data,
                               const std::vector<uint32_t>& packet_lengths,
                               uint32_t timeout,
                               IsochronousTransferOutCallback callback) override;
diff --git a/services/device/public/cpp/test/mock_usb_mojo_device.cc b/services/device/public/cpp/test/mock_usb_mojo_device.cc
index 25e8bd9..6bdf2a27 100644
--- a/services/device/public/cpp/test/mock_usb_mojo_device.cc
+++ b/services/device/public/cpp/test/mock_usb_mojo_device.cc
@@ -32,7 +32,7 @@
 
 void MockUsbMojoDevice::IsochronousTransferOut(
     uint8_t endpoint_number,
-    const std::vector<uint8_t>& data,
+    base::span<const uint8_t> data,
     const std::vector<uint32_t>& packet_lengths,
     uint32_t timeout,
     IsochronousTransferOutCallback callback) {
diff --git a/services/device/public/cpp/test/mock_usb_mojo_device.h b/services/device/public/cpp/test/mock_usb_mojo_device.h
index 5cb402c..249f1c9e 100644
--- a/services/device/public/cpp/test/mock_usb_mojo_device.h
+++ b/services/device/public/cpp/test/mock_usb_mojo_device.h
@@ -85,14 +85,14 @@
                     ControlTransferInCallback*));
 
   void ControlTransferOut(mojom::UsbControlTransferParamsPtr params,
-                          const std::vector<uint8_t>& data,
+                          base::span<const uint8_t> data,
                           uint32_t timeout,
                           ControlTransferOutCallback callback) override {
     ControlTransferOutInternal(*params, data, timeout, &callback);
   }
   MOCK_METHOD4(ControlTransferOutInternal,
                void(const mojom::UsbControlTransferParams&,
-                    const std::vector<uint8_t>&,
+                    base::span<const uint8_t>,
                     uint32_t,
                     ControlTransferOutCallback*));
 
@@ -128,14 +128,14 @@
                                                uint32_t));
 
   void IsochronousTransferOut(uint8_t endpoint_number,
-                              const std::vector<uint8_t>& data,
+                              base::span<const uint8_t> data,
                               const std::vector<uint32_t>& packet_lengths,
                               uint32_t timeout,
                               IsochronousTransferOutCallback callback) override;
   MOCK_METHOD4(
       IsochronousTransferOutInternal,
       std::vector<mojom::UsbIsochronousPacket>(uint8_t,
-                                               const std::vector<uint8_t>&,
+                                               base::span<const uint8_t>,
                                                const std::vector<uint32_t>&,
                                                uint32_t));
 
diff --git a/services/device/public/mojom/usb_device.mojom b/services/device/public/mojom/usb_device.mojom
index 71643f4d..c393daf7 100644
--- a/services/device/public/mojom/usb_device.mojom
+++ b/services/device/public/mojom/usb_device.mojom
@@ -246,7 +246,7 @@
   ControlTransferIn(UsbControlTransferParams params,
                     uint32 length,
                     uint32 timeout)
-      => (UsbTransferStatus status, array<uint8> data);
+      => (UsbTransferStatus status, mojo_base.mojom.ReadOnlyBuffer data);
 
   // Initiates an inbound control transfer request. |params| determine the
   // details of the request. Transfers to recipients other than DEVICE require a
@@ -258,7 +258,7 @@
   // indicates no timeout: the request will remain pending indefinitely until
   // completed or otherwise terminated.
   ControlTransferOut(UsbControlTransferParams params,
-                     array<uint8> data,
+                     mojo_base.mojom.ReadOnlyBuffer data,
                      uint32 timeout)
       => (UsbTransferStatus status);
 
@@ -276,7 +276,7 @@
   // indicates no timeout: the request will remain pending indefinitely until
   // completed or otherwise terminated.
   GenericTransferIn(uint8 endpoint_number, uint32 length, uint32 timeout)
-      => (UsbTransferStatus status, array<uint8> data);
+      => (UsbTransferStatus status, mojo_base.mojom.ReadOnlyBuffer data);
 
   // Initiates an outbound generic transfer request on a specific endpoint. The
   // interface to which |endpoint_number| belongs must be claimed, and the
@@ -315,7 +315,8 @@
   IsochronousTransferIn(uint8 endpoint_number,
                         array<uint32> packet_lengths,
                         uint32 timeout)
-      => (array<uint8> data, array<UsbIsochronousPacket> packets);
+      => (mojo_base.mojom.ReadOnlyBuffer data,
+          array<UsbIsochronousPacket> packets);
 
   // Initiates an outbound isochronous transfer request on a specific endpoint.
   // The interface to which |endpoint_number| belongs must be claimed, and the
@@ -334,7 +335,7 @@
 
   // |packets| contains the status of each packet sent to the device, in order.
   IsochronousTransferOut(uint8 endpoint_number,
-                         array<uint8> data,
+                         mojo_base.mojom.ReadOnlyBuffer data,
                          array<uint32> packet_lengths,
                          uint32 timeout)
       => (array<UsbIsochronousPacket> packets);
diff --git a/services/device/usb/mojo/device_impl.cc b/services/device/usb/mojo/device_impl.cc
index b1bd9e4..5a14c6b7 100644
--- a/services/device/usb/mojo/device_impl.cc
+++ b/services/device/usb/mojo/device_impl.cc
@@ -37,15 +37,8 @@
                   UsbTransferStatus status,
                   scoped_refptr<base::RefCountedBytes> buffer,
                   size_t buffer_size) {
-  std::vector<uint8_t> data;
-  if (buffer) {
-    // TODO(rockot/reillyg): Take advantage of the ability to access the
-    // std::vector<uint8_t> within a base::RefCountedBytes to move instead of
-    // copy.
-    data.resize(buffer_size);
-    std::copy(buffer->front(), buffer->front() + buffer_size, data.begin());
-  }
-
+  auto data = buffer ? base::make_span(buffer->front(), buffer_size)
+                     : base::span<const uint8_t>();
   std::move(callback).Run(mojo::ConvertTo<mojom::UsbTransferStatus>(status),
                           data);
 }
@@ -61,19 +54,13 @@
     mojom::UsbDevice::IsochronousTransferInCallback callback,
     scoped_refptr<base::RefCountedBytes> buffer,
     std::vector<UsbIsochronousPacketPtr> packets) {
-  std::vector<uint8_t> data;
-  if (buffer) {
-    // TODO(rockot/reillyg): Take advantage of the ability to access the
-    // std::vector<uint8_t> within a base::RefCountedBytes to move instead of
-    // copy.
-    uint32_t buffer_size = std::accumulate(
-        packets.begin(), packets.end(), 0u,
-        [](const uint32_t& a, const UsbIsochronousPacketPtr& packet) {
-          return a + packet->length;
-        });
-    data.resize(buffer_size);
-    std::copy(buffer->front(), buffer->front() + buffer_size, data.begin());
-  }
+  uint32_t buffer_size = std::accumulate(
+      packets.begin(), packets.end(), 0u,
+      [](const uint32_t& a, const UsbIsochronousPacketPtr& packet) {
+        return a + packet->length;
+      });
+  auto data = buffer ? base::make_span(buffer->front(), buffer_size)
+                     : base::span<const uint8_t>();
   std::move(callback).Run(data, std::move(packets));
 }
 
@@ -88,7 +75,7 @@
 // configure an Android phone to act as a security key.
 bool IsAndroidSecurityKeyRequest(
     const mojom::UsbControlTransferParamsPtr& params,
-    const std::vector<uint8_t>& data) {
+    base::span<const uint8_t> data) {
   // This matches a request to send an AOA model string:
   // https://source.android.com/devices/accessories/aoa#attempt-to-start-in-accessory-mode
   //
@@ -344,7 +331,7 @@
 }
 
 void DeviceImpl::ControlTransferOut(UsbControlTransferParamsPtr params,
-                                    const std::vector<uint8_t>& data,
+                                    base::span<const uint8_t> data,
                                     uint32_t timeout,
                                     ControlTransferOutCallback callback) {
   if (!device_handle_) {
@@ -417,7 +404,7 @@
 
 void DeviceImpl::IsochronousTransferOut(
     uint8_t endpoint_number,
-    const std::vector<uint8_t>& data,
+    base::span<const uint8_t> data,
     const std::vector<uint32_t>& packet_lengths,
     uint32_t timeout,
     IsochronousTransferOutCallback callback) {
diff --git a/services/device/usb/mojo/device_impl.h b/services/device/usb/mojo/device_impl.h
index 11fb6c3..a4b2286 100644
--- a/services/device/usb/mojo/device_impl.h
+++ b/services/device/usb/mojo/device_impl.h
@@ -82,7 +82,7 @@
                          uint32_t timeout,
                          ControlTransferInCallback callback) override;
   void ControlTransferOut(mojom::UsbControlTransferParamsPtr params,
-                          const std::vector<uint8_t>& data,
+                          base::span<const uint8_t> data,
                           uint32_t timeout,
                           ControlTransferOutCallback callback) override;
   void GenericTransferIn(uint8_t endpoint_number,
@@ -98,7 +98,7 @@
                              uint32_t timeout,
                              IsochronousTransferInCallback callback) override;
   void IsochronousTransferOut(uint8_t endpoint_number,
-                              const std::vector<uint8_t>& data,
+                              base::span<const uint8_t> data,
                               const std::vector<uint32_t>& packet_lengths,
                               uint32_t timeout,
                               IsochronousTransferOutCallback callback) override;
diff --git a/services/device/usb/mojo/device_impl_unittest.cc b/services/device/usb/mojo/device_impl_unittest.cc
index c79d76c..8524e27 100644
--- a/services/device/usb/mojo/device_impl_unittest.cc
+++ b/services/device/usb/mojo/device_impl_unittest.cc
@@ -93,7 +93,7 @@
                              const std::vector<uint8_t>& expected_bytes,
                              base::OnceClosure continuation,
                              mojom::UsbTransferStatus actual_status,
-                             const std::vector<uint8_t>& actual_bytes) {
+                             base::span<const uint8_t> actual_bytes) {
   EXPECT_EQ(expected_status, actual_status);
   ASSERT_EQ(expected_bytes.size(), actual_bytes.size());
   for (size_t i = 0; i < actual_bytes.size(); ++i) {
@@ -121,7 +121,7 @@
     const std::vector<uint8_t>& expected_bytes,
     const std::vector<uint32_t>& expected_packets,
     base::OnceClosure continuation,
-    const std::vector<uint8_t>& actual_bytes,
+    base::span<const uint8_t> actual_bytes,
     std::vector<UsbIsochronousPacketPtr> actual_packets) {
   ASSERT_EQ(expected_packets.size(), actual_packets.size());
   for (size_t i = 0; i < expected_packets.size(); ++i) {
diff --git a/services/network/trust_tokens/trust_token_database_owner.cc b/services/network/trust_tokens/trust_token_database_owner.cc
index 55af4fd..6b02af7 100644
--- a/services/network/trust_tokens/trust_token_database_owner.cc
+++ b/services/network/trust_tokens/trust_token_database_owner.cc
@@ -17,6 +17,7 @@
 #include "components/sqlite_proto/key_value_table.h"
 #include "components/sqlite_proto/proto_table_manager.h"
 #include "services/network/trust_tokens/proto/storage.pb.h"
+#include "sql/database.h"
 
 namespace network {
 
@@ -79,7 +80,14 @@
       table_manager_(base::MakeRefCounted<sqlite_proto::ProtoTableManager>(
           db_task_runner)),
       db_task_runner_(db_task_runner),
-      backing_database_(std::make_unique<sql::Database>()),
+      backing_database_(std::make_unique<sql::Database>(sql::DatabaseOptions{
+          // As they work on deleting the feature (crbug.com/1120969), sql/
+          // owners prefer to see which clients are explicitly okay with using
+          // exclusive locking (the default).
+          .exclusive_locking = true,
+          .page_size = 4096,
+          .cache_size = 500,
+      })),
       issuer_table_(
           std::make_unique<sqlite_proto::KeyValueTable<TrustTokenIssuerConfig>>(
               kIssuerTableName)),
diff --git a/services/network/trust_tokens/trust_token_database_owner.h b/services/network/trust_tokens/trust_token_database_owner.h
index 0bb35ec8..b0ef18a 100644
--- a/services/network/trust_tokens/trust_token_database_owner.h
+++ b/services/network/trust_tokens/trust_token_database_owner.h
@@ -5,14 +5,22 @@
 #ifndef SERVICES_NETWORK_TRUST_TOKENS_TRUST_TOKEN_DATABASE_OWNER_H_
 #define SERVICES_NETWORK_TRUST_TOKENS_TRUST_TOKEN_DATABASE_OWNER_H_
 
+#include <memory>
+
+#include "base/callback.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/sequence_checker.h"
 #include "base/sequenced_task_runner.h"
+#include "base/time/time.h"
 #include "components/sqlite_proto/key_value_data.h"
 #include "components/sqlite_proto/key_value_table.h"
 #include "components/sqlite_proto/proto_table_manager.h"
 #include "services/network/trust_tokens/proto/storage.pb.h"
 
+namespace sql {
+class Database;
+}
+
 namespace network {
 
 // A TrustTokenDatabaseOwner does two things:
diff --git a/sql/README.md b/sql/README.md
index eb73d8c..25ecda4a 100644
--- a/sql/README.md
+++ b/sql/README.md
@@ -393,6 +393,10 @@
 Triggers significantly increase the difficulty of reviewing and maintaining
 Chrome features that use them.
 
+Triggers are not executed on SQLite databases opened with Chrome's
+`sql::Database` infrastructure. This is intended to steer feature developers
+away from the discouraged feature.
+
 After [WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we
 plan to disable SQLite's trigger support using
 [SQLITE_OMIT_TRIGGER](https://sqlite.org/compile.html#omit_trigger).
diff --git a/sql/database.cc b/sql/database.cc
index 2f223ab..f0f3156 100644
--- a/sql/database.cc
+++ b/sql/database.cc
@@ -238,6 +238,8 @@
               "DatabaseOptions::kDefaultPageSize must match the value "
               "configured into SQLite");
 
+// DatabaseOptions::explicit_locking needs to be set to false for historical
+// reasons.
 Database::Database() : Database({.exclusive_locking = false}) {}
 
 Database::Database(DatabaseOptions options)
@@ -1495,6 +1497,12 @@
       return false;
   }
 
+  // The use of triggers is discouraged for Chrome code. Thanks to this
+  // configuration change, triggers are not executed. CREATE TRIGGER and DROP
+  // TRIGGER still succeed.
+  err = sqlite3_db_config(db_, SQLITE_DBCONFIG_ENABLE_TRIGGER, 0, nullptr);
+  DCHECK_EQ(err, SQLITE_OK) << "sqlite3_db_config() should not fail";
+
   // Enable extended result codes to provide more color on I/O errors.
   // Not having extended result codes is not a fatal problem, as
   // Chromium code does not attempt to handle I/O errors anyhow.  The
diff --git a/sql/database.h b/sql/database.h
index 4d89fff..eea1380 100644
--- a/sql/database.h
+++ b/sql/database.h
@@ -92,20 +92,44 @@
 
   // Database page size.
   //
+  // New Chrome features should set an explicit page size in their
+  // DatabaseOptions initializers, even if they use the default page size. This
+  // makes it easier to track the page size used by the databases on the users'
+  // devices.
+  //
+  // The value in this option is only applied to newly created databases. In
+  // other words, changing the value doesn't impact the databases that have
+  // already been created on the users' devices. So, changing the value in the
+  // code without a lot of work (re-creating existing databases) will result in
+  // inconsistent page sizes across the fleet of user devices, which will make
+  // it (even) more difficult to reason about database performance.
+  //
   // Larger page sizes result in shallower B-trees, because they allow an inner
   // page to hold more keys. On the flip side, larger page sizes may result in
   // more I/O when making small changes to existing records.
   //
   // Must be a power of two between 512 and 65536 inclusive.
+  //
+  // TODO(pwnall): Replace the default with an invalid value after all
+  //               sql::Database users explicitly initialize page_size.
   int page_size = kDefaultPageSize;
 
   // The size of in-memory cache, in pages.
   //
+  // New Chrome features should set an explicit cache size in their
+  // DatabaseOptions initializers, even if they use the default cache size. This
+  // makes it easier to track the cache size used by the databases on the users'
+  // devices. The default page size of 4,096 bytes results in a cache size of
+  // 500 pages.
+  //
   // SQLite's database cache will take up at most (`page_size` * `cache_size`)
   // bytes of RAM.
   //
   // 0 invokes SQLite's default, which is currently to size up the cache to use
   // exactly 2,048,000 bytes of RAM.
+  //
+  // TODO(pwnall): Replace the default with an invalid value after all
+  //               sql::Database users explicitly initialize page_size.
   int cache_size = 0;
 };
 
@@ -113,20 +137,32 @@
 //
 // Instances of this class are thread-unsafe and DCHECK that they are accessed
 // on the same sequence.
+//
+// When a Database instance goes out of scope, any uncommitted transactions are
+// rolled back.
 class COMPONENT_EXPORT(SQL) Database {
  private:
   class StatementRef;  // Forward declaration, see real one below.
 
  public:
-  // The database is opened by calling Open[InMemory](). Any uncommitted
-  // transactions will be rolled back when this object is deleted.
+  // Creates an instance that can receive Open() / OpenInMemory() calls.
   //
+  // Some `options` members are only applied to newly created databases.
+  //
+  // Most operations on the new instance will fail until Open() / OpenInMemory()
+  // is called.
+  explicit Database(DatabaseOptions options);
+
   // This constructor is deprecated.
+  //
+  // When transitioning away from this default constructor, consider setting
+  // DatabaseOptions::explicit_locking to true. For historical reasons, this
+  // constructor results in DatabaseOptions::explicit_locking set to false.
+  //
   // TODO(crbug.com/1126968): Remove this constructor after migrating all
   //                          uses to the explicit constructor below.
   Database();
-  // |options| only affects newly created databases.
-  explicit Database(DatabaseOptions options);
+
   Database(const Database&) = delete;
   Database& operator=(const Database&) = delete;
   ~Database();
diff --git a/sql/database_unittest.cc b/sql/database_unittest.cc
index c7d85020..fa785bb 100644
--- a/sql/database_unittest.cc
+++ b/sql/database_unittest.cc
@@ -1387,6 +1387,27 @@
       << "Page cache usage should go down after calling TrimMemory()";
 }
 
+TEST_P(SQLDatabaseTest, TriggersDisabledByDefault) {
+  ASSERT_TRUE(db_->Execute("CREATE TABLE data(id INTEGER)"));
+
+  // sqlite3_db_config() currently only disables running triggers. Schema
+  // operations on triggers are still allowed.
+  EXPECT_TRUE(
+      db_->Execute("CREATE TRIGGER trigger AFTER INSERT ON data "
+                   "BEGIN DELETE FROM data; END"));
+
+  ASSERT_TRUE(db_->Execute("INSERT INTO data(id) VALUES(42)"));
+
+  Statement select(db_->GetUniqueStatement("SELECT id FROM data"));
+  EXPECT_TRUE(select.Step())
+      << "If the trigger did not run, the table should not be empty.";
+  EXPECT_EQ(42, select.ColumnInt64(0));
+
+  // sqlite3_db_config() currently only disables running triggers. Schema
+  // operations on triggers are still allowed.
+  EXPECT_TRUE(db_->Execute("DROP TRIGGER IF EXISTS trigger"));
+}
+
 class SQLDatabaseTestExclusiveMode : public testing::Test,
                                      public testing::WithParamInterface<bool> {
  public:
diff --git a/sql/recovery_unittest.cc b/sql/recovery_unittest.cc
index d5c541b..3f37a27 100644
--- a/sql/recovery_unittest.cc
+++ b/sql/recovery_unittest.cc
@@ -780,16 +780,10 @@
   ASSERT_TRUE(
       db_.Execute("CREATE VIEW v AS SELECT x.v FROM x, y WHERE x.v = y.v"));
 
-  // When an element is deleted from [x], trigger a delete on [y].  Between the
-  // BEGIN and END, [old] stands for the deleted rows from [x].
-  ASSERT_TRUE(
-      db_.Execute("CREATE TRIGGER t AFTER DELETE ON x "
-                  "BEGIN DELETE FROM y WHERE y.v = old.v; END"));
-
   // Save aside a copy of the original schema, verifying that it has the created
   // items plus the sqlite_sequence table.
   const std::string orig_schema(GetSchema(&db_));
-  ASSERT_EQ(6, std::count(orig_schema.begin(), orig_schema.end(), '\n'));
+  ASSERT_EQ(5, std::count(orig_schema.begin(), orig_schema.end(), '\n'));
 
   static const char kXSql[] = "SELECT * FROM x ORDER BY 1";
   static const char kYSql[] = "SELECT * FROM y ORDER BY 1";
@@ -815,13 +809,6 @@
   EXPECT_EQ("bob|truck\ndean|trailer\njim|telephone",
             ExecuteWithResults(&db_, kYSql, "|", "\n"));
   EXPECT_EQ("trailer\ntruck", ExecuteWithResults(&db_, kVSql, "|", "\n"));
-
-  // Test that the trigger works.
-  ASSERT_TRUE(db_.Execute("DELETE FROM x WHERE v = 'truck'"));
-  EXPECT_EQ("1|turtle\n3|trailer", ExecuteWithResults(&db_, kXSql, "|", "\n"));
-  EXPECT_EQ("dean|trailer\njim|telephone",
-            ExecuteWithResults(&db_, kYSql, "|", "\n"));
-  EXPECT_EQ("trailer", ExecuteWithResults(&db_, kVSql, "|", "\n"));
 }
 
 // When RecoverDatabase() encounters SQLITE_NOTADB, the database is deleted.
diff --git a/sql/statement.cc b/sql/statement.cc
index 56bcf296..1f479c2 100644
--- a/sql/statement.cc
+++ b/sql/statement.cc
@@ -139,76 +139,113 @@
   return is_valid() && succeeded_;
 }
 
-bool Statement::BindNull(int col) {
+bool Statement::BindNull(int param_index) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
+  if (!is_valid())
+    return false;
 
-  return is_valid() && CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
+  DCHECK_GE(param_index, 0);
+  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
+      << "Invalid parameter index";
+  return sqlite3_bind_null(ref_->stmt(), param_index + 1) == SQLITE_OK;
 }
 
-bool Statement::BindBool(int col, bool val) {
+bool Statement::BindBool(int param_index, bool val) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
 
-  return BindInt(col, val ? 1 : 0);
+  return BindInt64(param_index, val ? 1 : 0);
 }
 
-bool Statement::BindInt(int col, int val) {
+bool Statement::BindInt(int param_index, int val) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
+  if (!is_valid())
+    return false;
 
-  return is_valid() && CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
+  DCHECK_GE(param_index, 0);
+  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
+      << "Invalid parameter index";
+  return sqlite3_bind_int(ref_->stmt(), param_index + 1, val) == SQLITE_OK;
 }
 
-bool Statement::BindInt64(int col, int64_t val) {
+bool Statement::BindInt64(int param_index, int64_t val) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
+  if (!is_valid())
+    return false;
 
-  return is_valid() && CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
+  DCHECK_GE(param_index, 0);
+  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
+      << "Invalid parameter index";
+  return sqlite3_bind_int64(ref_->stmt(), param_index + 1, val) == SQLITE_OK;
 }
 
-bool Statement::BindDouble(int col, double val) {
+bool Statement::BindDouble(int param_index, double val) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
+  if (!is_valid())
+    return false;
 
-  return is_valid() && CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
+  DCHECK_GE(param_index, 0);
+  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
+      << "Invalid parameter index";
+  return sqlite3_bind_double(ref_->stmt(), param_index + 1, val) == SQLITE_OK;
 }
 
-bool Statement::BindTime(int col, base::Time val) {
+bool Statement::BindTime(int param_index, base::Time val) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
+  if (!is_valid())
+    return false;
 
+  DCHECK_GE(param_index, 0);
+  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
+      << "Invalid parameter index";
   int64_t int_value = val.ToDeltaSinceWindowsEpoch().InMicroseconds();
-  return is_valid() &&
-         CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, int_value));
+  return sqlite3_bind_int64(ref_->stmt(), param_index + 1, int_value) ==
+         SQLITE_OK;
 }
 
-bool Statement::BindCString(int col, const char* val) {
+bool Statement::BindCString(int param_index, const char* val) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
+  DCHECK(val);
+  if (!is_valid())
+    return false;
 
-  return is_valid() && CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, val, -1,
-                                                 SQLITE_TRANSIENT));
+  DCHECK_GE(param_index, 0);
+  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
+      << "Invalid parameter index";
+  return sqlite3_bind_text(ref_->stmt(), param_index + 1, val, -1,
+                           SQLITE_TRANSIENT) == SQLITE_OK;
 }
 
-bool Statement::BindString(int col, base::StringPiece value) {
+bool Statement::BindString(int param_index, base::StringPiece value) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
+  if (!is_valid())
+    return false;
+
+  DCHECK_GE(param_index, 0);
+  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
+      << "Invalid parameter index";
 
   // base::StringPiece::data() may return null for empty pieces. In particular,
   // this may happen when the StringPiece is created from the default
@@ -219,24 +256,29 @@
   static constexpr char kEmptyPlaceholder[] = {0x00};
   const char* data = (value.size() > 0) ? value.data() : kEmptyPlaceholder;
 
-  return is_valid() &&
-         CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, data, value.size(),
-                                   SQLITE_TRANSIENT));
+  return sqlite3_bind_text(ref_->stmt(), param_index + 1, data, value.size(),
+                           SQLITE_TRANSIENT) == SQLITE_OK;
 }
 
-bool Statement::BindString16(int col, base::StringPiece16 value) {
+bool Statement::BindString16(int param_index, base::StringPiece16 value) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
 
-  return BindString(col, base::UTF16ToUTF8(value));
+  return BindString(param_index, base::UTF16ToUTF8(value));
 }
 
-bool Statement::BindBlob(int col, base::span<const uint8_t> value) {
+bool Statement::BindBlob(int param_index, base::span<const uint8_t> value) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
+  if (!is_valid())
+    return false;
+
+  DCHECK_GE(param_index, 0);
+  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
+      << "Invalid parameter index";
 
   // span::data() may return null for empty spans. In particular, this may
   // happen when the span is created out of a std::vector, because
@@ -251,9 +293,8 @@
   static constexpr uint8_t kEmptyPlaceholder[] = {0x00};
   const uint8_t* data = (value.size() > 0) ? value.data() : kEmptyPlaceholder;
 
-  return is_valid() &&
-         CheckOk(sqlite3_bind_blob(ref_->stmt(), col + 1, data, value.size(),
-                                   SQLITE_TRANSIENT));
+  return sqlite3_bind_blob(ref_->stmt(), param_index + 1, data, value.size(),
+                           SQLITE_TRANSIENT) == SQLITE_OK;
 }
 
 int Statement::ColumnCount() const {
@@ -460,18 +501,6 @@
   return sqlite3_sql(ref_->stmt());
 }
 
-bool Statement::CheckOk(int err) const {
-#if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-#endif  // OS_ANDROID
-
-  // Binding to a non-existent variable is evidence of a serious error.
-  // TODO(gbillock,shess): make this invalidate the statement so it
-  // can't wreak havoc.
-  DCHECK_NE(err, SQLITE_RANGE) << "Bind value out of range";
-  return err == SQLITE_OK;
-}
-
 int Statement::CheckError(int err) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/sql/statement.h b/sql/statement.h
index 11018d26..120c553 100644
--- a/sql/statement.h
+++ b/sql/statement.h
@@ -117,24 +117,25 @@
 
   // Binding -------------------------------------------------------------------
 
-  // These all take a 0-based argument index and return true on success. You
+  // These all take a 0-based parameter index and return true on success. You
   // may not always care about the return value (they'll DCHECK if they fail).
   // The main thing you may want to check is when binding large blobs or
   // strings there may be out of memory.
-  bool BindNull(int col);
-  bool BindBool(int col, bool val);
-  bool BindInt(int col, int val);
-  bool BindInt(int col, int64_t val) = delete;  // Call BindInt64() instead.
-  bool BindInt64(int col, int64_t val);
-  bool BindDouble(int col, double val);
-  bool BindCString(int col, const char* val);
-  bool BindString(int col, base::StringPiece val);
-  bool BindString16(int col, base::StringPiece16 value);
-  bool BindBlob(int col, base::span<const uint8_t> value);
+  bool BindNull(int param_index);
+  bool BindBool(int param_index, bool val);
+  bool BindInt(int param_index, int val);
+  bool BindInt(int param_index,
+               int64_t val) = delete;  // Call BindInt64() instead.
+  bool BindInt64(int param_index, int64_t val);
+  bool BindDouble(int param_index, double val);
+  bool BindCString(int param_index, const char* val);
+  bool BindString(int param_index, base::StringPiece val);
+  bool BindString16(int param_index, base::StringPiece16 value);
+  bool BindBlob(int param_index, base::span<const uint8_t> value);
 
   // Overload that makes it easy to pass in std::string values.
-  bool BindBlob(int col, base::span<const char> value) {
-    return BindBlob(col, base::as_bytes(base::make_span(value)));
+  bool BindBlob(int param_index, base::span<const char> value) {
+    return BindBlob(param_index, base::as_bytes(base::make_span(value)));
   }
 
   // Conforms with base::Time serialization recommendations.
@@ -149,7 +150,7 @@
   //
   // TODO(crbug.com/1195962): Migrate all time serialization to this method, and
   //                          then remove the migration details above.
-  bool BindTime(int col, base::Time time);
+  bool BindTime(int param_index, base::Time time);
 
   // Retrieving ----------------------------------------------------------------
 
@@ -207,10 +208,6 @@
   // enhanced in the future to do the notification.
   int CheckError(int err);
 
-  // Contraction for checking an error code against SQLITE_OK. Does not set the
-  // succeeded flag.
-  bool CheckOk(int err) const;
-
   // Should be called by all mutating methods to check that the statement is
   // valid. Returns true if the statement is valid. DCHECKS and returns false
   // if it is not.
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index e81e1024..47ab03e4 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -10247,7 +10247,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.161"
+              "revision": "version:91.0.4472.162"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -10333,7 +10333,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.97"
+              "revision": "version:92.0.4515.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -10505,7 +10505,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.161"
+              "revision": "version:91.0.4472.162"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -10591,7 +10591,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.97"
+              "revision": "version:92.0.4515.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index d197b77b..573ced16 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -49495,7 +49495,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.161"
+              "revision": "version:91.0.4472.162"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49582,7 +49582,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.97"
+              "revision": "version:92.0.4515.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49756,7 +49756,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.161"
+              "revision": "version:91.0.4472.162"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -49843,7 +49843,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.97"
+              "revision": "version:92.0.4515.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50089,7 +50089,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.161"
+              "revision": "version:91.0.4472.162"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50175,7 +50175,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.97"
+              "revision": "version:92.0.4515.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50347,7 +50347,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.161"
+              "revision": "version:91.0.4472.162"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50433,7 +50433,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.97"
+              "revision": "version:92.0.4515.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50679,7 +50679,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.161"
+              "revision": "version:91.0.4472.162"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50765,7 +50765,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.97"
+              "revision": "version:92.0.4515.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -50937,7 +50937,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.161"
+              "revision": "version:91.0.4472.162"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -51023,7 +51023,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.97"
+              "revision": "version:92.0.4515.98"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 380c9f7..e0fa3b1 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -416,7 +416,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M92',
-          'revision': 'version:92.0.4515.97',
+          'revision': 'version:92.0.4515.98',
         }
       ],
     },
@@ -440,7 +440,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.161',
+          'revision': 'version:91.0.4472.162',
         }
       ],
     },
@@ -488,7 +488,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M92',
-          'revision': 'version:92.0.4515.97',
+          'revision': 'version:92.0.4515.98',
         }
       ],
     },
@@ -512,7 +512,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.161',
+          'revision': 'version:91.0.4472.162',
         }
       ],
     },
@@ -560,7 +560,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M92',
-          'revision': 'version:92.0.4515.97',
+          'revision': 'version:92.0.4515.98',
         }
       ],
     },
@@ -584,7 +584,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.161',
+          'revision': 'version:91.0.4472.162',
         }
       ],
     },
diff --git a/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc b/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc
index 475ce15..4857c53 100644
--- a/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc
+++ b/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc
@@ -55,9 +55,6 @@
     case WebSchedulerTrackedFeature::kOutstandingIndexedDBTransaction:
       return {"OutstandingIndexedDBTransaction",
               "outstanding IndexedDB transaction"};
-    case WebSchedulerTrackedFeature::kRequestedGeolocationPermission:
-      return {"RequestedGeolocationPermission",
-              "requested geolocation permission"};
     case WebSchedulerTrackedFeature::kRequestedNotificationsPermission:
       return {"RequestedNotificationsPermission",
               "requested notifications permission"};
@@ -178,7 +175,6 @@
       WebSchedulerTrackedFeature::kSubresourceHasCacheControlNoCache,
       WebSchedulerTrackedFeature::kContainsPlugins,
       WebSchedulerTrackedFeature::kDocumentLoaded,
-      WebSchedulerTrackedFeature::kRequestedGeolocationPermission,
       WebSchedulerTrackedFeature::kRequestedNotificationsPermission,
       WebSchedulerTrackedFeature::kRequestedMIDIPermission,
       WebSchedulerTrackedFeature::kRequestedAudioCapturePermission,
diff --git a/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h b/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
index 29b24181..424f94e 100644
--- a/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
+++ b/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
@@ -57,7 +57,7 @@
   // Whether the page tried to request a permission regardless of the outcome.
   // TODO(altimin): Track this more accurately depending on the data.
   // See permission.mojom for more details.
-  kRequestedGeolocationPermission = 19,
+  // kRequestedGeolocationPermission = 19,   // No longer blocking.
   kRequestedNotificationsPermission = 20,
   kRequestedMIDIPermission = 21,
   kRequestedAudioCapturePermission = 22,
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 241db85a..80b6aba 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -7754,7 +7754,6 @@
       DedicatedWorkerOrWorklet
       OutstandingNetworkRequestOthers
       OutstandingIndexedDBTransaction
-      RequestedGeolocationPermission
       RequestedNotificationsPermission
       RequestedMIDIPermission
       RequestedAudioCapturePermission
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom
index 50b301aa..ce22edf 100644
--- a/third_party/blink/public/mojom/frame/frame.mojom
+++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -510,11 +510,12 @@
       blink.mojom.FrameToken child_frame_token,
       blink.mojom.FramePolicy frame_policy);
 
-  // Notifies the browser that the frame changed the 'csp' attribute
-  // of one of its child frames.
-  DidChangeCSPAttribute(
+  // Notifies the browser that one of the iframe attributes tracked by the
+  // browser process changed.
+  DidChangeIframeAttributes(
       blink.mojom.FrameToken child_frame_token,
-      network.mojom.ContentSecurityPolicy? parsed_csp_attribute);
+      network.mojom.ContentSecurityPolicy? parsed_csp_attribute,
+      bool anonymous);
 
   // Sent by the renderer to request a paint preview of a subframe. |clip_rect|
   // is the size of the frame in it's parent. |guid| is an an identifier for
diff --git a/third_party/blink/public/web/web_performance.h b/third_party/blink/public/web/web_performance.h
index 07f178ca..fa2dfe0 100644
--- a/third_party/blink/public/web/web_performance.h
+++ b/third_party/blink/public/web/web_performance.h
@@ -139,6 +139,7 @@
   BLINK_EXPORT double ParseBlockedOnScriptExecutionFromDocumentWriteDuration()
       const;
   BLINK_EXPORT absl::optional<base::TimeTicks> LastPortalActivatedPaint() const;
+  BLINK_EXPORT absl::optional<base::TimeDelta> PrerenderActivationStart() const;
   BLINK_EXPORT absl::optional<base::TimeTicks> UnloadStart() const;
   BLINK_EXPORT absl::optional<base::TimeTicks> UnloadEnd() const;
   BLINK_EXPORT absl::optional<base::TimeTicks> CommitNavigationEnd() const;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index f937c8a..d8759ce9 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -60,6 +60,7 @@
 #include "third_party/blink/renderer/core/css/parser/css_selector_parser.h"
 #include "third_party/blink/renderer/core/css/property_set_css_style_declaration.h"
 #include "third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope.h"
+#include "third_party/blink/renderer/core/css/resolver/style_adjuster.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver_stats.h"
 #include "third_party/blink/renderer/core/css/selector_query.h"
@@ -141,6 +142,7 @@
 #include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
 #include "third_party/blink/renderer/core/layout/layout_text_fragment.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_combine.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/page/focus_controller.h"
 #include "third_party/blink/renderer/core/page/page.h"
@@ -3161,6 +3163,12 @@
 
   if (LayoutObject* layout_object = GetLayoutObject()) {
     DCHECK(new_style);
+    if (UNLIKELY(layout_object->IsText()) &&
+        UNLIKELY(IsA<LayoutNGTextCombine>(layout_object->Parent()))) {
+      // Adjust style for <br> and <wbr> in combined text.
+      // See http://crbug.com/1228058
+      StyleAdjuster::AdjustStyleForCombinedText(*new_style);
+    }
     scoped_refptr<const ComputedStyle> layout_style(std::move(new_style));
     if (auto* pseudo_element = DynamicTo<PseudoElement>(this)) {
       if (layout_style->Display() == EDisplay::kContents) {
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder.cc b/third_party/blink/renderer/core/dom/layout_tree_builder.cc
index 1c79343..72b080c8 100644
--- a/third_party/blink/renderer/core/dom/layout_tree_builder.cc
+++ b/third_party/blink/renderer/core/dom/layout_tree_builder.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/core/layout/layout_object.h"
 #include "third_party/blink/renderer/core/layout/layout_text.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_combine.h"
 #include "third_party/blink/renderer/core/svg/svg_element.h"
 #include "third_party/blink/renderer/core/svg_names.h"
 
@@ -146,6 +147,11 @@
   if (LayoutObject* wrapper = CreateInlineWrapperForDisplayContentsIfNeeded()) {
     layout_object_parent = wrapper;
     next_layout_object = nullptr;
+  } else if (next_layout_object) {
+    auto* const text_combine =
+        DynamicTo<LayoutNGTextCombine>(next_layout_object->Parent());
+    if (UNLIKELY(text_combine))
+      layout_object_parent = text_combine;
   }
 
   LegacyLayout legacy_layout = layout_object_parent->ForceLegacyLayout()
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder.h b/third_party/blink/renderer/core/dom/layout_tree_builder.h
index 1b34883..f7c0bbd 100644
--- a/third_party/blink/renderer/core/dom/layout_tree_builder.h
+++ b/third_party/blink/renderer/core/dom/layout_tree_builder.h
@@ -91,7 +91,7 @@
     auto* const text_combine_parent = parent->Parent();
     if (IsAnonymousInline(text_combine_parent))
       return text_combine_parent;
-    return parent;
+    return next;
   }
 
   static bool IsAnonymousInline(const LayoutObject* layout_object) {
diff --git a/third_party/blink/renderer/core/exported/web_performance.cc b/third_party/blink/renderer/core/exported/web_performance.cc
index 99a7e8f4..3fea958 100644
--- a/third_party/blink/renderer/core/exported/web_performance.cc
+++ b/third_party/blink/renderer/core/exported/web_performance.cc
@@ -308,6 +308,11 @@
   return private_->timing()->LastPortalActivatedPaint();
 }
 
+absl::optional<base::TimeDelta> WebPerformance::PrerenderActivationStart()
+    const {
+  return private_->timing()->PrerenderActivationStart();
+}
+
 absl::optional<base::TimeTicks> WebPerformance::UnloadStart() const {
   return private_->timing()->UnloadStart();
 }
diff --git a/third_party/blink/renderer/core/frame/frame_owner.h b/third_party/blink/renderer/core/frame/frame_owner.h
index e9399489..956f1382 100644
--- a/third_party/blink/renderer/core/frame/frame_owner.h
+++ b/third_party/blink/renderer/core/frame/frame_owner.h
@@ -68,7 +68,7 @@
 
  protected:
   virtual void FrameOwnerPropertiesChanged() {}
-  virtual void CSPAttributeChanged() {}
+  virtual void DidChangeAttributes() {}
 
  private:
   virtual void SetIsSwappingFrames(bool) {}
@@ -97,7 +97,7 @@
     if (frame_owner_) {
       frame_owner_->SetIsSwappingFrames(false);
       frame_owner_->FrameOwnerPropertiesChanged();
-      frame_owner_->CSPAttributeChanged();
+      frame_owner_->DidChangeAttributes();
     }
   }
 
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
index 3f7e547..c91b266e 100644
--- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc
+++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -582,8 +582,8 @@
   if (!child_frame)
     return false;
 
-  // Send 'csp' attribute to the browser.
-  CSPAttributeChanged();
+  // Propagate attributes like 'csp' or 'anonymous' to the browser process.
+  DidChangeAttributes();
 
   WebFrameLoadType child_load_type = WebFrameLoadType::kReplaceCurrentItem;
   // If the frame URL is not about:blank, see if it should do a
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc
index 42cb5477..c60e3281 100644
--- a/third_party/blink/renderer/core/html/html_iframe_element.cc
+++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -219,9 +219,16 @@
     }
     if (required_csp_ != value) {
       required_csp_ = value;
-      CSPAttributeChanged();
+      DidChangeAttributes();
       UseCounter::Count(GetDocument(), WebFeature::kIFrameCSPAttribute);
     }
+  } else if (name == html_names::kAnonymousAttr &&
+             RuntimeEnabledFeatures::AnonymousIframeEnabled()) {
+    bool new_value = !value.IsNull();
+    if (anonymous_ != new_value) {
+      anonymous_ = new_value;
+      DidChangeAttributes();
+    }
   } else if (name == html_names::kAllowAttr) {
     if (allow_ != value) {
       allow_ = value;
@@ -461,7 +468,7 @@
   return parsed_params;
 }
 
-void HTMLIFrameElement::CSPAttributeChanged() {
+void HTMLIFrameElement::DidChangeAttributes() {
   // Don't notify about updates if ContentFrame() is null, for example when
   // the subframe hasn't been created yet; or if we are in the middle of
   // swapping one frame for another, in which case the final state
@@ -482,9 +489,9 @@
           network::mojom::blink::ContentSecurityPolicySource::kHTTP, KURL());
   DCHECK_LE(csp.size(), 1u);
 
-  GetDocument().GetFrame()->GetLocalFrameHostRemote().DidChangeCSPAttribute(
+  GetDocument().GetFrame()->GetLocalFrameHostRemote().DidChangeIframeAttributes(
       ContentFrame()->GetFrameToken(),
-      csp.IsEmpty() ? nullptr : std::move(csp[0]));
+      csp.IsEmpty() ? nullptr : std::move(csp[0]), anonymous_);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.h b/third_party/blink/renderer/core/html/html_iframe_element.h
index dc8bf2a..2e962777 100644
--- a/third_party/blink/renderer/core/html/html_iframe_element.h
+++ b/third_party/blink/renderer/core/html/html_iframe_element.h
@@ -87,7 +87,7 @@
   // FrameOwner overrides:
   bool AllowFullscreen() const override { return allow_fullscreen_; }
   bool AllowPaymentRequest() const override { return allow_payment_request_; }
-  void CSPAttributeChanged() override;
+  void DidChangeAttributes() override;
 
   AtomicString name_;
   AtomicString required_csp_;
@@ -100,6 +100,7 @@
   bool allow_fullscreen_;
   bool allow_payment_request_;
   bool collapsed_by_client_;
+  bool anonymous_ = false;
   Member<HTMLIFrameElementSandbox> sandbox_;
   Member<DOMFeaturePolicy> policy_;
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
index 233992b6..48c0372 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -33,7 +33,6 @@
 #include "third_party/blink/renderer/core/layout/layout_inline.h"
 #include "third_party/blink/renderer/core/layout/layout_object.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
-#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.h"
@@ -1028,6 +1027,59 @@
          layout_flex->StyleRef().ResolvedIsColumnFlexDirection();
 }
 
+Vector<Vector<std::pair<PhysicalRect, float>>> GetFlexLinesAndItems(
+    LayoutBox* layout_box,
+    bool is_horizontal,
+    bool is_reverse) {
+  Vector<Vector<std::pair<PhysicalRect, float>>> flex_lines;
+
+  // Flex containers can't get fragmented yet, but this may change in the
+  // future.
+  for (const auto& fragment : layout_box->PhysicalFragments()) {
+    LayoutUnit progression;
+
+    for (const auto& child : fragment.Children()) {
+      const NGPhysicalFragment* child_fragment = child.get();
+      if (!child_fragment || child_fragment->IsOutOfFlowPositioned())
+        continue;
+
+      PhysicalSize fragment_size = child_fragment->Size();
+      PhysicalOffset fragment_offset = child.Offset();
+
+      const LayoutObject* object = child_fragment->GetLayoutObject();
+      const auto* box = To<LayoutBox>(object);
+
+      LayoutUnit baseline =
+          NGBoxFragment(box->StyleRef().GetWritingDirection(),
+                        *To<NGPhysicalBoxFragment>(child_fragment))
+              .BaselineOrSynthesize();
+      float adjusted_baseline = AdjustForAbsoluteZoom::AdjustFloat(
+          baseline + box->MarginTop(), box->StyleRef());
+
+      PhysicalRect item_rect =
+          PhysicalRect(fragment_offset.left - box->MarginLeft(),
+                       fragment_offset.top - box->MarginTop(),
+                       fragment_size.width + box->MarginWidth(),
+                       fragment_size.height + box->MarginHeight());
+
+      LayoutUnit item_start = is_horizontal ? item_rect.X() : item_rect.Y();
+      LayoutUnit item_end = is_horizontal ? item_rect.X() + item_rect.Width()
+                                          : item_rect.Y() + item_rect.Height();
+
+      if (flex_lines.IsEmpty() ||
+          (is_reverse ? item_end > progression : item_start < progression)) {
+        flex_lines.emplace_back();
+      }
+
+      flex_lines.back().push_back(std::make_pair(item_rect, adjusted_baseline));
+
+      progression = is_reverse ? item_start : item_end;
+    }
+  }
+
+  return flex_lines;
+}
+
 std::unique_ptr<protocol::DictionaryValue> BuildFlexContainerInfo(
     Node* node,
     const InspectorFlexContainerHighlightConfig&
@@ -1054,11 +1106,9 @@
   FrameQuadToViewport(containing_view, content_quad);
   container_builder.AppendPath(QuadToPath(content_quad), scale);
 
-  DevtoolsFlexInfo flex_info_from_layout =
-      To<LayoutNGFlexibleBox>(layout_object)->LayoutForDevtools();
-
-  Vector<blink::DevtoolsFlexInfo::Line> flex_lines =
-      flex_info_from_layout.lines;
+  // Gather all flex items, sorted by flex line.
+  Vector<Vector<std::pair<PhysicalRect, float>>> flex_lines =
+      GetFlexLinesAndItems(layout_box, is_horizontal, is_reverse);
 
   // We send a list of flex lines, each containing a list of flex items, with
   // their baselines, to the frontend.
@@ -1067,20 +1117,18 @@
   for (auto line : flex_lines) {
     std::unique_ptr<protocol::ListValue> items_info =
         protocol::ListValue::create();
-
-    for (auto& item : line.items) {
+    for (auto item_data : line) {
       std::unique_ptr<protocol::DictionaryValue> item_info =
           protocol::DictionaryValue::create();
 
       FloatQuad item_margin_quad =
-          layout_object->LocalRectToAbsoluteQuad(item.rect);
+          layout_object->LocalRectToAbsoluteQuad(item_data.first);
       FrameQuadToViewport(containing_view, item_margin_quad);
       PathBuilder item_builder;
       item_builder.AppendPath(QuadToPath(item_margin_quad), scale);
 
       item_info->setValue("itemBorder", item_builder.Release());
-
-      item_info->setDouble("baseline", item.baseline);
+      item_info->setDouble("baseline", item_data.second);
 
       items_info->pushValue(std::move(item_info));
     }
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
index b95e830f..df59515 100644
--- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -794,18 +794,9 @@
   dict.Add("priority", ResourcePriorityString(load_priority));
 }
 
-void inspector_send_request_event::Data(
-    perfetto::TracedValue context,
-    DocumentLoader* loader,
-    uint64_t identifier,
-    LocalFrame* frame,
-    const ResourceRequest& request,
+namespace {
+String GetRenderBlockingStringFromBehavior(
     RenderBlockingBehavior render_blocking_behavior) {
-  auto dict = std::move(context).WriteDictionary();
-  dict.Add("requestId", IdentifiersFactory::RequestId(loader, identifier));
-  dict.Add("frame", IdentifiersFactory::FrameId(frame));
-  dict.Add("url", request.Url().GetString());
-  dict.Add("requestMethod", request.HttpMethod());
   String render_blocking_string;
   switch (render_blocking_behavior) {
     case RenderBlockingBehavior::kUnset:
@@ -828,6 +819,25 @@
     default:
       NOTREACHED();
   }
+  return render_blocking_string;
+}
+
+}  // namespace
+
+void inspector_send_request_event::Data(
+    perfetto::TracedValue context,
+    DocumentLoader* loader,
+    uint64_t identifier,
+    LocalFrame* frame,
+    const ResourceRequest& request,
+    RenderBlockingBehavior render_blocking_behavior) {
+  auto dict = std::move(context).WriteDictionary();
+  dict.Add("requestId", IdentifiersFactory::RequestId(loader, identifier));
+  dict.Add("frame", IdentifiersFactory::FrameId(frame));
+  dict.Add("url", request.Url().GetString());
+  dict.Add("requestMethod", request.HttpMethod());
+  String render_blocking_string =
+      GetRenderBlockingStringFromBehavior(render_blocking_behavior);
   if (!render_blocking_string.IsNull()) {
     dict.Add("renderBlocking", render_blocking_string);
   }
@@ -837,6 +847,24 @@
   SetCallStack(dict);
 }
 
+void inspector_change_render_blocking_behavior_event::Data(
+    perfetto::TracedValue context,
+    DocumentLoader* loader,
+    uint64_t identifier,
+    const ResourceRequestHead& request,
+    RenderBlockingBehavior render_blocking_behavior) {
+  String request_id = IdentifiersFactory::RequestId(loader, identifier);
+
+  auto dict = std::move(context).WriteDictionary();
+  dict.Add("requestId", request_id);
+  dict.Add("url", request.Url().GetString());
+  String render_blocking_string =
+      GetRenderBlockingStringFromBehavior(render_blocking_behavior);
+  if (!render_blocking_string.IsNull()) {
+    dict.Add("renderBlocking", render_blocking_string);
+  }
+}
+
 void inspector_send_navigation_request_event::Data(
     perfetto::TracedValue context,
     DocumentLoader* loader,
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.h b/third_party/blink/renderer/core/inspector/inspector_trace_events.h
index f397c84..9b54ad9 100644
--- a/third_party/blink/renderer/core/inspector/inspector_trace_events.h
+++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.h
@@ -68,6 +68,7 @@
 class ResourceError;
 struct ResourceLoaderOptions;
 class ResourceRequest;
+class ResourceRequestHead;
 class ResourceResponse;
 class StyleChangeReasonForTracing;
 class StyleImage;
@@ -323,6 +324,14 @@
           RenderBlockingBehavior);
 }
 
+namespace inspector_change_render_blocking_behavior_event {
+void Data(perfetto::TracedValue context,
+          DocumentLoader*,
+          uint64_t identifier,
+          const ResourceRequestHead&,
+          RenderBlockingBehavior);
+}
+
 namespace inspector_send_navigation_request_event {
 void Data(perfetto::TracedValue context,
           DocumentLoader*,
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 62f8d164..c668328 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -3864,6 +3864,21 @@
 
   if (LocalFrameView* frame_view = GetFrameView())
     frame_view->GetPaintTimingDetector().LayoutObjectWillBeDestroyed(*this);
+
+  // Merge |next_text_combine| into |previous_text_combine| if needed.
+  // See http:://crbug.com/1227066
+  auto* const previous_text_combine =
+      DynamicTo<LayoutNGTextCombine>(PreviousSibling());
+  if (LIKELY(!previous_text_combine))
+    return;
+  auto* const next_text_combine = DynamicTo<LayoutNGTextCombine>(NextSibling());
+  if (LIKELY(!next_text_combine))
+    return;
+  while (auto* child = next_text_combine->FirstChild()) {
+    next_text_combine->RemoveChild(child);
+    previous_text_combine->AddChild(child);
+  }
+  Parent()->RemoveChild(next_text_combine);
 }
 
 void LayoutObject::SetNeedsPaintPropertyUpdate() {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_combine_test.cc b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_combine_test.cc
index c3853bc..7b7df81f 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_combine_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_combine_test.cc
@@ -136,6 +136,36 @@
             ToSimpleLayoutTree(root_layout_object));
 }
 
+// http://crbug.com/1228058
+TEST_F(LayoutNGTextCombineTest, ElementRecalcOwnStyle) {
+  InsertStyleElement(
+      "#root { text-combine-upright: all; writing-mode: vertical-rl; }");
+  SetBodyInnerHTML("<div id=root><br id=target></div>");
+  auto& root = *GetElementById("root");
+  const auto& root_layout_object =
+      *To<LayoutNGBlockFlow>(root.GetLayoutObject());
+
+  EXPECT_EQ(R"DUMP(
+LayoutNGBlockFlow DIV id="root"
+  +--LayoutNGTextCombine (anonymous)
+  |  +--LayoutBR BR id="target"
+)DUMP",
+            ToSimpleLayoutTree(root_layout_object));
+
+  // Call |Element::RecalcOwnStyle()| for <br>
+  auto& target = *GetElementById("target");
+  target.style()->setProperty(GetDocument().GetExecutionContext(), "color",
+                              "red", "", ASSERT_NO_EXCEPTION);
+  RunDocumentLifecycle();
+
+  EXPECT_EQ(R"DUMP(
+LayoutNGBlockFlow DIV id="root"
+  +--LayoutNGTextCombine (anonymous)
+  |  +--LayoutBR BR id="target" style="color: red;"
+)DUMP",
+            ToSimpleLayoutTree(root_layout_object));
+}
+
 TEST_F(LayoutNGTextCombineTest, InkOverflow) {
   LoadAhem();
   InsertStyleElement(
@@ -812,6 +842,73 @@
             ToSimpleLayoutTree(root_layout_object));
 }
 
+// http://crbug.com/1227066
+TEST_F(LayoutNGTextCombineTest, RemoveChildToOneCombinedText) {
+  InsertStyleElement(
+      "div { text-combine-upright: all; }"
+      "div { writing-mode: vertical-rl; }");
+  SetBodyInnerHTML("<div id=root>a<b id=t>x</b>z</div>");
+  auto& root = *GetElementById("root");
+  const auto& root_layout_object =
+      *To<LayoutNGBlockFlow>(root.GetLayoutObject());
+  EXPECT_EQ(R"DUMP(
+LayoutNGBlockFlow DIV id="root"
+  +--LayoutNGTextCombine (anonymous)
+  |  +--LayoutText #text "a"
+  +--LayoutInline B id="t"
+  |  +--LayoutNGTextCombine (anonymous)
+  |  |  +--LayoutText #text "x"
+  +--LayoutNGTextCombine (anonymous)
+  |  +--LayoutText #text "z"
+)DUMP",
+            ToSimpleLayoutTree(root_layout_object));
+
+  GetElementById("t")->remove();
+  RunDocumentLifecycle();
+
+  EXPECT_EQ(R"DUMP(
+LayoutNGBlockFlow DIV id="root"
+  +--LayoutNGTextCombine (anonymous)
+  |  +--LayoutText #text "a"
+  |  +--LayoutText #text "z"
+)DUMP",
+            ToSimpleLayoutTree(root_layout_object));
+}
+
+// http://crbug.com/1227066
+TEST_F(LayoutNGTextCombineTest, ReplaceChildToOneCombinedText) {
+  InsertStyleElement(
+      "div { text-combine-upright: all; }"
+      "div { writing-mode: vertical-rl; }");
+  SetBodyInnerHTML("<div id=root>a<b id=t>x</b>z</div>");
+  auto& root = *GetElementById("root");
+  const auto& root_layout_object =
+      *To<LayoutNGBlockFlow>(root.GetLayoutObject());
+  EXPECT_EQ(R"DUMP(
+LayoutNGBlockFlow DIV id="root"
+  +--LayoutNGTextCombine (anonymous)
+  |  +--LayoutText #text "a"
+  +--LayoutInline B id="t"
+  |  +--LayoutNGTextCombine (anonymous)
+  |  |  +--LayoutText #text "x"
+  +--LayoutNGTextCombine (anonymous)
+  |  +--LayoutText #text "z"
+)DUMP",
+            ToSimpleLayoutTree(root_layout_object));
+
+  root.replaceChild(Text::Create(GetDocument(), "X"), GetElementById("t"));
+  RunDocumentLifecycle();
+
+  EXPECT_EQ(R"DUMP(
+LayoutNGBlockFlow DIV id="root"
+  +--LayoutNGTextCombine (anonymous)
+  |  +--LayoutText #text "a"
+  |  +--LayoutText #text "X"
+  |  +--LayoutText #text "z"
+)DUMP",
+            ToSimpleLayoutTree(root_layout_object));
+}
+
 TEST_F(LayoutNGTextCombineTest, SetDataToEmpty) {
   InsertStyleElement(
       "c { text-combine-upright: all; }"
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
index e97cebd..a7c85ce 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
 
+#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
 #include "third_party/blink/renderer/platform/wtf/size_assertions.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
@@ -20,21 +21,72 @@
 
 }  // namespace
 
+const NGBlockBreakToken* const*
+NGInlineBreakToken::BlockInInlineBreakTokenAddress() const {
+  CHECK(flags_ & kHasBlockInInlineToken);
+  return block_in_inline_break_token_;
+}
+
+const NGBlockBreakToken* NGInlineBreakToken::BlockInInlineBreakToken() const {
+  if (!(flags_ & kHasBlockInInlineToken))
+    return nullptr;
+  const NGBlockBreakToken* const* ptr = BlockInInlineBreakTokenAddress();
+  DCHECK(*ptr);
+  return *ptr;
+}
+
+// static
+scoped_refptr<NGInlineBreakToken> NGInlineBreakToken::Create(
+    NGInlineNode node,
+    const ComputedStyle* style,
+    unsigned item_index,
+    unsigned text_offset,
+    unsigned flags /* NGInlineBreakTokenFlags */,
+    const NGBlockBreakToken* block_in_inline_break_token) {
+  // We store the children list inline in the break token as a flexible
+  // array. Therefore, we need to make sure to allocate enough space for that
+  // array here, which requires a manual allocation + placement new.
+  wtf_size_t size = sizeof(NGInlineBreakToken);
+  if (UNLIKELY(block_in_inline_break_token)) {
+    size += sizeof(NGBlockBreakToken*);
+    flags |= kHasBlockInInlineToken;
+  }
+
+  void* data = ::WTF::Partitions::FastMalloc(
+      size, ::WTF::GetStringWithTypeName<NGInlineBreakToken>());
+  new (data) NGInlineBreakToken(PassKey(), node, style, item_index, text_offset,
+                                flags, block_in_inline_break_token);
+  return base::AdoptRef(static_cast<NGInlineBreakToken*>(data));
+}
+
 NGInlineBreakToken::NGInlineBreakToken(
     PassKey key,
     NGInlineNode node,
     const ComputedStyle* style,
     unsigned item_index,
     unsigned text_offset,
-    unsigned flags /* NGInlineBreakTokenFlags */)
+    unsigned flags /* NGInlineBreakTokenFlags */,
+    const NGBlockBreakToken* block_in_inline_break_token)
     : NGBreakToken(kInlineBreakToken, node),
       style_(style),
       item_index_(item_index),
       text_offset_(text_offset) {
   flags_ = flags;
+
+  if (UNLIKELY(block_in_inline_break_token)) {
+    block_in_inline_break_token->AddRef();
+    const NGBlockBreakToken* const* ptr = BlockInInlineBreakTokenAddress();
+    *const_cast<const NGBlockBreakToken**>(ptr) = block_in_inline_break_token;
+  }
 }
 
-NGInlineBreakToken::~NGInlineBreakToken() = default;
+NGInlineBreakToken::~NGInlineBreakToken() {
+  if (UNLIKELY(flags_ & kHasBlockInInlineToken)) {
+    const NGBlockBreakToken* const* ptr = BlockInInlineBreakTokenAddress();
+    DCHECK(*ptr);
+    (*ptr)->Release();
+  }
+}
 
 #if DCHECK_IS_ON()
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
index 3104236..a1654a48 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
@@ -13,14 +13,17 @@
 
 namespace blink {
 
+class NGBlockBreakToken;
+
 // Represents a break token for an inline node.
 class CORE_EXPORT NGInlineBreakToken final : public NGBreakToken {
  public:
   enum NGInlineBreakTokenFlags {
     kDefault = 0,
     kIsForcedBreak = 1 << 0,
-    kUseFirstLineStyle = 1 << 1,
-    kHasClonedBoxDecorations = 1 << 2,
+    kHasBlockInInlineToken = 1 << 1,
+    kUseFirstLineStyle = 1 << 2,
+    kHasClonedBoxDecorations = 1 << 3,
     // When adding values, ensure |flags_| has enough storage.
   };
 
@@ -32,11 +35,8 @@
       const ComputedStyle* style,
       unsigned item_index,
       unsigned text_offset,
-      unsigned flags /* NGInlineBreakTokenFlags */) {
-    return base::AdoptRef(new NGInlineBreakToken(
-        PassKey(), node, style, item_index, text_offset, flags));
-  }
-
+      unsigned flags /* NGInlineBreakTokenFlags */,
+      const NGBlockBreakToken* block_in_inline_break_token = nullptr);
   ~NGInlineBreakToken() override;
 
   // The style at the end of this break token. The next line should start with
@@ -59,6 +59,9 @@
     return flags_ & kIsForcedBreak;
   }
 
+  // The BreakToken when a block-in-inline is block-fragmented.
+  const NGBlockBreakToken* BlockInInlineBreakToken() const;
+
   // True if the current position has open tags that has `box-decoration-break:
   // clone`. They should be cloned to the start of the next line.
   bool HasClonedBoxDecorations() const {
@@ -71,7 +74,8 @@
                      const ComputedStyle*,
                      unsigned item_index,
                      unsigned text_offset,
-                     unsigned flags /* NGInlineBreakTokenFlags */);
+                     unsigned flags /* NGInlineBreakTokenFlags */,
+                     const NGBlockBreakToken* block_in_inline_break_token);
 
   explicit NGInlineBreakToken(PassKey, NGLayoutInputNode node);
 
@@ -80,9 +84,14 @@
 #endif
 
  private:
+  const NGBlockBreakToken* const* BlockInInlineBreakTokenAddress() const;
+
   scoped_refptr<const ComputedStyle> style_;
   unsigned item_index_;
   unsigned text_offset_;
+
+  // This is an array of one item if |kHasBlockInInlineToken|, or zero.
+  NGBlockBreakToken* block_in_inline_break_token_[];
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
index 51d5a8d..c089e580 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
@@ -32,6 +32,7 @@
     kText,
     kControl,
     kAtomicInline,
+    kBlockInInline,
     kOpenTag,
     kCloseTag,
     kFloating,
@@ -184,8 +185,14 @@
     return static_cast<NGCollapseType>(end_collapse_type_);
   }
   void SetEndCollapseType(NGCollapseType type) {
-    DCHECK(Type() == NGInlineItem::kText || type == kOpaqueToCollapsing ||
-           (Type() == NGInlineItem::kControl && type == kCollapsible));
+    // |kText| can set any types.
+    DCHECK(Type() == NGInlineItem::kText ||
+           // |kControl| and |kBlockInInline| are always |kCollapsible|.
+           ((Type() == NGInlineItem::kControl ||
+             Type() == NGInlineItem::kBlockInInline) &&
+            type == kCollapsible) ||
+           // Other types are |kOpaqueToCollapsing|.
+           type == kOpaqueToCollapsing);
     end_collapse_type_ = type;
   }
   bool IsCollapsibleSpaceOnly() const {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
index b5a2bb5..94757a3 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -1019,6 +1019,19 @@
 }
 
 template <typename OffsetMappingBuilder>
+void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendBlockInInline(
+    LayoutObject* layout_object) {
+  DCHECK(layout_object);
+  // Before a block-in-inline is like after a forced break.
+  RemoveTrailingCollapsibleSpaceIfExists();
+  NGInlineItem& item = Append(NGInlineItem::kBlockInInline,
+                              kObjectReplacementCharacter, layout_object);
+  // After a block-in-inline is like after a forced break. See
+  // |AppendForcedBreak|.
+  item.SetEndCollapseType(NGInlineItem::kCollapsible, false);
+}
+
+template <typename OffsetMappingBuilder>
 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendFloating(
     LayoutObject* layout_object) {
   AppendOpaque(NGInlineItem::kFloating, kObjectReplacementCharacter,
@@ -1080,9 +1093,11 @@
 
   // A forced break pretends that it's a collapsible space, see
   // |AppendForcedBreak()|. It should not be removed.
-  if (item->Type() == NGInlineItem::kControl)
+  if (item->Type() != NGInlineItem::kText) {
+    DCHECK(item->Type() == NGInlineItem::kControl ||
+           item->Type() == NGInlineItem::kBlockInInline);
     return;
-  DCHECK_EQ(item->Type(), NGInlineItem::kText);
+  }
 
   DCHECK_GT(item->EndOffset(), item->StartOffset());
   unsigned space_offset = item->EndOffset() - 1;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
index cbc0ad67..9b2faf2a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
@@ -105,6 +105,7 @@
   // Append a unicode "object replacement character" for an atomic inline,
   // signaling the presence of a non-text object to the unicode bidi algorithm.
   void AppendAtomicInline(LayoutObject* layout_object);
+  void AppendBlockInInline(LayoutObject* layout_object);
 
   // Append floats and positioned objects in the same way as atomic inlines.
   // Because these objects need positions, they will be handled in
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
index b4b69db..9250d45 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -74,6 +74,13 @@
     builder->AppendAtomicInline(layout_block_flow);
   }
 
+  void AppendBlockInInline(NGInlineItemsBuilder* builder) {
+    LayoutBlockFlow* layout_block_flow = LayoutBlockFlow::CreateAnonymous(
+        &GetDocument(), style_, LegacyLayout::kAuto);
+    anonymous_objects_.push_back(layout_block_flow);
+    builder->AppendBlockInInline(layout_block_flow);
+  }
+
   void AppendRubyRun(NGInlineItemsBuilder* builder) {
     LayoutNGRubyRun* ruby_run = new LayoutNGRubyRun();
     ruby_run->SetDocumentForAnonymous(&GetDocument());
@@ -533,6 +540,16 @@
   isolate_override_rtl->Destroy();
 }
 
+TEST_F(NGInlineItemsBuilderTest, BlockInInline) {
+  Vector<NGInlineItem> items;
+  NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
+  AppendText("Hello ", &builder);
+  AppendBlockInInline(&builder);
+  AppendText(" World", &builder);
+  // Collapsible spaces before and after block-in-inline should be collapsed.
+  EXPECT_EQ(String(u"Hello\uFFFCWorld"), builder.ToString());
+}
+
 TEST_F(NGInlineItemsBuilderTest, HasRuby) {
   Vector<NGInlineItem> items;
   NGInlineItemsBuilder builder(GetLayoutBlockFlow(), &items);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_break_token.h b/third_party/blink/renderer/core/layout/ng/ng_break_token.h
index 425499d5..3ba26c03 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_break_token.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_break_token.h
@@ -89,7 +89,7 @@
   // The following bitfields are only to be used by NGInlineBreakToken (it's
   // defined here to save memory, since that class has no bitfields).
 
-  unsigned flags_ : 3;  // NGInlineBreakTokenFlags
+  unsigned flags_ : 4;  // NGInlineBreakTokenFlags
 
   // The following bitfields are only to be used by NGBlockBreakToken (it's
   // defined here to save memory, since that class has no bitfields).
diff --git a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
index 393bfed..80098bc 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc
@@ -179,8 +179,10 @@
       LayoutUnit old_block_size =
           NGFragment(writing_direction_, physical_fragment).BlockSize();
 #if DCHECK_IS_ON()
-      // Tables don't respect the typical block-sizing rules.
-      if (!physical_fragment.IsTableNG())
+      // Tables, sections, rows don't respect the typical block-sizing rules.
+      if (!physical_fragment.IsTableNG() &&
+          !physical_fragment.IsTableNGSection() &&
+          !physical_fragment.IsTableNGRow())
         DCHECK_EQ(old_block_size, new_block_size);
 #endif
       container_builder_.SetFragmentBlockSize(old_block_size);
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
index 3bc7c2bf..2632d77 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
@@ -810,10 +810,18 @@
     NGConstraintSpaceBuilder section_space_builder(
         table_writing_direction.GetWritingMode(), table_writing_direction,
         /* is_new_fc */ true);
-    section_space_builder.SetAvailableSize(
-        {section_available_inline_size, sections[section_index].block_size});
+
+    LogicalSize available_size = {section_available_inline_size,
+                                  kIndefiniteSize};
+
+    // Sections without rows can receive redistributed height from the table.
+    if (constraint_space_data->sections[section_index].rowspan == 0) {
+      section_space_builder.SetIsFixedBlockSize(true);
+      available_size.block_size = sections[section_index].block_size;
+    }
+
+    section_space_builder.SetAvailableSize(available_size);
     section_space_builder.SetIsFixedInlineSize(true);
-    section_space_builder.SetIsFixedBlockSize(true);
     section_space_builder.SetPercentageResolutionSize(
         {section_available_inline_size, kIndefiniteSize});
     section_space_builder.SetTableSectionData(constraint_space_data,
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
index 23e0a28..16e7629 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
@@ -13,11 +13,15 @@
 
 // Implements spec distribution algorithm:
 // https://www.w3.org/TR/css-tables-3/#width-distribution-algorithm
+// |treat_target_size_as_constrained| constrained target can grow fixed-width
+// columns. unconstrained target cannot grow fixed-width columns beyond
+// specified size.
 Vector<LayoutUnit> DistributeInlineSizeToComputedInlineSizeAuto(
     LayoutUnit target_inline_size,
     LayoutUnit inline_border_spacing,
     const NGTableTypes::Column* start_column,
-    const NGTableTypes::Column* end_column) {
+    const NGTableTypes::Column* end_column,
+    const bool treat_target_size_as_constrained) {
   unsigned all_columns_count = 0;
   unsigned percent_columns_count = 0;
   unsigned fixed_columns_count = 0;
@@ -263,7 +267,7 @@
           DCHECK(last_computed_size);
           *last_computed_size += rounding_error_inline_size;
         }
-      } else if (fixed_columns_count > 0) {
+      } else if (fixed_columns_count > 0 && treat_target_size_as_constrained) {
         // Grow fixed columns if available.
         LayoutUnit rounding_error_inline_size = distributable_inline_size;
         LayoutUnit* last_computed_size = nullptr;
@@ -304,9 +308,8 @@
         LayoutUnit* computed_size = computed_sizes.begin();
         for (const NGTableTypes::Column* column = start_column;
              column != end_column; ++column, ++computed_size) {
-          if (column->is_mergeable)
+          if (column->is_mergeable || !column->percent)
             continue;
-          DCHECK(column->percent);
           last_computed_size = computed_size;
           LayoutUnit percent_inline_size =
               column->ResolvePercentInlineSize(target_inline_size);
@@ -321,8 +324,7 @@
           rounding_error_inline_size -= delta;
           *computed_size = percent_inline_size + delta;
         }
-        if (rounding_error_inline_size != LayoutUnit()) {
-          DCHECK(last_computed_size);
+        if (rounding_error_inline_size != LayoutUnit() && last_computed_size) {
           *last_computed_size += rounding_error_inline_size;
         }
       }
@@ -661,9 +663,9 @@
       column->max_inline_size = LayoutUnit();
   }
   Vector<LayoutUnit> computed_sizes =
-      DistributeInlineSizeToComputedInlineSizeAuto(colspan_cell_min_inline_size,
-                                                   inline_border_spacing,
-                                                   start_column, end_column);
+      DistributeInlineSizeToComputedInlineSizeAuto(
+          colspan_cell_min_inline_size, inline_border_spacing, start_column,
+          end_column, true);
   LayoutUnit* computed_size = computed_sizes.begin();
   for (NGTableTypes::Column* column = start_column; column != end_column;
        ++column, ++computed_size) {
@@ -672,12 +674,14 @@
   }
   computed_sizes = DistributeInlineSizeToComputedInlineSizeAuto(
       colspan_cell_max_inline_size, inline_border_spacing, start_column,
-      end_column);
+      end_column, /* treat_target_size_as_constrained */
+      colspan_cell.cell_inline_constraint.is_constrained);
   computed_size = computed_sizes.begin();
   for (NGTableTypes::Column* column = start_column; column != end_column;
        ++column, ++computed_size) {
     column->max_inline_size =
-        std::max(*column->max_inline_size, *computed_size);
+        std::max(std::max(*column->min_inline_size, *column->max_inline_size),
+                 *computed_size);
   }
 }
 
@@ -1042,7 +1046,7 @@
         start_column + column_constraints.data.size();
     return DistributeInlineSizeToComputedInlineSizeAuto(
         assignable_table_inline_size, inline_border_spacing, start_column,
-        end_column);
+        end_column, /* treat_target_size_as_constrained */ true);
   }
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc
index 61d7a8f..55dc9d64 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_section_layout_algorithm.cc
@@ -33,6 +33,8 @@
 
   absl::optional<LayoutUnit> section_baseline;
 
+  const LogicalSize available_size = {container_builder_.InlineSize(),
+                                      kIndefiniteSize};
   LogicalOffset offset;
   bool is_first_row = true;
   wtf_size_t row_index = table_data.sections[section_index].start_row_index;
@@ -44,12 +46,9 @@
         table_data.table_writing_direction.GetWritingMode(),
         table_data.table_writing_direction,
         /* is_new_fc */ true);
-    row_space_builder.SetAvailableSize({container_builder_.InlineSize(),
-                                        table_data.rows[row_index].block_size});
+    row_space_builder.SetAvailableSize(available_size);
+    row_space_builder.SetPercentageResolutionSize(available_size);
     row_space_builder.SetIsFixedInlineSize(true);
-    row_space_builder.SetIsFixedBlockSize(true);
-    row_space_builder.SetPercentageResolutionSize(
-        {container_builder_.InlineSize(), kIndefiniteSize});
     row_space_builder.SetTableRowData(&table_data, row_index);
     NGConstraintSpace row_space = row_space_builder.ToConstraintSpace();
     scoped_refptr<const NGLayoutResult> row_result = row.Layout(row_space);
@@ -66,9 +65,9 @@
     is_first_row = false;
     row_index++;
   }
-  if (table_data.sections[section_index].rowspan == 0) {
-    // Sections without rows can get redistributed height from table.
-    DCHECK(ConstraintSpace().IsFixedBlockSize());
+  if (ConstraintSpace().IsFixedBlockSize()) {
+    // A fixed block-size should only occur for a section without children.
+    DCHECK_EQ(table_data.sections[section_index].rowspan, 0u);
     container_builder_.SetFragmentBlockSize(
         ConstraintSpace().AvailableSize().block_size);
   } else {
diff --git a/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc b/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
index 32cf999..b672cebc 100644
--- a/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
+++ b/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc
@@ -379,6 +379,21 @@
   document_->CheckCompleted();
 }
 
+void ResourceLoadObserverForFrame::DidChangeRenderBlockingBehavior(
+    Resource* resource,
+    const FetchParameters& params) {
+  TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(
+      "devtools.timeline", "PreloadRenderBlockingStatusChange",
+      TRACE_EVENT_SCOPE_THREAD, base::TimeTicks::Now(), "data",
+      [&](perfetto::TracedValue ctx) {
+        inspector_change_render_blocking_behavior_event::Data(
+            std::move(ctx), document_->Loader(),
+            resource->GetResourceRequest().InspectorId(),
+            resource->GetResourceRequest(),
+            params.GetResourceRequest().GetRenderBlockingBehavior());
+      });
+}
+
 void ResourceLoadObserverForFrame::Trace(Visitor* visitor) const {
   visitor->Trace(document_loader_);
   visitor->Trace(document_);
diff --git a/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h b/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h
index e1f00c904..5ef931f 100644
--- a/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h
+++ b/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.h
@@ -60,6 +60,8 @@
                       const ResourceError&,
                       int64_t encoded_data_length,
                       IsInternalRequest) override;
+  void DidChangeRenderBlockingBehavior(Resource* resource,
+                                       const FetchParameters& params) override;
   void Trace(Visitor*) const override;
 
  private:
diff --git a/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h b/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h
index 4130744..2e4ee05b 100644
--- a/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h
+++ b/third_party/blink/renderer/core/loader/resource_load_observer_for_worker.h
@@ -57,6 +57,9 @@
                       const ResourceError&,
                       int64_t encoded_data_length,
                       IsInternalRequest) override;
+  void DidChangeRenderBlockingBehavior(Resource* resource,
+                                       const FetchParameters& params) override {
+  }
   void Trace(Visitor*) const override;
 
  private:
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 2c2a14d..04f33532 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -2521,14 +2521,6 @@
   return ListStyleTypeInternal();
 }
 
-EListStyleType ComputedStyle::ListStyleType() const {
-  if (!GetListStyleType())
-    return EListStyleType::kNone;
-  if (GetListStyleType()->IsString())
-    return EListStyleType::kString;
-  return GetListStyleType()->ToDeprecatedListStyleTypeEnum();
-}
-
 const AtomicString& ComputedStyle::ListStyleStringValue() const {
   if (!GetListStyleType() || !GetListStyleType()->IsString())
     return g_null_atom;
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 8273271..4103f1c 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -962,12 +962,8 @@
   void SetListStyleImage(StyleImage*);
 
   // list-style-type
-  // TODO(crbug.com/687225): These functions are deprecated. Callers should be
-  // migrated to GetListStyleType().
-  CORE_EXPORT EListStyleType ListStyleType() const;
   const AtomicString& ListStyleStringValue() const;
-  // TODO(crbug.com/687225): Get rid of the deprecated functions above so that
-  // the getter can also be auto-generated.
+  // TODO(crbug.com/687225): Make this function auto-generated.
   CORE_EXPORT ListStyleTypeData* GetListStyleType() const;
   bool ListStyleTypeDataEquivalent(const ComputedStyle& other) const {
     return DataEquivalent(ListStyleTypeInternal(),
diff --git a/third_party/blink/renderer/core/style/content_data.h b/third_party/blink/renderer/core/style/content_data.h
index c5aebe2e..34f747f 100644
--- a/third_party/blink/renderer/core/style/content_data.h
+++ b/third_party/blink/renderer/core/style/content_data.h
@@ -209,8 +209,6 @@
   const AtomicString& Separator() const { return separator_; }
   const TreeScope* GetTreeScope() const { return tree_scope_; }
 
-  EListStyleType ToDeprecatedListStyleTypeEnum() const;
-
   void Trace(Visitor*) const override;
 
  private:
diff --git a/third_party/blink/renderer/core/style/list_style_type_data.cc b/third_party/blink/renderer/core/style/list_style_type_data.cc
index bc3f2a70..0771d0e 100644
--- a/third_party/blink/renderer/core/style/list_style_type_data.cc
+++ b/third_party/blink/renderer/core/style/list_style_type_data.cc
@@ -9,41 +9,12 @@
 #include "third_party/blink/renderer/core/css/style_engine.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/tree_scope.h"
-#include "third_party/blink/renderer/core/style/content_data.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 
 namespace blink {
 
-namespace {
-
-using PredefinedCounterStyleNameMap = HashMap<AtomicString, EListStyleType>;
-
-PredefinedCounterStyleNameMap BuildPredefinedCounterStyleNameMap() {
-  PredefinedCounterStyleNameMap map;
-  for (unsigned i = 0; i < static_cast<unsigned>(EListStyleType::kString);
-       ++i) {
-    EListStyleType list_style_type = static_cast<EListStyleType>(i);
-    CSSValueID css_value_id = PlatformEnumToCSSValueID(list_style_type);
-    AtomicString value_name(getValueName(css_value_id));
-    map.Set(value_name, list_style_type);
-  }
-  return map;
-}
-
-EListStyleType CounterStyleNameToDeprecatedEnum(const AtomicString& name) {
-  DEFINE_STATIC_LOCAL(PredefinedCounterStyleNameMap,
-                      predefined_counter_style_name_map,
-                      (BuildPredefinedCounterStyleNameMap()));
-  auto iterator = predefined_counter_style_name_map.find(name);
-  if (iterator != predefined_counter_style_name_map.end())
-    return iterator->value;
-  return EListStyleType::kDecimal;
-}
-
-}  // namespace
-
 void ListStyleTypeData::Trace(Visitor* visitor) const {
   visitor->Trace(tree_scope_);
   visitor->Trace(counter_style_);
@@ -62,20 +33,6 @@
                                                  tree_scope);
 }
 
-EListStyleType ListStyleTypeData::ToDeprecatedListStyleTypeEnum() const {
-  if (IsString())
-    return EListStyleType::kString;
-  return CounterStyleNameToDeprecatedEnum(GetCounterStyleName());
-}
-
-// TODO(crbug.com/687225): We temporarily put this function here to share the
-// common logic. Clean it up when @counter-style is shipped.
-EListStyleType CounterContentData::ToDeprecatedListStyleTypeEnum() const {
-  if (ListStyle() == "none")
-    return EListStyleType::kNone;
-  return CounterStyleNameToDeprecatedEnum(ListStyle());
-}
-
 bool ListStyleTypeData::IsCounterStyleReferenceValid(Document& document) const {
   if (!IsCounterStyle()) {
     DCHECK(!counter_style_);
diff --git a/third_party/blink/renderer/core/style/list_style_type_data.h b/third_party/blink/renderer/core/style/list_style_type_data.h
index 8b79e26d5..a17722c0 100644
--- a/third_party/blink/renderer/core/style/list_style_type_data.h
+++ b/third_party/blink/renderer/core/style/list_style_type_data.h
@@ -61,8 +61,6 @@
   bool IsCounterStyleReferenceValid(Document&) const;
   const CounterStyle& GetCounterStyle(Document&) const;
 
-  EListStyleType ToDeprecatedListStyleTypeEnum() const;
-
  private:
   Type type_;
   AtomicString name_or_string_value_;
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
index e491d42..f2bac7901 100644
--- a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
+++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
@@ -202,9 +202,10 @@
 void FakeLocalFrameHost::DidChangeOpener(
     const absl::optional<LocalFrameToken>& opener_frame) {}
 
-void FakeLocalFrameHost::DidChangeCSPAttribute(
+void FakeLocalFrameHost::DidChangeIframeAttributes(
     const blink::FrameToken& child_frame_token,
-    network::mojom::blink::ContentSecurityPolicyPtr) {}
+    network::mojom::blink::ContentSecurityPolicyPtr,
+    bool anonymous) {}
 
 void FakeLocalFrameHost::DidChangeFramePolicy(
     const blink::FrameToken& child_frame_token,
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.h b/third_party/blink/renderer/core/testing/fake_local_frame_host.h
index c26a344..88a021c 100644
--- a/third_party/blink/renderer/core/testing/fake_local_frame_host.h
+++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.h
@@ -136,9 +136,10 @@
       mojom::blink::FrameOwnerPropertiesPtr frame_owner_properties) override;
   void DidChangeOpener(
       const absl::optional<LocalFrameToken>& opener_frame) override;
-  void DidChangeCSPAttribute(const blink::FrameToken& child_frame_token,
-                             network::mojom::blink::ContentSecurityPolicyPtr
-                                 parsed_csp_attribute) override;
+  void DidChangeIframeAttributes(
+      const blink::FrameToken& child_frame_token,
+      network::mojom::blink::ContentSecurityPolicyPtr parsed_csp_attribute,
+      bool anonymous) override;
   void DidChangeFramePolicy(const blink::FrameToken& child_frame_token,
                             const FramePolicy& frame_policy) override;
   void CapturePaintPreviewOfSubframe(
diff --git a/third_party/blink/renderer/core/timing/performance_timing.cc b/third_party/blink/renderer/core/timing/performance_timing.cc
index 7838348..d5acc15 100644
--- a/third_party/blink/renderer/core/timing/performance_timing.cc
+++ b/third_party/blink/renderer/core/timing/performance_timing.cc
@@ -639,6 +639,19 @@
   return timing->LastPortalActivatedPaint();
 }
 
+absl::optional<base::TimeDelta> PerformanceTiming::PrerenderActivationStart()
+    const {
+  DocumentLoadTiming* timing = GetDocumentLoadTiming();
+  if (!timing)
+    return absl::nullopt;
+
+  base::TimeTicks activation_start = timing->ActivationStart();
+  if (activation_start.is_null())
+    return absl::nullopt;
+
+  return timing->MonotonicTimeToZeroBasedDocumentTime(activation_start);
+}
+
 absl::optional<base::TimeTicks> PerformanceTiming::UnloadStart() const {
   DocumentLoadTiming* timing = GetDocumentLoadTiming();
   if (!timing)
diff --git a/third_party/blink/renderer/core/timing/performance_timing.h b/third_party/blink/renderer/core/timing/performance_timing.h
index 484844bc..a5c7172 100644
--- a/third_party/blink/renderer/core/timing/performance_timing.h
+++ b/third_party/blink/renderer/core/timing/performance_timing.h
@@ -196,6 +196,8 @@
 
   // The time of the first paint after a portal activation.
   absl::optional<base::TimeTicks> LastPortalActivatedPaint() const;
+  // The start time of the prerender activation navigation.
+  absl::optional<base::TimeDelta> PrerenderActivationStart() const;
 
   typedef uint64_t (PerformanceTiming::*PerformanceTimingGetter)() const;
   using NameToAttributeMap = HashMap<AtomicString, PerformanceTimingGetter>;
diff --git a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h
index 56df4d3..4e2f933 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h
@@ -33,6 +33,7 @@
 #include "base/memory/weak_ptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
 #include "third_party/blink/renderer/modules/webaudio/audio_node.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
 
 namespace base {
 class SingleThreadTaskRunner;
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_node.h b/third_party/blink/renderer/modules/webaudio/script_processor_node.h
index d720fea..11b9610 100644
--- a/third_party/blink/renderer/modules/webaudio/script_processor_node.h
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_node.h
@@ -35,6 +35,7 @@
 #include "third_party/blink/renderer/platform/audio/audio_bus.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace base {
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc
index 4ebfe502..7c9fa09 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -96,28 +96,6 @@
   }
 }
 
-bool ConvertBufferSource(const DOMArrayPiece& buffer_source,
-                         Vector<uint8_t>* vector,
-                         ScriptPromiseResolver* resolver) {
-  DCHECK(!buffer_source.IsNull());
-
-  if (buffer_source.IsDetached()) {
-    resolver->Reject(MakeGarbageCollected<DOMException>(
-        DOMExceptionCode::kInvalidStateError, kDetachedBuffer));
-    return false;
-  }
-
-  if (buffer_source.ByteLength() > std::numeric_limits<wtf_size_t>::max()) {
-    resolver->Reject(MakeGarbageCollected<DOMException>(
-        DOMExceptionCode::kDataError, kBufferTooBig));
-    return false;
-  }
-
-  vector->Append(buffer_source.Bytes(),
-                 static_cast<wtf_size_t>(buffer_source.ByteLength()));
-  return true;
-}
-
 }  // namespace
 
 USBDevice::USBDevice(UsbDeviceInfoPtr device_info,
@@ -388,6 +366,8 @@
     ScriptState* script_state,
     const USBControlTransferParameters* setup,
     const DOMArrayPiece& data) {
+  DCHECK(!data.IsNull());
+
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (!EnsureNoDeviceOrInterfaceChangeInProgress(resolver))
@@ -403,14 +383,23 @@
   if (!parameters)
     return promise;
 
-  Vector<uint8_t> buffer;
-  if (!ConvertBufferSource(data, &buffer, resolver))
+  if (data.IsDetached()) {
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kInvalidStateError, kDetachedBuffer));
     return promise;
+  }
 
-  unsigned transfer_length = buffer.size();
+  if (data.ByteLength() > std::numeric_limits<uint32_t>::max()) {
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kDataError, kBufferTooBig));
+    return promise;
+  }
+
+  auto transfer_length = static_cast<uint32_t>(data.ByteLength());
   device_requests_.insert(resolver);
   device_->ControlTransferOut(
-      std::move(parameters), buffer, 0,
+      std::move(parameters), base::make_span(data.Bytes(), data.ByteLength()),
+      0,
       WTF::Bind(&USBDevice::AsyncControlTransferOut, WrapPersistent(this),
                 transfer_length, WrapPersistent(resolver)));
   return promise;
@@ -472,7 +461,7 @@
     return promise;
   }
 
-  unsigned transfer_length = static_cast<uint32_t>(data.ByteLength());
+  auto transfer_length = static_cast<uint32_t>(data.ByteLength());
   device_requests_.insert(resolver);
   device_->GenericTransferOut(
       endpoint_number, base::make_span(data.Bytes(), data.ByteLength()), 0,
@@ -502,18 +491,29 @@
     uint8_t endpoint_number,
     const DOMArrayPiece& data,
     Vector<unsigned> packet_lengths) {
+  DCHECK(!data.IsNull());
+
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (!EnsureEndpointAvailable(false /* out */, endpoint_number, resolver))
     return promise;
 
-  Vector<uint8_t> buffer;
-  if (!ConvertBufferSource(data, &buffer, resolver))
+  if (data.IsDetached()) {
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kInvalidStateError, kDetachedBuffer));
     return promise;
+  }
+
+  if (data.ByteLength() > std::numeric_limits<wtf_size_t>::max()) {
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        DOMExceptionCode::kDataError, kBufferTooBig));
+    return promise;
+  }
 
   device_requests_.insert(resolver);
   device_->IsochronousTransferOut(
-      endpoint_number, buffer, packet_lengths, 0,
+      endpoint_number, base::make_span(data.Bytes(), data.ByteLength()),
+      packet_lengths, 0,
       WTF::Bind(&USBDevice::AsyncIsochronousTransferOut, WrapPersistent(this),
                 WrapPersistent(resolver)));
   return promise;
@@ -915,7 +915,7 @@
 
 void USBDevice::AsyncControlTransferIn(ScriptPromiseResolver* resolver,
                                        UsbTransferStatus status,
-                                       const Vector<uint8_t>& data) {
+                                       base::span<const uint8_t> data) {
   if (!MarkRequestComplete(resolver))
     return;
 
@@ -928,7 +928,7 @@
   }
 }
 
-void USBDevice::AsyncControlTransferOut(unsigned transfer_length,
+void USBDevice::AsyncControlTransferOut(uint32_t transfer_length,
                                         ScriptPromiseResolver* resolver,
                                         UsbTransferStatus status) {
   if (!MarkRequestComplete(resolver))
@@ -957,7 +957,7 @@
 
 void USBDevice::AsyncTransferIn(ScriptPromiseResolver* resolver,
                                 UsbTransferStatus status,
-                                const Vector<uint8_t>& data) {
+                                base::span<const uint8_t> data) {
   if (!MarkRequestComplete(resolver))
     return;
 
@@ -987,7 +987,7 @@
 
 void USBDevice::AsyncIsochronousTransferIn(
     ScriptPromiseResolver* resolver,
-    const Vector<uint8_t>& data,
+    base::span<const uint8_t> data,
     Vector<UsbIsochronousPacketPtr> mojo_packets) {
   if (!MarkRequestComplete(resolver))
     return;
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.h b/third_party/blink/renderer/modules/webusb/usb_device.h
index 4735888..21231db 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.h
+++ b/third_party/blink/renderer/modules/webusb/usb_device.h
@@ -7,6 +7,7 @@
 
 #include <bitset>
 
+#include "base/containers/span.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "services/device/public/mojom/usb_device.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
@@ -144,20 +145,20 @@
                                      bool success);
   void AsyncControlTransferIn(ScriptPromiseResolver*,
                               device::mojom::blink::UsbTransferStatus,
-                              const Vector<uint8_t>&);
-  void AsyncControlTransferOut(unsigned,
+                              base::span<const uint8_t> data);
+  void AsyncControlTransferOut(uint32_t transfer_length,
                                ScriptPromiseResolver*,
                                device::mojom::blink::UsbTransferStatus);
   void AsyncClearHalt(ScriptPromiseResolver*, bool success);
   void AsyncTransferIn(ScriptPromiseResolver*,
                        device::mojom::blink::UsbTransferStatus,
-                       const Vector<uint8_t>&);
+                       base::span<const uint8_t> data);
   void AsyncTransferOut(uint32_t transfer_length,
                         ScriptPromiseResolver*,
                         device::mojom::blink::UsbTransferStatus);
   void AsyncIsochronousTransferIn(
       ScriptPromiseResolver*,
-      const Vector<uint8_t>&,
+      base::span<const uint8_t> data,
       Vector<device::mojom::blink::UsbIsochronousPacketPtr>);
   void AsyncIsochronousTransferOut(
       ScriptPromiseResolver*,
diff --git a/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h b/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h
index 9d75cf5..b081f7f 100644
--- a/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h
+++ b/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h
@@ -20,7 +20,7 @@
 
  public:
   static USBInTransferResult* Create(const String& status,
-                                     const Vector<uint8_t>& data) {
+                                     base::span<const uint8_t> data) {
     DOMDataView* data_view = DOMDataView::Create(
         DOMArrayBuffer::Create(data.data(), data.size()), 0, data.size());
     return MakeGarbageCollected<USBInTransferResult>(status, data_view);
diff --git a/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.h b/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.h
index de501a8..629d1ac 100644
--- a/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.h
+++ b/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.h
@@ -20,21 +20,21 @@
   }
 
   static USBOutTransferResult* Create(const String& status,
-                                      unsigned bytes_written) {
+                                      uint32_t bytes_written) {
     return MakeGarbageCollected<USBOutTransferResult>(status, bytes_written);
   }
 
-  USBOutTransferResult(const String& status, unsigned bytes_written)
+  USBOutTransferResult(const String& status, uint32_t bytes_written)
       : status_(status), bytes_written_(bytes_written) {}
 
   ~USBOutTransferResult() override = default;
 
   String status() const { return status_; }
-  unsigned bytesWritten() const { return bytes_written_; }
+  uint32_t bytesWritten() const { return bytes_written_; }
 
  private:
   const String status_;
-  const unsigned bytes_written_;
+  const uint32_t bytes_written_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
index 5e3b8f0..3beef82 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -163,12 +163,8 @@
 const TransformPaintPropertyNode&
 PaintArtifactCompositor::NearestScrollTranslationForLayer(
     const PendingLayer& pending_layer) {
-  if (pending_layer.GetCompositingType() != PendingLayer::kPreCompositedLayer) {
-    if (const auto* scroll_translation =
-            pending_layer.ScrollTranslationForScrollHitTestLayer()) {
-      return *scroll_translation;
-    }
-  }
+  if (pending_layer.GetCompositingType() == PendingLayer::kScrollHitTestLayer)
+    return pending_layer.ScrollTranslationForScrollHitTestLayer();
 
   const auto& transform = pending_layer.GetPropertyTreeState().Transform();
   // TODO(pdr): This could be a performance issue because it crawls up the
@@ -180,18 +176,24 @@
 scoped_refptr<cc::Layer>
 PaintArtifactCompositor::ScrollHitTestLayerForPendingLayer(
     const PendingLayer& pending_layer) {
-  const auto* scroll_translation =
-      pending_layer.ScrollTranslationForScrollHitTestLayer();
-  if (!scroll_translation)
+  if (pending_layer.GetCompositingType() != PendingLayer::kScrollHitTestLayer)
     return nullptr;
 
   // We shouldn't decomposite scroll transform nodes.
   DCHECK_EQ(FloatPoint(), pending_layer.OffsetOfDecompositedTransforms());
 
-  const auto& scroll_node = *scroll_translation->ScrollNode();
+  const auto& scroll_node =
+      *pending_layer.ScrollTranslationForScrollHitTestLayer().ScrollNode();
 
-  scoped_refptr<cc::Layer> scroll_layer =
-      ExistingScrollHitTestLayerForPendingLayer(pending_layer);
+  scoped_refptr<cc::Layer> scroll_layer;
+  auto scroll_element_id = scroll_node.GetCompositorElementId();
+  for (auto& existing_layer : scroll_hit_test_layers_) {
+    if (existing_layer && existing_layer->element_id() == scroll_element_id) {
+      scroll_layer = std::move(existing_layer);
+      break;
+    }
+  }
+
   if (scroll_layer) {
     DCHECK_EQ(scroll_layer->element_id(), scroll_node.GetCompositorElementId());
   } else {
@@ -220,23 +222,6 @@
   return scroll_layer;
 }
 
-scoped_refptr<cc::Layer>
-PaintArtifactCompositor::ExistingScrollHitTestLayerForPendingLayer(
-    const PendingLayer& pending_layer) const {
-  const auto* scroll_translation =
-      pending_layer.ScrollTranslationForScrollHitTestLayer();
-  if (!scroll_translation)
-    return nullptr;
-
-  const auto& scroll_node = *scroll_translation->ScrollNode();
-  auto scroll_element_id = scroll_node.GetCompositorElementId();
-  for (auto& existing_layer : scroll_hit_test_layers_) {
-    if (existing_layer && existing_layer->element_id() == scroll_element_id)
-      return existing_layer;
-  }
-  return nullptr;
-}
-
 scoped_refptr<cc::ScrollbarLayerBase>
 PaintArtifactCompositor::ScrollbarLayerForPendingLayer(
     const PendingLayer& pending_layer) {
@@ -247,13 +232,19 @@
   DCHECK(item.IsScrollbar());
 
   const auto& scrollbar_item = To<ScrollbarDisplayItem>(item);
-  auto* existing_layer = ScrollbarLayer(scrollbar_item.ElementId());
-  scoped_refptr<cc::ScrollbarLayerBase> layer =
-      scrollbar_item.CreateOrReuseLayer(existing_layer);
-  layer->SetOffsetToTransformParent(
-      layer->offset_to_transform_parent() +
+  scoped_refptr<cc::ScrollbarLayerBase> scrollbar_layer;
+  for (auto& layer : scrollbar_layers_) {
+    if (layer && layer->element_id() == scrollbar_item.ElementId()) {
+      scrollbar_layer = std::move(layer);
+      break;
+    }
+  }
+
+  scrollbar_layer = scrollbar_item.CreateOrReuseLayer(scrollbar_layer.get());
+  scrollbar_layer->SetOffsetToTransformParent(
+      scrollbar_layer->offset_to_transform_parent() +
       gfx::Vector2dF(pending_layer.OffsetOfDecompositedTransforms()));
-  return layer;
+  return scrollbar_layer;
 }
 
 std::unique_ptr<ContentLayerClientImpl>
@@ -500,23 +491,6 @@
   return true;
 }
 
-static bool IsCompositedScrollHitTest(const PaintChunk& chunk) {
-  if (!chunk.hit_test_data)
-    return false;
-  const auto* scroll_translation = chunk.hit_test_data->scroll_translation;
-  return scroll_translation &&
-         scroll_translation->HasDirectCompositingReasons();
-}
-
-static bool IsCompositedScrollbar(const DisplayItem& item) {
-  if (const auto* scrollbar = DynamicTo<ScrollbarDisplayItem>(item)) {
-    const auto* scroll_translation = scrollbar->ScrollTranslation();
-    return scroll_translation &&
-           scroll_translation->HasDirectCompositingReasons();
-  }
-  return false;
-}
-
 void PaintArtifactCompositor::LayerizeGroup(
     const PaintChunkSubset& chunks,
     const EffectPaintPropertyNode& current_group,
@@ -547,19 +521,7 @@
     // C. The next chunk belongs to some subgroup of the current group.
     const auto& chunk_effect = chunk_cursor->properties.Effect().Unalias();
     if (&chunk_effect == &current_group) {
-      // Case A: The next chunk belongs to the current group but no subgroup.
-      PendingLayer::CompositingType compositing_type = PendingLayer::kOther;
-      if (IsCompositedScrollHitTest(*chunk_cursor)) {
-        compositing_type = PendingLayer::kCompositedScrollHitTestLayer;
-      } else if (chunk_cursor->size()) {
-        const auto& first_display_item = *chunk_cursor.DisplayItems().begin();
-        if (first_display_item.IsForeignLayer())
-          compositing_type = PendingLayer::kForeignLayer;
-        else if (IsCompositedScrollbar(first_display_item))
-          compositing_type = PendingLayer::kScrollbarLayer;
-      }
-
-      pending_layers_.emplace_back(chunks, chunk_cursor, compositing_type);
+      pending_layers_.emplace_back(chunks, chunk_cursor);
       ++chunk_cursor;
       if (pending_layers_.back().RequiresOwnLayer())
         continue;
@@ -972,69 +934,30 @@
   }
 }
 
-void PaintArtifactCompositor::UpdateRepaintedLayer(
-    PendingLayer& pending_layer,
-    cc::LayerSelection& layer_selection) {
-  cc::Layer* layer = nullptr;
-
-  switch (pending_layer.GetCompositingType()) {
-    case PendingLayer::kForeignLayer:
-      // These layers are fully managed externally and do not need an update.
-      return;
-    case PendingLayer::kPreCompositedLayer:
-      if (!pending_layer.GetGraphicsLayer()->Repainted())
-        return;
-      layer = &pending_layer.GetGraphicsLayer()->CcLayer();
+void PaintArtifactCompositor::UpdateRepaintedContentLayerClient(
+    const PendingLayer& pending_layer,
+    ContentLayerClientImpl& content_layer_client) {
+  bool all_moved_from_cached_subsequence = true;
+  for (const auto& chunk : pending_layer.Chunks()) {
+    if (!chunk.is_moved_from_cached_subsequence) {
+      all_moved_from_cached_subsequence = false;
       break;
-    case PendingLayer::kScrollbarLayer: {
-      // TODO(pdr): Share this code with ScrollbarLayerForPendingLayer.
-      const auto& item = pending_layer.FirstDisplayItem();
-      layer = ScrollbarLayer(To<ScrollbarDisplayItem>(item).ElementId());
-    } break;
-    default: {
-      if (scoped_refptr<cc::Layer> scroll_layer =
-              ExistingScrollHitTestLayerForPendingLayer(pending_layer)) {
-        layer = scroll_layer.get();
-        break;
-      }
-
-      ContentLayerClientImpl* content_layer_client = nullptr;
-      const auto& first_chunk = pending_layer.FirstPaintChunk();
-      for (auto& client : content_layer_clients_) {
-        if (client && client->Matches(first_chunk)) {
-          content_layer_client = client.get();
-          break;
-        }
-      }
-      CHECK(content_layer_client);
-
-      bool all_moved_from_cached_subsequence = true;
-      for (const auto& chunk : pending_layer.Chunks()) {
-        if (!chunk.is_moved_from_cached_subsequence) {
-          all_moved_from_cached_subsequence = false;
-          break;
-        }
-      }
-
-      // Checking |all_moved_from_cached_subsequence| is an optimization to
-      // avoid the expensive call to |UpdateCcPictureLayer| when no repainting
-      // occurs for this PendingLayer.
-      if (all_moved_from_cached_subsequence) {
-        // See RasterInvalidator::SetOldPaintArtifact() for the reason for this.
-        content_layer_client->GetRasterInvalidator().SetOldPaintArtifact(
-            &pending_layer.Chunks().GetPaintArtifact());
-      } else {
-        IntRect cc_combined_bounds = EnclosingIntRect(pending_layer.Bounds());
-        content_layer_client->UpdateCcPictureLayer(
-            pending_layer.Chunks(), cc_combined_bounds,
-            pending_layer.GetPropertyTreeState());
-      }
-      layer = &content_layer_client->Layer();
     }
   }
 
-  DCHECK(layer);
-  UpdateLayerProperties(*layer, pending_layer, layer_selection);
+  // Checking |all_moved_from_cached_subsequence| is an optimization to
+  // avoid the expensive call to |UpdateCcPictureLayer| when no repainting
+  // occurs for this PendingLayer.
+  if (all_moved_from_cached_subsequence) {
+    // See RasterInvalidator::SetOldPaintArtifact() for the reason for this.
+    content_layer_client.GetRasterInvalidator().SetOldPaintArtifact(
+        &pending_layer.Chunks().GetPaintArtifact());
+  } else {
+    IntRect cc_combined_bounds = EnclosingIntRect(pending_layer.Bounds());
+    content_layer_client.UpdateCcPictureLayer(
+        pending_layer.Chunks(), cc_combined_bounds,
+        pending_layer.GetPropertyTreeState());
+  }
 }
 
 namespace {
@@ -1122,6 +1045,9 @@
   // The loop below iterates over the existing PendingLayers and issues updates.
   PreCompositedLayerPaintChunkFinder repainted_chunk_finder(
       pre_composited_layers);
+  auto* content_layer_client_it = content_layer_clients_.begin();
+  auto* scroll_hit_test_layer_it = scroll_hit_test_layers_.begin();
+  auto* scrollbar_layer_it = scrollbar_layers_.begin();
   for (auto* pending_layer_it = pending_layers_.begin();
        pending_layer_it != pending_layers_.end(); pending_layer_it++) {
     auto compositing_type = pending_layer_it->GetCompositingType();
@@ -1166,8 +1092,30 @@
                 repainted_artifact.PaintChunks().size());
       pending_layer_it->SetPaintArtifact(&repainted_artifact);
 
-      // Update the cc::Layer associated with the pending layer.
-      UpdateRepaintedLayer(*pending_layer_it, layer_selection);
+      cc::Layer* cc_layer = nullptr;
+      switch (pending_layer_it->GetCompositingType()) {
+        case PendingLayer::kPreCompositedLayer:
+          NOTREACHED();
+          break;
+        case PendingLayer::kForeignLayer:
+          continue;
+        case PendingLayer::kScrollbarLayer:
+          cc_layer = scrollbar_layer_it->get();
+          ++scrollbar_layer_it;
+          break;
+        case PendingLayer::kScrollHitTestLayer:
+          cc_layer = scroll_hit_test_layer_it->get();
+          ++scroll_hit_test_layer_it;
+          break;
+        default:
+          UpdateRepaintedContentLayerClient(*pending_layer_it,
+                                            **content_layer_client_it);
+          cc_layer = &(*content_layer_client_it)->Layer();
+          ++content_layer_client_it;
+          break;
+      }
+      DCHECK(cc_layer);
+      UpdateLayerProperties(*cc_layer, *pending_layer_it, layer_selection);
     }
   }
 
@@ -1400,15 +1348,11 @@
         layer = scrollbar_layer_it->get();
         ++scrollbar_layer_it;
         break;
+      case PendingLayer::kScrollHitTestLayer:
+        layer = scroll_hit_test_layer_it->get();
+        ++scroll_hit_test_layer_it;
+        break;
       default:
-        if (scoped_refptr<cc::Layer> scroll_layer =
-                ExistingScrollHitTestLayerForPendingLayer(pending_layer)) {
-          DCHECK_EQ(scroll_layer, scroll_hit_test_layer_it->get());
-          layer = scroll_hit_test_layer_it->get();
-          ++scroll_hit_test_layer_it;
-          break;
-        }
-
         tracking =
             (*content_layer_client_it)->GetRasterInvalidator().GetTracking();
         layer = &(*content_layer_client_it)->Layer();
@@ -1426,15 +1370,6 @@
   }
 }
 
-cc::ScrollbarLayerBase* PaintArtifactCompositor::ScrollbarLayer(
-    CompositorElementId element_id) {
-  for (auto& layer : scrollbar_layers_) {
-    if (layer->element_id() == element_id)
-      return layer.get();
-  }
-  return nullptr;
-}
-
 CompositingReasons PaintArtifactCompositor::GetCompositingReasons(
     const PendingLayer& layer,
     const PendingLayer* previous_layer) const {
@@ -1444,8 +1379,7 @@
     return layer.GetGraphicsLayer()->GetCompositingReasons();
 
   if (layer.RequiresOwnLayer()) {
-    const auto& first_chunk = layer.FirstPaintChunk();
-    if (IsCompositedScrollHitTest(first_chunk))
+    if (layer.GetCompositingType() == PendingLayer::kScrollHitTestLayer)
       return CompositingReason::kOverflowScrolling;
     switch (layer.FirstDisplayItem().GetType()) {
       case DisplayItem::kForeignLayerCanvas:
@@ -1549,8 +1483,12 @@
 
 void PaintArtifactCompositor::SetScrollbarNeedsDisplay(
     CompositorElementId element_id) {
-  if (auto* scrollbar_layer = ScrollbarLayer(element_id))
-    scrollbar_layer->SetNeedsDisplay();
+  for (auto& layer : scrollbar_layers_) {
+    if (layer->element_id() == element_id) {
+      layer->SetNeedsDisplay();
+      return;
+    }
+  }
 }
 
 void LayerListBuilder::Add(scoped_refptr<cc::Layer> layer) {
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
index b2fbb3de..5842674 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
@@ -246,11 +246,11 @@
                                     const PendingLayer&,
                                     cc::LayerSelection& layer_selection);
 
-  // Updates the cc::Layer associated with a |pending_layer| following a paint.
-  // This includes both raster invalidation and updating the cc::Layer
-  // properties (bounds, background_color, etc).
-  void UpdateRepaintedLayer(PendingLayer& pending_layer,
-                            cc::LayerSelection& layer_selection);
+  // Updates |content_layer_client| associated with a |pending_layer| following
+  // a paint. This includes updating the drawings and raster invalidation.
+  void UpdateRepaintedContentLayerClient(
+      const PendingLayer& pending_layer,
+      ContentLayerClientImpl& content_layer_client);
 
   // Collects the PaintChunks into groups which will end up in the same
   // cc layer. This is the entry point of the layerization algorithm.
@@ -302,11 +302,6 @@
   scoped_refptr<cc::Layer> ScrollHitTestLayerForPendingLayer(
       const PendingLayer&);
 
-  // Finds an existing scroll hit test layer for the pending layer, returning
-  // nullptr if none exists.
-  scoped_refptr<cc::Layer> ExistingScrollHitTestLayerForPendingLayer(
-      const PendingLayer&) const;
-
   // Finds an existing or creates a new scrollbar layer for the pending layer,
   // returning nullptr if the layer is not a scrollbar layer.
   scoped_refptr<cc::ScrollbarLayerBase> ScrollbarLayerForPendingLayer(
@@ -341,8 +336,6 @@
 
   void UpdateDebugInfo() const;
 
-  cc::ScrollbarLayerBase* ScrollbarLayer(CompositorElementId);
-
   // For notifying blink of composited scrolling.
   base::WeakPtr<CompositorScrollCallbacks> scroll_callbacks_;
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
index 45b7fab3..d5b91eb5 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -1349,8 +1349,10 @@
       t0(), 11, 13, *scroll_a, CompositingReason::kLayerForScrollingContents);
 
   CompositorElementId scroll_element_id_b = ScrollElementId(3);
-  auto scroll_b = CreateScroll(*scroll_a, ScrollState2(), kNotScrollingOnMain,
-                               scroll_element_id_b);
+  auto scroll_b =
+      CreateScroll(*scroll_a, ScrollState2(),
+                   cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText,
+                   scroll_element_id_b);
   auto scroll_translation_b =
       CreateScrollTranslation(*scroll_translation_a, 37, 41, *scroll_b);
 
@@ -1360,35 +1362,23 @@
   Update(artifact.Build());
 
   const cc::ScrollTree& scroll_tree = GetPropertyTrees().scroll_tree;
-  // Node #0 reserved for null; #1 for root render surface.
-  ASSERT_EQ(4u, scroll_tree.size());
+  // Node #0 reserved for null; #1 for root render surface. #2 is for scroll_a.
+  // We don't need to create cc scroll node for scroll_b which doesn't use
+  // composited scrolling.
+  ASSERT_EQ(3u, scroll_tree.size());
 
   const cc::ScrollNode& scroll_node_a = *scroll_tree.Node(2);
   EXPECT_EQ(1, scroll_node_a.parent_id);
   EXPECT_EQ(scroll_element_id_a, scroll_node_a.element_id);
   EXPECT_EQ(scroll_node_a.id, ElementIdToScrollNodeIndex(scroll_element_id_a));
-  // The second scrollable layer should be associated with the first scroll node
-  // (a).
-  EXPECT_EQ(scroll_element_id_a, ScrollableLayerAt(1)->element_id());
+  // The first scrollable layer should be associated with scroll_a.
+  EXPECT_EQ(scroll_element_id_a, ScrollableLayerAt(0)->element_id());
 
   const cc::TransformTree& transform_tree = GetPropertyTrees().transform_tree;
   const cc::TransformNode& transform_node_a =
       *transform_tree.Node(scroll_node_a.transform_id);
   EXPECT_TRUE(transform_node_a.local.IsIdentity());
   EXPECT_EQ(gfx::ScrollOffset(-11, -13), transform_node_a.scroll_offset);
-
-  const cc::ScrollNode& scroll_node_b = *scroll_tree.Node(3);
-  EXPECT_EQ(scroll_node_a.id, scroll_node_b.parent_id);
-  EXPECT_EQ(scroll_element_id_b, scroll_node_b.element_id);
-  EXPECT_EQ(scroll_node_b.id, ElementIdToScrollNodeIndex(scroll_element_id_b));
-  // The first scrollable layer should be associated with the second scroll node
-  // (b).
-  EXPECT_EQ(scroll_element_id_b, ScrollableLayerAt(0)->element_id());
-
-  const cc::TransformNode& transform_node_b =
-      *transform_tree.Node(scroll_node_b.transform_id);
-  EXPECT_TRUE(transform_node_b.local.IsIdentity());
-  EXPECT_EQ(gfx::ScrollOffset(-37, -41), transform_node_b.scroll_offset);
 }
 
 TEST_P(PaintArtifactCompositorTest, MergeSimpleChunks) {
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
index 81a6764..8d4c0629 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
@@ -38,11 +38,27 @@
   }
 }
 
+bool IsCompositedScrollHitTest(const PaintChunk& chunk) {
+  if (!chunk.hit_test_data)
+    return false;
+  const auto* scroll_translation = chunk.hit_test_data->scroll_translation;
+  return scroll_translation &&
+         scroll_translation->HasDirectCompositingReasons();
+}
+
+bool IsCompositedScrollbar(const DisplayItem& item) {
+  if (const auto* scrollbar = DynamicTo<ScrollbarDisplayItem>(item)) {
+    const auto* scroll_translation = scrollbar->ScrollTranslation();
+    return scroll_translation &&
+           scroll_translation->HasDirectCompositingReasons();
+  }
+  return false;
+}
+
 }  // anonymous namespace
 
 PendingLayer::PendingLayer(const PaintChunkSubset& chunks,
-                           const PaintChunkIterator& first_chunk,
-                           CompositingType compositing_type)
+                           const PaintChunkIterator& first_chunk)
     : bounds_(first_chunk->bounds),
       rect_known_to_be_opaque_(first_chunk->rect_known_to_be_opaque),
       has_text_(first_chunk->has_text),
@@ -51,13 +67,23 @@
       chunks_(&chunks.GetPaintArtifact(), first_chunk.IndexInPaintArtifact()),
       property_tree_state_(
           first_chunk->properties.GetPropertyTreeState().Unalias()),
-      compositing_type_(compositing_type) {
+      compositing_type_(kOther) {
   DCHECK(!RequiresOwnLayer() || first_chunk->size() <= 1u);
   // Though text_known_to_be_on_opaque_background is only meaningful when
   // has_text is true, we expect text_known_to_be_on_opaque_background to be
   // true when !has_text to simplify code.
   DCHECK(has_text_ || text_known_to_be_on_opaque_background_);
   ClipToVisibilityLimit(property_tree_state_, bounds_);
+
+  if (IsCompositedScrollHitTest(*first_chunk)) {
+    compositing_type_ = kScrollHitTestLayer;
+  } else if (first_chunk->size()) {
+    const auto& first_display_item = FirstDisplayItem();
+    if (first_display_item.IsForeignLayer())
+      compositing_type_ = kForeignLayer;
+    else if (IsCompositedScrollbar(first_display_item))
+      compositing_type_ = kScrollbarLayer;
+  }
 }
 
 PendingLayer::PendingLayer(const PreCompositedLayerInfo& pre_composited_layer)
@@ -220,21 +246,15 @@
   return true;
 }
 
-const TransformPaintPropertyNode*
+const TransformPaintPropertyNode&
 PendingLayer::ScrollTranslationForScrollHitTestLayer() const {
-  // Not checking that the compositing type is
-  // PendingLayer::kCompositedScrollHitTestLayer because a scroll hit test
-  // chunk without a direct compositing reasons can still be composited
-  // (e.g. when it can't be merged into any other layer).
-  DCHECK_NE(GetCompositingType(), PendingLayer::kPreCompositedLayer);
-
-  if (Chunks().size() != 1)
-    return nullptr;
-
+  DCHECK_EQ(GetCompositingType(), kScrollHitTestLayer);
+  DCHECK_EQ(1u, Chunks().size());
   const auto& paint_chunk = FirstPaintChunk();
-  if (!paint_chunk.hit_test_data)
-    return nullptr;
-  return paint_chunk.hit_test_data->scroll_translation;
+  DCHECK(paint_chunk.hit_test_data);
+  DCHECK(paint_chunk.hit_test_data->scroll_translation);
+  DCHECK(paint_chunk.hit_test_data->scroll_translation->ScrollNode());
+  return *paint_chunk.hit_test_data->scroll_translation;
 }
 
 bool PendingLayer::PropertyTreeStateChanged() const {
@@ -302,16 +322,15 @@
     // clips or effects.
     auto mark_not_decompositable =
         [&can_be_decomposited](
-            const TransformPaintPropertyNode* transform_node) {
-          DCHECK(transform_node);
-          while (transform_node && !transform_node->IsRoot()) {
-            auto result = can_be_decomposited.insert(transform_node, false);
+            const TransformPaintPropertyNode& transform_node) {
+          for (const auto* node = &transform_node; node && !node->IsRoot();
+               node = node->UnaliasedParent()) {
+            auto result = can_be_decomposited.insert(node, false);
             if (!result.is_new_entry) {
               if (!result.stored_value->value)
                 break;
               result.stored_value->value = false;
             }
-            transform_node = &transform_node->Parent()->Unalias();
           }
         };
 
@@ -325,7 +344,7 @@
           node->HasDirectCompositingReasonsOtherThan3dTransform() ||
           !node->FlattensInheritedTransformSameAsParent() ||
           !node->BackfaceVisibilitySameAsParent()) {
-        mark_not_decompositable(node);
+        mark_not_decompositable(*node);
         break;
       }
       can_be_decomposited.insert(node, true);
@@ -336,23 +355,22 @@
          !node->IsRoot() && !clips_and_effects_seen.Contains(node);
          node = &node->Parent()->Unalias()) {
       clips_and_effects_seen.insert(node);
-      mark_not_decompositable(&node->LocalTransformSpace().Unalias());
+      mark_not_decompositable(node->LocalTransformSpace().Unalias());
     }
     for (const auto* node = &property_state.Effect();
          !node->IsRoot() && !clips_and_effects_seen.Contains(node);
          node = &node->Parent()->Unalias()) {
       clips_and_effects_seen.insert(node);
-      mark_not_decompositable(&node->LocalTransformSpace().Unalias());
+      mark_not_decompositable(node->LocalTransformSpace().Unalias());
     }
 
-    if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+    if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+        pending_layer.GetCompositingType() == kScrollHitTestLayer) {
       // The scroll translation node of a scroll hit test layer may not be
       // referenced by any pending layer's property tree state. Disallow
       // decomposition of it (and its ancestors).
-      if (const auto* translation =
-              pending_layer.ScrollTranslationForScrollHitTestLayer()) {
-        mark_not_decompositable(translation);
-      }
+      mark_not_decompositable(
+          pending_layer.ScrollTranslationForScrollHitTestLayer());
     }
   }
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
index 1468192..5fdda81 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
+++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
@@ -32,9 +32,7 @@
 class PLATFORM_EXPORT PendingLayer {
  public:
   enum CompositingType {
-    // This type is only for scroll hit test layers that have direct
-    // compositing reasons.
-    kCompositedScrollHitTestLayer,
+    kScrollHitTestLayer,
     kPreCompositedLayer,
     kForeignLayer,
     kScrollbarLayer,
@@ -42,9 +40,7 @@
     kOther,
   };
 
-  PendingLayer(const PaintChunkSubset&,
-               const PaintChunkIterator&,
-               CompositingType compositng_type = kOther);
+  PendingLayer(const PaintChunkSubset&, const PaintChunkIterator&);
   explicit PendingLayer(const PreCompositedLayerInfo&);
 
   const FloatRect& Bounds() const { return bounds_; }
@@ -105,7 +101,7 @@
   const PaintChunk& FirstPaintChunk() const;
   const DisplayItem& FirstDisplayItem() const;
 
-  const TransformPaintPropertyNode* ScrollTranslationForScrollHitTestLayer()
+  const TransformPaintPropertyNode& ScrollTranslationForScrollHitTestLayer()
       const;
 
   std::unique_ptr<JSONObject> ToJSON() const;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 4345417d..8fc72ba 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -709,6 +709,10 @@
       non_blocking_loaders_.Contains(resource->Loader())) {
     non_blocking_loaders_.erase(resource->Loader());
     loaders_.insert(resource->Loader());
+    if (resource_load_observer_) {
+      resource_load_observer_->DidChangeRenderBlockingBehavior(resource,
+                                                               params);
+    }
   }
 }
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
index 2e6739f..34d02891 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -158,6 +158,9 @@
                         const ResourceError&,
                         int64_t encoded_data_length,
                         IsInternalRequest is_internal_request) override {}
+    void DidChangeRenderBlockingBehavior(
+        Resource* resource,
+        const FetchParameters& params) override {}
     const absl::optional<PartialResourceRequest>& GetLastRequest() const {
       return request_;
     }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h b/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h
index 659f85a..56bbcca9 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h
@@ -96,6 +96,11 @@
                               int64_t encoded_data_length,
                               IsInternalRequest) = 0;
 
+  // Called when the RenderBlockingBehavior given to WillSendRequest changes.
+  virtual void DidChangeRenderBlockingBehavior(
+      Resource* resource,
+      const FetchParameters& params) = 0;
+
   virtual void Trace(Visitor*) const {}
 };
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader_unittest.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader_unittest.cc
index e75f82f..2ed5e0d 100644
--- a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader_unittest.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader_unittest.cc
@@ -179,6 +179,8 @@
                       const ResourceError&,
                       int64_t encoded_data_length,
                       IsInternalRequest));
+    MOCK_METHOD2(DidChangeRenderBlockingBehavior,
+                 void(Resource* resource, const FetchParameters& params));
     MOCK_METHOD1(EvictFromBackForwardCache,
                  void(blink::mojom::RendererEvictionReason));
   };
diff --git a/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc b/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
index c17e32e..6b7c95c 100644
--- a/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
@@ -41,7 +41,6 @@
     case Feature::kResumeEventListener:
     case Feature::kContainsPlugins:
     case Feature::kDocumentLoaded:
-    case Feature::kRequestedGeolocationPermission:
     case Feature::kRequestedNotificationsPermission:
     case Feature::kRequestedMIDIPermission:
     case Feature::kRequestedAudioCapturePermission:
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index e43eb1a..3655d242a 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -217,6 +217,9 @@
 crbug.com/591099 external/wpt/css/css-position/position-relative-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-relative-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-position/position-relative-004.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-position/position-relative-011.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-position/position-relative-012.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-position/position-relative-013.html [ Failure ]
 
 ### external/wpt/css/css-position/static-position/
 crbug.com/591099 external/wpt/css/css-position/static-position/htb-ltr-rtl.tentative.html [ Failure ]
@@ -1115,9 +1118,9 @@
 ### virtual/stable/compositing/filters/
 crbug.com/591099 virtual/stable/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow.html [ Failure ]
 
-### wpt_internal/css/css-counter-styles/
-crbug.com/591099 wpt_internal/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom.html [ Failure ]
-crbug.com/591099 wpt_internal/css/css-counter-styles/counter-styles-override-in-shadow-dom.html [ Failure ]
+### external/wpt/css/css-counter-styles/
+crbug.com/591099 external/wpt/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-counter-styles/counter-styles-override-in-shadow-dom.html [ Failure ]
 
 ### wpt_internal/webcodecs/
 crbug.com/591099 wpt_internal/webcodecs/annexb_decoding.any.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 5ed2be3..c7adc99 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -7249,10 +7249,10 @@
 crbug.com/1197464 [ Mac ] virtual/scroll-unification/plugins/refcount-leaks.html [ Failure Pass ]
 
 # File System Access API tests that depend on mojo interfaces that are only exposed behind a flag.
-crbug.com/1218431 external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle-dedicated-worker.https.window.html [ Skip ]
-crbug.com/1218431 virtual/file-system-access-access-handle/external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle-dedicated-worker.https.window.html [ Pass ]
-crbug.com/1218431 external/wpt/file-system-access/local_FileSystemFileHandle-create-sync-access-handle-dedicated-worker-manual.https.html [ Skip ]
-crbug.com/1218431 virtual/file-system-access-access-handle/external/wpt/file-system-access/local_FileSystemFileHandle-create-sync-access-handle-dedicated-worker-manual.https.html [ Pass ]
+crbug.com/1218431 external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle-dedicated-worker.https.tentative.window.html [ Skip ]
+crbug.com/1218431 virtual/file-system-access-access-handle/external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle-dedicated-worker.https.tentative.window.html [ Pass ]
+crbug.com/1218431 external/wpt/file-system-access/local_FileSystemFileHandle-create-sync-access-handle-dedicated-worker-manual.https.tentative.html [ Skip ]
+crbug.com/1218431 virtual/file-system-access-access-handle/external/wpt/file-system-access/local_FileSystemFileHandle-create-sync-access-handle-dedicated-worker-manual.https.tentative.html [ Pass ]
 
 # DevTools roll
 crbug.com/1187573 http/tests/devtools/throttling/mobile-throttling.js [ Skip ]
@@ -7288,3 +7288,6 @@
 
 # Depends on fixing WPT cross-origin iframe click flake in crbug.com/1066891.
 crbug.com/1227710 external/wpt/bluetooth/requestDevice/cross-origin-iframe.sub.https.html [ Failure Pass ]
+
+# Sheriff 2021-07-13
+crbug.com/1220114 [ Linux ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-access-from-shadow-dom-ref.html b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-access-from-shadow-dom-ref.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-access-from-shadow-dom-ref.html
rename to third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-access-from-shadow-dom-ref.html
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-access-from-shadow-dom.html b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-access-from-shadow-dom.html
similarity index 80%
rename from third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-access-from-shadow-dom.html
rename to third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-access-from-shadow-dom.html
index 560b3c4..a99bbcc 100644
--- a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-access-from-shadow-dom.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-access-from-shadow-dom.html
@@ -1,12 +1,10 @@
 <!DOCTYPE html>
 <title>Counter styles defined in the document tree scope should be globally accessible</title>
 <link rel="help" href="https://drafts.csswg.org/css-counter-styles-3/#the-counter-style-rule">
-<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5693">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
 <link rel="author" href="mailto:xiaochengh@chromium.org">
 <link rel="match" href="counter-style-access-from-shadow-dom-ref.html">
 
-<!-- TODO(xiaochengh): Move test to WPT after standardizing the behavior -->
-
 <style>
 @counter-style foo {
   system: fixed;
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom-ref.html b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom-ref.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom-ref.html
rename to third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom-ref.html
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom.html b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom.html
similarity index 88%
rename from third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom.html
rename to third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom.html
index 1aaa6eb..39fb5f8 100644
--- a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-style-fallbacks-in-shadow-dom.html
@@ -1,12 +1,10 @@
 <!DOCTYPE html>
 <title>Counter style references are tree-scoped, the same name may dereference to different rules</title>
 <link rel="help" href="https://drafts.csswg.org/css-counter-styles-3/#the-counter-style-rule">
-<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5693">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
 <link rel="author" href="mailto:xiaochengh@chromium.org">
 <link rel="match" href="counter-style-fallbacks-in-shadow-dom-ref.html">
 
-<!-- TODO(xiaochengh): Move test to WPT after standardizing the behavior -->
-
 <style>
 @counter-style foo {
   system: cyclic;
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-styles-override-in-shadow-dom-ref.html b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-styles-override-in-shadow-dom-ref.html
similarity index 100%
rename from third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-styles-override-in-shadow-dom-ref.html
rename to third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-styles-override-in-shadow-dom-ref.html
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-styles-override-in-shadow-dom.html b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-styles-override-in-shadow-dom.html
similarity index 87%
rename from third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-styles-override-in-shadow-dom.html
rename to third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-styles-override-in-shadow-dom.html
index ab66ac1..908cafa 100644
--- a/third_party/blink/web_tests/wpt_internal/css/css-counter-styles/counter-styles-override-in-shadow-dom.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-counter-styles/counter-styles-override-in-shadow-dom.html
@@ -1,12 +1,10 @@
 <!DOCTYPE html>
 <title>Counter style rules in shadow DOM can override rules in ancestor scopes</title>
 <link rel="help" href="https://drafts.csswg.org/css-counter-styles-3/#the-counter-style-rule">
-<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5693">
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
 <link rel="author" href="mailto:xiaochengh@chromium.org">
 <link rel="match" href="counter-styles-override-in-shadow-dom-ref.html">
 
-<!-- TODO(xiaochengh): Move test to WPT after standardizing the behavior -->
-
 <style>
 @counter-style foo {
   system: fixed;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-008.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-008.html
new file mode 100644
index 0000000..e2c7c02
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-008.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1227884">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<meta name="assert" content="top: 100% doesn't resolve if the parent doesn't have a height specified.">
+<p>Test passes if there is a filled green square.</p>
+<table style="border-spacing: 0; background: red;">
+  <tbody>
+    <tr style="position: relative; top: 100%;">
+      <td style="padding: 0;">
+        <div style="width: 100px; height: 100px; background: green;"></div>
+      </td>
+    </tr>
+  </tbody>
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-009.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-009.html
new file mode 100644
index 0000000..5f4093d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-009.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1227884">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<meta name="assert" content="top: 100% doesn't resolve if the parent doesn't have a height specified.">
+<p>Test passes if there is a filled green square.</p>
+<table style="border-spacing: 0; background: red;">
+  <tbody style="position: relative; top: 100%;">
+    <tr>
+      <td style="padding: 0;">
+        <div style="width: 100px; height: 100px; background: green;"></div>
+      </td>
+    </tr>
+  </tbody>
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-010.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-010.html
new file mode 100644
index 0000000..4069735
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-010.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1227884">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<meta name="assert" content="top: 100% doesn't resolve if the parent doesn't have a height specified.">
+<p>Test passes if there is a filled green square.</p>
+<table style="border-spacing: 0; background: red;">
+  <tbody>
+    <tr>
+      <td style="position: relative; top: 100%; padding: 0;">
+        <div style="width: 100px; height: 100px; background: green;"></div>
+      </td>
+    </tr>
+  </tbody>
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-011.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-011.html
new file mode 100644
index 0000000..aaf7492
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-011.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1227884">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<meta name="assert" content="top: 100% doesn't resolves against the specified parent height (not the used height).">
+<p>Test passes if there is a filled green square.</p>
+<table style="border-spacing: 0; background: red;">
+  <tbody style="height: 10px;">
+    <tr style="position: relative; top: 100%;">
+      <td style="padding: 0;">
+        <div style="position: relative; top: -10px; width: 100px; height: 100px; background: green;"></div>
+      </td>
+    </tr>
+  </tbody>
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-012.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-012.html
new file mode 100644
index 0000000..c2debe1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-012.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1227884">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<meta name="assert" content="top: 100% doesn't resolves against the specified parent height (not the used height).">
+<p>Test passes if there is a filled green square.</p>
+<table style="border-spacing: 0; background: red; height: 10px;">
+  <tbody style="position: relative; top: 100%;">
+    <tr>
+      <td style="padding: 0;">
+        <div style="position: relative; top: -10px; width: 100px; height: 100px; background: green;"></div>
+      </td>
+    </tr>
+  </tbody>
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-013.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-013.html
new file mode 100644
index 0000000..94888b15
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-relative-013.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1227884">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<meta name="assert" content="top: 100% doesn't resolves against the specified parent height (not the used height).">
+<p>Test passes if there is a filled green square.</p>
+<table style="border-spacing: 0; background: red;">
+  <tbody>
+    <tr style="height: 10px;">
+      <td style="position: relative; top: 100%; padding: 0;">
+        <div style="position: relative; top: -10px; width: 100px; height: 100px; background: green;"></div>
+      </td>
+    </tr>
+  </tbody>
+</table>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/colspan-redistribution.html b/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/colspan-redistribution.html
index bf744da..3c4d57c1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/colspan-redistribution.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/colspan-redistribution.html
@@ -458,6 +458,58 @@
   </tr>
 </table>
 
+<h2>Colspan&gt;1 cell's maximum width distribution</h2>
+<li>Only constrained colspans can distribute max-width over fixed columns</li>
+
+<p class="testdesc">Colspan: constrained. Col: constrained
+Constrained colspan redistributes widths over constrained cols.
+</p>
+<table data-expected-width=216>
+  <col style="width:50px">
+  <col style="width:50px">
+  <tr>
+    <td>50</td>
+    <td>50</td>
+  </tr>
+  <tr>
+    <td colspan=2 style="width:200px" data-expected-width=200>200</td>
+  </tr>
+</table>
+<p class="testdesc">Colspan: unconstrained. Col: constrained
+Colspan max-width does not get redistributed.
+</p>
+<table data-expected-width=124>
+  <col style="width:50px">
+  <col style="width:50px">
+  <tr>
+    <td>50</td>
+    <td>50</td>
+  </tr>
+  <tr>
+    <td colspan=2 data-expected-width=108><div style="width:50px">50</div><div style="width:50px">50</div><div style="width:50px">50</div><div style="width:50px">50</div></td>
+  </tr>
+</table>
+
+<p class="testdesc">Colspan: unconstrained, Col: constrained/%
+Colspanned col distributes width over %ge column.
+max-guess is 50px + 200px*50% = 150px
+distributable_size is 50px
+%ge column gets percentage_size + distributable_size = 150px
+Later, this makes table 300px wide.
+</p>
+<p class="error">FF, Legacy, and TablesNG all disagree about the correct widths. FF feels more like the right answer, but I can't figure out the math behind it.</p>
+<table data-expected-width=308>
+  <col style="width:50px">
+  <col style="width:50%">
+  <tr>
+    <td data-expected-width=142>50</td>
+    <td>50</td>
+  </tr>
+  <tr>
+    <td colspan=2 data-expected-width=292><div style="width:50px">50</div><div style="width:50px">50</div><div style="width:50px">50</div><div style="width:50px">50</div></td>
+  </tr>
+</table>
+
 <h2>Merging cell widths into column widths</h2>
 <p>What happens when different types of cells get merged into a single column?</p>
 <p class="testdesc">C0:0 25%/50px C0:1 50%/40px
diff --git a/third_party/blink/web_tests/external/wpt/file-system-access/local_FileSystemFileHandle-create-sync-access-handle-dedicated-worker-manual.https.html b/third_party/blink/web_tests/external/wpt/file-system-access/local_FileSystemFileHandle-create-sync-access-handle-dedicated-worker-manual.https.tentative.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/file-system-access/local_FileSystemFileHandle-create-sync-access-handle-dedicated-worker-manual.https.html
rename to third_party/blink/web_tests/external/wpt/file-system-access/local_FileSystemFileHandle-create-sync-access-handle-dedicated-worker-manual.https.tentative.html
diff --git a/third_party/blink/web_tests/external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle-dedicated-worker.https.window.js b/third_party/blink/web_tests/external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle-dedicated-worker.https.tentative.window.js
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle-dedicated-worker.https.window.js
rename to third_party/blink/web_tests/external/wpt/file-system-access/sandboxed_FileSystemFileHandle-create-sync-access-handle-dedicated-worker.https.tentative.window.js
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/webusb-test.js b/third_party/blink/web_tests/external/wpt/resources/chromium/webusb-test.js
index 5775c071..10140a5 100644
--- a/third_party/blink/web_tests/external/wpt/resources/chromium/webusb-test.js
+++ b/third_party/blink/web_tests/external/wpt/resources/chromium/webusb-test.js
@@ -283,10 +283,12 @@
 
     return {
       status: mojom.UsbTransferStatus.OK,
-      data: [
-        length >> 8, length & 0xff, params.request, params.value >> 8,
-        params.value & 0xff, params.index >> 8, params.index & 0xff
-      ]
+      data: {
+        buffer: [
+          length >> 8, length & 0xff, params.request, params.value >> 8,
+          params.value & 0xff, params.index >> 8, params.index & 0xff
+        ]
+      }
     };
   }
 
@@ -311,7 +313,8 @@
     let data = new Array(length);
     for (let i = 0; i < length; ++i)
       data[i] = i & 0xff;
-    return Promise.resolve({status: mojom.UsbTransferStatus.OK, data: data});
+    return Promise.resolve(
+        {status: mojom.UsbTransferStatus.OK, data: {buffer: data}});
   }
 
   genericTransferOut(endpointNumber, data, timeout) {
@@ -338,7 +341,7 @@
         status: mojom.UsbTransferStatus.OK
       };
     }
-    return Promise.resolve({ data: data, packets: packets });
+    return Promise.resolve({data: {buffer: data}, packets: packets});
   }
 
   isochronousTransferOut(endpointNumber, data, packetLengths, timeout) {
diff --git a/third_party/blink/web_tests/inspector-protocol/resources/render-blocking-frame.html b/third_party/blink/web_tests/inspector-protocol/resources/render-blocking-frame.html
index bc10ae2..adeae79 100644
--- a/third_party/blink/web_tests/inspector-protocol/resources/render-blocking-frame.html
+++ b/third_party/blink/web_tests/inspector-protocol/resources/render-blocking-frame.html
@@ -7,6 +7,7 @@
 <link rel=stylesheet href='style.css?head'>
 <link rel=stylesheet href='style.css?head_print' media=print>
 <link rel=preload as=style href='style.css?preload'>
+<link rel=preload as=style href='style.css?preload_used'>
 <body>
 <link rel=stylesheet href='importer.css?body'>
 <link rel=stylesheet href='style.css?body_print' media=print>
@@ -15,3 +16,4 @@
       document.write("<link rel=stylesheet href='../resources/style.css?dynamicDocWriteBody'>");
       document.write("<link rel=stylesheet href='../resources/style.css?dynamicDocWritePrintBody' media=print>");
 </script>
+<link rel=stylesheet href='style.css?preload_used'>
diff --git a/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-expected.txt b/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-expected.txt
index 99e940e..12db4ff 100644
--- a/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-expected.txt
+++ b/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-expected.txt
@@ -1,6 +1,7 @@
 Tests various style traces.
 Recording started
 Tracing complete
+Previous value requestId is identical to the current one
 importer.css: blocking
 importer_print.css: non_blocking
 style.css?dynamicDOM: dynamically_injected_non_blocking
@@ -11,4 +12,5 @@
 style.css?imported: blocking
 style.css?imported_print: non_blocking
 style.css?preload: non_blocking
+style.css?preload_used: dynamically_injected_non_blocking
 
diff --git a/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-frame-expected.txt b/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-frame-expected.txt
index ae9e10c..8845abd 100644
--- a/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-frame-expected.txt
+++ b/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-frame-expected.txt
@@ -1,6 +1,7 @@
 Tests various style traces.
 Recording started
 Tracing complete
+Previous value requestId is identical to the current one
 importer.css?body: in_body_parser_blocking
 style.css?body_print: non_blocking
 style.css?dynamicDocWriteBody: in_body_parser_blocking
@@ -11,4 +12,5 @@
 style.css?head_print: non_blocking
 style.css?imported: in_body_parser_blocking
 style.css?preload: non_blocking
+style.css?preload_used: in_body_parser_blocking
 
diff --git a/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-frame.js b/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-frame.js
index 4e372c5c..c09161e 100644
--- a/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-frame.js
+++ b/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style-frame.js
@@ -1,7 +1,7 @@
 (async function(testRunner) {
-  // The number includes the frame, the 4 CSS files it loads directly, and the
+  // The number includes the frame, the 5 CSS files it loads directly, and the
   // one imported by them.
-  const numberOfURLs = 11;
+  const numberOfURLs = 12;
 
   var {page, session, dp} = await testRunner.startHTML(`
       <head></head>
@@ -27,17 +27,26 @@
   }
 
   const events = await tracingHelper.stopTracing();
-  const requestEvents = events.filter(e => e.name == "ResourceSendRequest");
+  const requestEvents = events.filter(e =>
+      (e.name == "ResourceSendRequest" ||
+       e.name == "PreloadRenderBlockingStatusChange"));
   const resources = new Map();
   for (let e of requestEvents) {
     const data = e['args']['data'];
     const url_list = data['url'].split('/');
     const url = url_list[url_list.length - 1];
     if (url.includes("css")) {
-      resources.set(url, data['renderBlocking']);
+      const previousValue = resources.get(url);
+      if (previousValue) {
+        const descriptor = (previousValue[1] === data['requestId']) ?
+          "identical" : "different";
+        testRunner.log(`Previous value requestId is ${descriptor} to the ` +
+          `current one`);
+      }
+      resources.set(url, [data['renderBlocking'], data['requestId']]);
     }
   }
   for (const resource of Array.from(resources.keys()).sort())
-    testRunner.log(`${resource}: ${resources.get(resource)}`);
+    testRunner.log(`${resource}: ${resources.get(resource)[0]}`);
   testRunner.completeTest();
 })
diff --git a/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style.js b/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style.js
index 75852a6..210de9d 100644
--- a/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style.js
+++ b/third_party/blink/web_tests/inspector-protocol/timeline/render-blocking-style.js
@@ -1,6 +1,6 @@
 (async function(testRunner) {
   // The number includes the 2 imported CSS files
-  const numberOfURLs = 10;
+  const numberOfURLs = 11;
 
   // Test traces
   var {page, session, dp} = await testRunner.startHTML(`
@@ -28,6 +28,19 @@
       link.as = "style";
       document.head.appendChild(link);
 
+      // Add a style preload with DOM API to be used later
+      link = document.createElement("link");
+      link.href = "../resources/style.css?preload_used";
+      link.rel = "preload";
+      link.as = "style";
+      document.head.appendChild(link);
+
+      // Use the preload
+      link = document.createElement("link");
+      link.href = "../resources/style.css?preload_used";
+      link.rel = "stylesheet";
+      document.head.appendChild(link);
+
       // Add a dynamic style with document.write
       document.write("<link rel=stylesheet href='../resources/style.css?dynamicDocWrite'>");
       document.write("<link rel=stylesheet href='../resources/style.css?dynamicDocWritePrint' media=print>");
@@ -48,7 +61,9 @@
   }
 
   const events = await tracingHelper.stopTracing();
-  const requestEvents = events.filter(e => e.name == "ResourceSendRequest");
+  const requestEvents = events.filter(e =>
+      (e.name == "ResourceSendRequest" ||
+       e.name == "PreloadRenderBlockingStatusChange"));
 
   const resources = new Map();
   for (let e of requestEvents) {
@@ -56,10 +71,17 @@
     const url_list = data['url'].split('/');
     const url = url_list[url_list.length - 1];
     if (url.includes("css")) {
-      resources.set(url, data['renderBlocking']);
+      const previousValue = resources.get(url);
+      if (previousValue) {
+        const descriptor = (previousValue[1] === data['requestId']) ?
+          "identical" : "different";
+        testRunner.log(`Previous value requestId is ${descriptor} to the ` +
+          `current one`);
+      }
+      resources.set(url, [data['renderBlocking'], data['requestId']]);
     }
   }
   for (const resource of Array.from(resources.keys()).sort())
-    testRunner.log(`${resource}: ${resources.get(resource)}`);
+    testRunner.log(`${resource}: ${resources.get(resource)[0]}`);
   testRunner.completeTest();
 })
diff --git a/third_party/blink/web_tests/platform/linux/tables/mozilla_expected_failures/bugs/bug47163-expected.png b/third_party/blink/web_tests/platform/linux/tables/mozilla_expected_failures/bugs/bug47163-expected.png
index 90fc151..48d081d 100644
--- a/third_party/blink/web_tests/platform/linux/tables/mozilla_expected_failures/bugs/bug47163-expected.png
+++ b/third_party/blink/web_tests/platform/linux/tables/mozilla_expected_failures/bugs/bug47163-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/tables/mozilla_expected_failures/bugs/bug47163-expected.png b/third_party/blink/web_tests/platform/mac/tables/mozilla_expected_failures/bugs/bug47163-expected.png
index 15d23402..7bbf26af 100644
--- a/third_party/blink/web_tests/platform/mac/tables/mozilla_expected_failures/bugs/bug47163-expected.png
+++ b/third_party/blink/web_tests/platform/mac/tables/mozilla_expected_failures/bugs/bug47163-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/tables/mozilla_expected_failures/bugs/bug47163-expected.png b/third_party/blink/web_tests/platform/win/tables/mozilla_expected_failures/bugs/bug47163-expected.png
index 3b7028f..4dba2b3 100644
--- a/third_party/blink/web_tests/platform/win/tables/mozilla_expected_failures/bugs/bug47163-expected.png
+++ b/third_party/blink/web_tests/platform/win/tables/mozilla_expected_failures/bugs/bug47163-expected.png
Binary files differ
diff --git a/third_party/closure_compiler/externs/accessibility_private.js b/third_party/closure_compiler/externs/accessibility_private.js
index e67ffbf..748afdd9 100644
--- a/third_party/closure_compiler/externs/accessibility_private.js
+++ b/third_party/closure_compiler/externs/accessibility_private.js
@@ -251,6 +251,7 @@
  */
 chrome.accessibilityPrivate.AccessibilityFeature = {
   SELECT_TO_SPEAK_NAVIGATION_CONTROL: 'selectToSpeakNavigationControl',
+  ENHANCED_NETWORK_VOICES: 'enhancedNetworkVoices',
 };
 
 /**
@@ -470,7 +471,8 @@
 /**
  * Gets the DOM key string for the given key code, taking into account the
  * current input method locale, and assuming the key code is for U.S. input. For
- * example, / would return the string ! if the current input method is French.
+ * example, the key code for '/' would return the string '!' if the current
+ * input method is French.
  * @param {number} keyCode
  * @param {function(string): void} callback Called with the resulting Dom key
  *     string.
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium
index 8a21c10..49dc100 100644
--- a/third_party/metrics_proto/README.chromium
+++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@
 Name: Metrics Protos
 Short Name: metrics_proto
 URL: This is the canonical public repository
-Version: 381096221
-Date: 2021/06/23 UTC
+Version: 384326864
+Date: 2021/07/12 UTC
 License: BSD
 Security Critical: Yes
 
diff --git a/third_party/metrics_proto/system_profile.proto b/third_party/metrics_proto/system_profile.proto
index 7941bc02..3b16229 100644
--- a/third_party/metrics_proto/system_profile.proto
+++ b/third_party/metrics_proto/system_profile.proto
@@ -17,7 +17,7 @@
 // Almost all the fields should be populated on every upload. (The only
 // exception is some fields in the stability section that are only uploaded
 // once per browsing session, usually shortly after startup.)
-// Next tag: 39
+// Next tag: 40
 message SystemProfileProto {
   // The time when the client was compiled/linked, in seconds since the epoch.
   optional int64 build_timestamp = 1;
@@ -80,6 +80,33 @@
   // For privacy, this is rounded to the nearest hour.
   optional int64 install_date = 16;
 
+  // A message about the cloned install detection that helps improve data
+  // quality by identifying potential VMs and bots. This message will be
+  // set in every record after the client has ever been reset due to cloned
+  // install detection. However, the `cloned_from_client_id`
+  // field will only be set in the resetting session because this is not
+  // persisted in the local prefs.
+  // Next tag: 5
+  message ClonedInstallInfo {
+    // The latest timestamp we reset a cloned client’s client id, in seconds
+    // since the epoch. For privacy, this is rounded to the nearest hour.
+    optional int64 last_timestamp = 1;
+
+    // cloned install detector only; any other way of resetting client_id
+    // doesn't touch this field. This field is only reported in the
+    // resetting session.
+    optional fixed64 cloned_from_client_id = 2;
+
+    // The first timestamp when we reset a cloned client’s client id, in seconds
+    // since the epoch. For privacy, this is rounded to the nearest hour.
+    optional int64 first_timestamp = 3;
+
+    // The number of times this client has been reset due to cloned install.
+    // Increment by one per reset happens.
+    optional int32 count = 4;
+  }
+  optional ClonedInstallInfo cloned_install_info = 39;
+
   // The non-identifying low entropy source value. This value seeds the
   // pseudorandom generator which picks experimental groups.
   optional int32 low_entropy_source = 31;
diff --git a/third_party/wayland-protocols/BUILD.gn b/third_party/wayland-protocols/BUILD.gn
index 49b2357e..15edf1bc 100644
--- a/third_party/wayland-protocols/BUILD.gn
+++ b/third_party/wayland-protocols/BUILD.gn
@@ -17,6 +17,10 @@
       [ "src/unstable/primary-selection/primary-selection-unstable-v1.xml" ]
 }
 
+wayland_protocol("idle_inhibit_protocol") {
+  sources = [ "src/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml" ]
+}
+
 wayland_protocol("input_method_protocol") {
   sources = [ "src/unstable/input-method/input-method-unstable-v1.xml" ]
 }
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index b62b6a8..4e09b62 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -934,34 +934,43 @@
 
     if (underlying_type.property_type.is_fundamental or
         underlying_type.is_serializable_function):
-      if is_ptr:
-        (c.Append('%(cpp_type)s temp;')
-          .Sblock('if (!%s) {' % cpp_util.GetAsFundamentalValue(
-                      self._type_helper.FollowRef(type_), src_var, '&temp'))
+      is_string_or_function = (
+        underlying_type.property_type == PropertyType.STRING
+        or (underlying_type.property_type == PropertyType.FUNCTION
+          and underlying_type.is_serializable_function))
+      c.Append('auto%s temp = %s;' % (
+        '*' if is_string_or_function else '',
+        cpp_util.GetAsFundamentalValue(underlying_type, src_var)
+      ))
+      if is_string_or_function:
+        (c.Sblock('if (!temp) {')
           .Concat(self._AppendError16(
             'u"\'%%(key)s\': expected ' + '%s, got " + %s' % (
                 type_.name,
                 self._util_cc_helper.GetValueTypeString(
                     '%%(src_var)s', True)))))
-        c.Append('%(dst_var)s.reset();')
-        c.Append('return %(failure_value)s;')
-        (c.Eblock('}')
-          .Append('else')
-          .Append('  %(dst_var)s = std::make_unique<%(cpp_type)s>(temp);')
-        )
       else:
-        (c.Sblock('if (!%s) {' % cpp_util.GetAsFundamentalValue(
-                      self._type_helper.FollowRef(type_),
-                      src_var,
-                      '&%s' % dst_var))
+        (c.Sblock('if (!temp.has_value()) {')
           .Concat(self._AppendError16(
             'u"\'%%(key)s\': expected ' + '%s, got " + %s' % (
                 type_.name,
                 self._util_cc_helper.GetValueTypeString(
-                    '%%(src_var)s', True))))
-          .Append('return %(failure_value)s;')
-          .Eblock('}')
-        )
+                    '%%(src_var)s', True)))))
+      if is_ptr:
+        c.Append('%(dst_var)s.reset();')
+      c.Append('return %(failure_value)s;')
+      (c.Eblock('}'))
+      if is_ptr:
+        if is_string_or_function:
+          c.Append('%(dst_var)s = std::make_unique<%(cpp_type)s>(*temp);')
+        else:
+          c.Append('%(dst_var)s = ' +
+            'std::make_unique<%(cpp_type)s>(temp.value());')
+      else:
+        if is_string_or_function:
+          c.Append('%(dst_var)s = *temp;')
+        else:
+          c.Append('%(dst_var)s = temp.value();')
     elif underlying_type.property_type == PropertyType.OBJECT:
       if is_ptr:
         (c.Append('const base::DictionaryValue* dictionary = nullptr;')
diff --git a/tools/json_schema_compiler/cpp_util.py b/tools/json_schema_compiler/cpp_util.py
index 1d76e2d..a6b741a 100644
--- a/tools/json_schema_compiler/cpp_util.py
+++ b/tools/json_schema_compiler/cpp_util.py
@@ -56,27 +56,26 @@
     result = '_' + result
   return result
 
-def GetAsFundamentalValue(type_, src, dst):
+def GetAsFundamentalValue(type_, src):
   """Returns the C++ code for retrieving a fundamental type from a
   Value into a variable.
 
   src: Value*
-  dst: Property*
   """
   if type_.property_type == PropertyType.BOOLEAN:
-    s = '%s->GetAsBoolean(%s)'
+    s = '%s->GetIfBool()'
   elif type_.property_type == PropertyType.DOUBLE:
-    s = '%s->GetAsDouble(%s)'
+    s = '%s->GetIfDouble()'
   elif type_.property_type == PropertyType.INTEGER:
-    s = '%s->GetAsInteger(%s)'
+    s = '%s->GetIfInt()'
   elif (type_.property_type == PropertyType.STRING or
       (type_.property_type == PropertyType.FUNCTION and
            type_.is_serializable_function)):
-    s = '%s->GetAsString(%s)'
+    s = '%s->GetIfString()'
   else:
     raise ValueError('Type %s is not a fundamental value' % type_.name)
 
-  return s % (src, dst)
+  return s % src
 
 
 def GetValueType(type_):
diff --git a/tools/json_schema_compiler/test/idl_schemas_unittest.cc b/tools/json_schema_compiler/test/idl_schemas_unittest.cc
index a6deda7..4d9d9b3 100644
--- a/tools/json_schema_compiler/test/idl_schemas_unittest.cc
+++ b/tools/json_schema_compiler/test/idl_schemas_unittest.cc
@@ -46,7 +46,7 @@
   EXPECT_EQ(5, f2_params->x);
 
   // Test Function3, which takes a MyType1 parameter.
-  list.Clear();
+  list.ClearList();
   std::unique_ptr<base::DictionaryValue> tmp(new base::DictionaryValue());
   tmp->SetInteger("x", 17);
   tmp->SetString("y", "hello");
@@ -93,7 +93,7 @@
 
   // Similar to above, but a function with one required and one optional
   // argument.
-  list.Clear();
+  list.ClearList();
   list.AppendInteger(8);
   std::unique_ptr<Function8::Params> f8_params =
       Function8::Params::Create(list);
@@ -105,11 +105,11 @@
   EXPECT_EQ("foo", *(f8_params->arg2));
 
   // Test a function with an optional argument of custom type.
-  list.Clear();
+  list.ClearList();
   std::unique_ptr<Function9::Params> f9_params =
       Function9::Params::Create(list);
   EXPECT_EQ(NULL, f9_params->arg.get());
-  list.Clear();
+  list.ClearList();
   std::unique_ptr<base::DictionaryValue> tmp(new base::DictionaryValue());
   tmp->SetInteger("x", 17);
   tmp->SetString("y", "hello");
@@ -138,7 +138,7 @@
   EXPECT_TRUE(f10_params->y.empty());
 
   // Same function, but this time with 2 values in the array.
-  list.Clear();
+  list.ClearList();
   list.AppendInteger(33);
   std::unique_ptr<base::ListValue> sublist(new base::ListValue);
   sublist->AppendInteger(34);
@@ -152,7 +152,7 @@
   EXPECT_EQ(35, f10_params->y[1]);
 
   // Now test a function which takes an array of a defined type.
-  list.Clear();
+  list.ClearList();
   MyType1 a;
   MyType1 b;
   a.x = 5;
diff --git a/tools/json_schema_compiler/util.h b/tools/json_schema_compiler/util.h
index 865ed178..9a8394da 100644
--- a/tools/json_schema_compiler/util.h
+++ b/tools/json_schema_compiler/util.h
@@ -161,7 +161,7 @@
 // implemented for |T|.
 template <class T>
 void PopulateListFromArray(const std::vector<T>& from, base::ListValue* out) {
-  out->Clear();
+  out->ClearList();
   for (const T& item : from)
     AddItemToList(item, out);
 }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index dcd7384f..246728d 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -7503,6 +7503,7 @@
   <int value="246" label="MDDH_INVALID_ALL_ORIGINS_PERMITTED"/>
   <int value="247" label="MDDH_INVALID_PERMITTED_ORIGIN"/>
   <int value="248" label="MDDH_NOT_TOP_LEVEL"/>
+  <int value="249" label="RFH_DID_CHANGE_IFRAME_ATTRIBUTE"/>
 </enum>
 
 <enum name="BadMessageReasonExtensions">
@@ -48843,6 +48844,7 @@
   <int value="61466986" label="AsyncDns:disabled"/>
   <int value="63187126" label="DownloadsAutoResumptionNative:enabled"/>
   <int value="64942701" label="OfflinePagesSvelteConcurrentLoading:disabled"/>
+  <int value="65245449" label="FilesBannerFramework:enabled"/>
   <int value="66897259" label="ModalPermissionDialogView:enabled"/>
   <int value="67639499" label="stop-loading-in-background:disabled"/>
   <int value="73929836" label="VrBrowsingInCustomTab:enabled"/>
@@ -50597,6 +50599,7 @@
   <int value="1515196403" label="fast-user-switching"/>
   <int value="1515334367" label="ToolbarMicIphAndroid:disabled"/>
   <int value="1517863401" label="history-entry-requires-user-gesture"/>
+  <int value="1517988103" label="FilesBannerFramework:disabled"/>
   <int value="1518833340" label="MediaAppDisplayExif:enabled"/>
   <int value="1518946321" label="DisableProcessReuse:disabled"/>
   <int value="1519067750" label="ActionableContentSettings:disabled"/>
@@ -70879,6 +70882,11 @@
   <int value="1" label="Cached StyleSheetContents was reused"/>
 </enum>
 
+<enum name="RestoreResult">
+  <int value="0" label="Finish"/>
+  <int value="1" label="Not finish"/>
+</enum>
+
 <enum name="RestoreSetting">
   <int value="0" label="Unknown"/>
   <int value="1" label="Always restore"/>
@@ -81437,7 +81445,7 @@
   <int value="1" label="Second attempt"/>
 </enum>
 
-<enum name="TrustedVaultKeyRetrievalTrigger">
+<enum name="TrustedVaultUserActionTrigger">
   <int value="0" label="Settings page"/>
   <int value="1" label="Profile menu"/>
   <int value="2" label="OS-level notification"/>
diff --git a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
index dd04866..4120dec 100644
--- a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
@@ -801,7 +801,7 @@
 </histogram>
 
 <histogram name="Accessibility.LiveCaption" enum="BooleanEnabled"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>katie@chromium.org</owner>
   <owner>abigailbklein@google.com</owner>
   <owner>evliu@google.com</owner>
@@ -894,7 +894,7 @@
 </histogram>
 
 <histogram name="Accessibility.LiveCaption.FeatureEnabled"
-    enum="BooleanEnabled" expires_after="2021-11-07">
+    enum="BooleanEnabled" expires_after="2022-01-09">
   <owner>katie@chromium.org</owner>
   <owner>abigailbklein@google.com</owner>
   <owner>evliu@google.com</owner>
@@ -929,7 +929,7 @@
 </histogram>
 
 <histogram name="Accessibility.LiveCaption.Session"
-    enum="LiveCaptionSessionEvent" expires_after="2021-11-07">
+    enum="LiveCaptionSessionEvent" expires_after="2022-01-09">
   <owner>katie@chromium.org</owner>
   <owner>abigailbklein@google.com</owner>
   <owner>evliu@google.com</owner>
@@ -970,7 +970,7 @@
 </histogram>
 
 <histogram name="Accessibility.LiveCaption.UseSodaForLiveCaption"
-    enum="BooleanEnabled" expires_after="2021-11-07">
+    enum="BooleanEnabled" expires_after="2022-01-09">
   <owner>abigailbklein@google.com</owner>
   <owner>evliu@google.com</owner>
   <owner>chrome-a11y-core@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml
index 21b6cbb..3cb27f8c 100644
--- a/tools/metrics/histograms/histograms_xml/android/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -471,7 +471,7 @@
 </histogram>
 
 <histogram name="Android.ChromeStartupDelegate.FailureReason"
-    enum="ChromeStartupDelegateFailureType" expires_after="2021-11-07">
+    enum="ChromeStartupDelegateFailureType" expires_after="2022-01-09">
   <owner>gangwu@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
@@ -481,7 +481,7 @@
 </histogram>
 
 <histogram name="Android.ChromeStartupDelegate.Result"
-    enum="ChromeStartupDelegateResult" expires_after="2021-11-07">
+    enum="ChromeStartupDelegateResult" expires_after="2022-01-09">
   <owner>gangwu@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
@@ -1851,7 +1851,7 @@
 </histogram>
 
 <histogram name="Android.Omnibox.InvalidMatch" enum="MatchResult"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>ender@chromium.org</owner>
   <owner>tedchoc@chromium.org</owner>
   <owner>mpearson@chromium.org</owner>
@@ -2870,7 +2870,7 @@
 </histogram>
 
 <histogram name="Android.WebView.ComponentUpdater.GetFilesDuration" units="ms"
-    expires_after="2021-10-08">
+    expires_after="2022-01-09">
   <owner>nator@chromium.org</owner>
   <owner>hazems@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
@@ -2882,7 +2882,7 @@
 </histogram>
 
 <histogram name="Android.WebView.ComponentUpdater.GetFilesResult"
-    enum="WebViewComponentUpdaterGetFilesResult" expires_after="2021-10-08">
+    enum="WebViewComponentUpdaterGetFilesResult" expires_after="2022-01-09">
   <owner>nator@chromium.org</owner>
   <owner>hazems@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
diff --git a/tools/metrics/histograms/histograms_xml/apps/histograms.xml b/tools/metrics/histograms/histograms_xml/apps/histograms.xml
index 2a6ea252..621360b 100644
--- a/tools/metrics/histograms/histograms_xml/apps/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/apps/histograms.xml
@@ -48,6 +48,15 @@
   <variant name="User" summary="Installed by user"/>
 </variants>
 
+<variants name="RestoreAction">
+  <variant name="CloseByUser"
+      summary="The full restore notfication is closed by user"/>
+  <variant name="CloseNotByUser"
+      summary="The full restore notfication is not closed by user"/>
+  <variant name="NotRestore" summary="No thanks is clicked"/>
+  <variant name="Restore" summary="Restore is clicked"/>
+</variants>
+
 <histogram name="Apps.ActivatedCount.{AppType}" units="ms"
     expires_after="2021-10-28">
   <owner>dominickn@chromium.org</owner>
@@ -1017,7 +1026,7 @@
 </histogram>
 
 <histogram name="Apps.AppListAppTypeClicked" enum="AppListAppType"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>charleszhao@chromium.org</owner>
   <owner>pdyson@chromium.org</owner>
   <summary>
@@ -2175,6 +2184,27 @@
   </summary>
 </histogram>
 
+<histogram name="Apps.RestoreArcAppsResult" enum="RestoreResult"
+    expires_after="2021-12-30">
+  <owner>nancylingwang@chromium.org</owner>
+  <owner>sstan@chromium.org</owner>
+  <summary>
+    Records whether all Arc app windows have been restored. This is logged when
+    the restoration process finishes during the system startup phase.
+  </summary>
+</histogram>
+
+<histogram name="Apps.RestoreArcWindowCount" units="units"
+    expires_after="2021-12-30">
+  <owner>nancylingwang@chromium.org</owner>
+  <owner>sstan@chromium.org</owner>
+  <summary>
+    Records the number of restored ARC app windows in Chrome OS. This is logged
+    during the system startup phase. This histogram is capped at 100; values
+    above this go into the overflow bucket.
+  </summary>
+</histogram>
+
 <histogram name="Apps.RestoredAppLaunch" enum="AppType"
     expires_after="2021-11-01">
   <owner>nancylingwang@chromium.org</owner>
@@ -2284,7 +2314,7 @@
 
 <histogram base="true"
     name="Apps.ScrollableShelf.Drag.PresentationTime.MaxLatency" units="ms"
-    expires_after="2021-11-08">
+    expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes
      name="TabletOrClamshellMode" and
      name="HomeLauncherVisibility" -->
@@ -2400,6 +2430,18 @@
   <token key="AppType" variants="AppType"/>
 </histogram>
 
+<histogram name="Apps.WindowCount.{RestoreAction}" units="unit"
+    expires_after="2021-12-30">
+  <owner>nancylingwang@chromium.org</owner>
+  <owner>sammiequon@chromium.org</owner>
+  <summary>
+    Records the number of the new created windows when {RestoreAction} in Chrome
+    OS. This is logged when {RestoreAction} on the full restore notfication
+    during the system startup phase.
+  </summary>
+  <token key="RestoreAction" variants="RestoreAction"/>
+</histogram>
+
 </histograms>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/histograms_xml/arc/histograms.xml b/tools/metrics/histograms/histograms_xml/arc/histograms.xml
index 85e3f2b..d18e161 100644
--- a/tools/metrics/histograms/histograms_xml/arc/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/arc/histograms.xml
@@ -58,7 +58,7 @@
 </histogram>
 
 <histogram name="Arc.AccessibilityWithTalkBack" enum="BooleanEnabled"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>hirokisato@chromium.org</owner>
   <owner>sarakato@chromium.org</owner>
   <summary>
@@ -146,7 +146,7 @@
 </histogram>
 
 <histogram name="Arc.AppInstalledReason" enum="InstallationCounterReasonEnum"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>robsc@chromium.org</owner>
   <owner>napper@chromium.org</owner>
   <summary>
@@ -1036,7 +1036,7 @@
 </histogram>
 
 <histogram name="Arc.Provisioning.TimeDelta.Failure" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="ArcUserTypes" -->
 
   <owner>alexchau@google.com</owner>
@@ -1047,7 +1047,7 @@
 </histogram>
 
 <histogram name="Arc.Provisioning.TimeDelta.Success" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="ArcUserTypes" -->
 
   <owner>alexchau@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/ash/histograms.xml b/tools/metrics/histograms/histograms_xml/ash/histograms.xml
index 9b87ad7..141ddb3 100644
--- a/tools/metrics/histograms/histograms_xml/ash/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/ash/histograms.xml
@@ -299,7 +299,7 @@
 </histogram>
 
 <histogram name="Ash.CaptureModeController.ConsecutiveScreenshots"
-    units="consecutive screenshots" expires_after="2021-11-10">
+    units="consecutive screenshots" expires_after="2022-01-09">
   <owner>chinsenj@chromium.org</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -343,7 +343,7 @@
 </histogram>
 
 <histogram name="Ash.CaptureModeController.ScreenRecordingLength"
-    units="seconds" expires_after="2021-11-04">
+    units="seconds" expires_after="2022-01-09">
   <owner>afakhry@chromium.org</owner>
   <owner>chinsenj@chromium.org</owner>
   <owner>gzadina@google.com</owner>
@@ -848,7 +848,7 @@
 </histogram>
 
 <histogram name="Ash.Desks.NumberOfDeskTraversals" units="units"
-    expires_after="2021-11-10">
+    expires_after="2022-01-09">
   <owner>afakhry@chromium.org</owner>
   <owner>sammiequon@chromium.org</owner>
   <owner>tclaiborne@chromium.org</owner>
@@ -2123,7 +2123,7 @@
 </histogram>
 
 <histogram name="Ash.Shelf.NavigationButtonsInTabletMode.ReasonShown"
-    enum="ReasonToShowShelfNavigationButtons" expires_after="2021-11-07">
+    enum="ReasonToShowShelfNavigationButtons" expires_after="2022-01-09">
   <owner>tbarzic@chromium.org</owner>
   <owner>gzadina@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/assistant/histograms.xml b/tools/metrics/histograms/histograms_xml/assistant/histograms.xml
index ef7bb2e..3e86204 100644
--- a/tools/metrics/histograms/histograms_xml/assistant/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/assistant/histograms.xml
@@ -342,7 +342,7 @@
 </histogram>
 
 <histogram name="QuickAnswers.ContextMenu.Close" enum="BooleanClicked"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>updowndota@google.com</owner>
   <owner>croissant-eng@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/autofill/histograms.xml b/tools/metrics/histograms/histograms_xml/autofill/histograms.xml
index 077780de..8ca6e8f 100644
--- a/tools/metrics/histograms/histograms_xml/autofill/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/autofill/histograms.xml
@@ -147,7 +147,7 @@
 
 <histogram name="Autofill.AddressProfileImportCountrySpecificFieldRequirements"
     enum="AutofillAddressProfileImportCountrySpecificFieldRequirement"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>koerber@google.com</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -158,7 +158,7 @@
 </histogram>
 
 <histogram name="Autofill.AddressProfileImportRequirements"
-    enum="AutofillAddressProfileImportRequirement" expires_after="2021-11-07">
+    enum="AutofillAddressProfileImportRequirement" expires_after="2022-01-09">
   <owner>koerber@google.com</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -168,7 +168,7 @@
 </histogram>
 
 <histogram name="Autofill.AddressProfileImportStatus"
-    enum="AutofillAddressProfileImportStatus" expires_after="2021-11-07">
+    enum="AutofillAddressProfileImportStatus" expires_after="2022-01-09">
   <owner>koerber@google.com</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -210,7 +210,7 @@
 
 <histogram
     name="Autofill.Autocomplete.NotOff.EditedAutofilledFieldAtSubmission"
-    enum="AutofilledFieldUserEditingStatus" expires_after="2021-11-07">
+    enum="AutofilledFieldUserEditingStatus" expires_after="2022-01-09">
   <owner>schwering@google.com</owner>
   <owner>chrome-autofill-alerts@google.com</owner>
   <summary>
@@ -220,7 +220,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.Autocomplete.NotOff.FillingAcceptance"
-    enum="BooleanAutofillFillingAcceptance" expires_after="2021-11-07">
+    enum="BooleanAutofillFillingAcceptance" expires_after="2022-01-09">
   <owner>schwering@google.com</owner>
   <owner>chrome-autofill-alerts@google.com</owner>
   <summary>
@@ -233,7 +233,7 @@
 </histogram>
 
 <histogram name="Autofill.Autocomplete.Off.EditedAutofilledFieldAtSubmission"
-    enum="AutofilledFieldUserEditingStatus" expires_after="2021-11-07">
+    enum="AutofilledFieldUserEditingStatus" expires_after="2022-01-09">
   <owner>schwering@google.com</owner>
   <owner>chrome-autofill-alerts@google.com</owner>
   <summary>
@@ -243,7 +243,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.Autocomplete.Off.FillingAcceptance"
-    enum="BooleanAutofillFillingAcceptance" expires_after="2021-11-07">
+    enum="BooleanAutofillFillingAcceptance" expires_after="2022-01-09">
   <owner>schwering@google.com</owner>
   <owner>chrome-autofill-alerts@google.com</owner>
   <summary>
@@ -680,7 +680,7 @@
 </histogram>
 
 <histogram name="Autofill.EditedAutofilledFieldAtSubmission.Aggregate"
-    enum="AutofilledFieldUserEditingStatus" expires_after="2021-11-07">
+    enum="AutofilledFieldUserEditingStatus" expires_after="2022-01-09">
   <owner>koerber@google.com</owner>
   <owner>battre@google.com</owner>
   <summary>
@@ -691,7 +691,7 @@
 
 <histogram name="Autofill.EditedAutofilledFieldAtSubmission.ByFieldType"
     enum="AutofilledFieldUserEditingStatusByFieldType"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>koerber@google.com</owner>
   <owner>battre@google.com</owner>
   <summary>
@@ -964,7 +964,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.Funnel.FillAfterSuggestion"
-    enum="BooleanAutofillFillAfterSuggestion" expires_after="2021-11-07">
+    enum="BooleanAutofillFillAfterSuggestion" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -982,7 +982,7 @@
 
 <histogram base="true" name="Autofill.Funnel.InteractionAfterParsedAsType"
     enum="BooleanAutofillInteractionAfterParsedAsType"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1003,7 +1003,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.Funnel.ParsedAsType"
-    enum="BooleanAutofillParsedAsType" expires_after="2021-11-07">
+    enum="BooleanAutofillParsedAsType" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1018,7 +1018,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.Funnel.SubmissionAfterFill"
-    enum="BooleanAutofillSubmissionAfterFill" expires_after="2021-11-07">
+    enum="BooleanAutofillSubmissionAfterFill" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1031,7 +1031,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.Funnel.SuggestionAfterInteraction"
-    enum="BooleanAutofillSuggestionAfterInteraction" expires_after="2021-11-07">
+    enum="BooleanAutofillSuggestionAfterInteraction" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1131,7 +1131,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.KeyMetrics.FillingAcceptance"
-    enum="BooleanAutofillFillingAcceptance" expires_after="2021-11-07">
+    enum="BooleanAutofillFillingAcceptance" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1144,7 +1144,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.KeyMetrics.FillingAssistance"
-    enum="BooleanAutofillFillingAssistance" expires_after="2021-11-07">
+    enum="BooleanAutofillFillingAssistance" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1160,7 +1160,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.KeyMetrics.FillingCorrectness"
-    enum="BooleanAutofillFillingCorrectness" expires_after="2021-11-07">
+    enum="BooleanAutofillFillingCorrectness" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1171,7 +1171,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.KeyMetrics.FillingReadiness"
-    enum="BooleanAutofillFillingReadiness" expires_after="2021-11-07">
+    enum="BooleanAutofillFillingReadiness" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1186,7 +1186,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.KeyMetrics.FormSubmission.Autofilled"
-    enum="BooleanAutofillSubmission" expires_after="2021-11-07">
+    enum="BooleanAutofillSubmission" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1202,7 +1202,7 @@
 </histogram>
 
 <histogram base="true" name="Autofill.KeyMetrics.FormSubmission.NotAutofilled"
-    enum="BooleanAutofillSubmission" expires_after="2021-11-07">
+    enum="BooleanAutofillSubmission" expires_after="2022-01-09">
   <owner>battre@chromium.org</owner>
   <owner>kolos@chromium.org</owner>
   <owner>nepper@chromium.org</owner>
@@ -1795,7 +1795,7 @@
 </histogram>
 
 <histogram name="Autofill.SaveCreditCardPromptOffer"
-    enum="AutofillSaveCreditCardPromptOfferEnum" expires_after="2021-11-07">
+    enum="AutofillSaveCreditCardPromptOfferEnum" expires_after="2022-01-09">
   <owner>jsaul@google.com</owner>
   <owner>siyua@chromium.org</owner>
   <summary>
@@ -1806,7 +1806,7 @@
 </histogram>
 
 <histogram name="Autofill.SaveCreditCardPromptResult"
-    enum="AutofillSaveCreditCardPromptResultEnum" expires_after="2021-11-07">
+    enum="AutofillSaveCreditCardPromptResultEnum" expires_after="2022-01-09">
   <owner>jsaul@google.com</owner>
   <owner>siyua@chromium.org</owner>
   <summary>
@@ -2492,7 +2492,7 @@
 </histogram>
 
 <histogram name="Autofill.WebOTP.OneTimeCode.FromAutocomplete" units="Boolean"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>yigu@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <owner>web-identity@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
index 5d74f084..e02ce51eb 100644
--- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
@@ -125,7 +125,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.Canvas.DrawImage.Duration"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
   <owner>fserb@chromium.org</owner>
   <owner>aaronhk@chromium.org</owner>
   <summary>
@@ -604,7 +604,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.CompositingAssignments.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -623,7 +623,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.CompositingCommit.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -646,7 +646,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.CompositingInputs.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -689,7 +689,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.ContentDocumentUpdate.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -709,7 +709,7 @@
 </histogram>
 
 <histogram name="Blink.ContextMenu.ImageSelection.Depth" units="count"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>benwgold@google.com</owner>
   <owner>flackr@chromium.org</owner>
   <summary>
@@ -722,7 +722,7 @@
 </histogram>
 
 <histogram name="Blink.ContextMenu.ImageSelection.ElapsedTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
   <owner>benwgold@google.com</owner>
   <owner>flackr@chromium.org</owner>
   <summary>
@@ -841,7 +841,7 @@
 </histogram>
 
 <histogram name="Blink.DecodedImage.WebPFileFormat" enum="WebPFileFormat"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mcasas@chromium.org</owner>
   <owner>andrescj@chromium.org</owner>
   <summary>
@@ -1150,7 +1150,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.HandleInputEvents.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -1168,7 +1168,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.HitTestDocumentUpdate.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -1564,7 +1564,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.ImplCompositorCommit.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -1618,7 +1618,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.JavascriptDocumentUpdate.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -1730,7 +1730,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.Layout.UpdateTime" units="microseconds"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -2444,7 +2444,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.ScrollDocumentUpdate.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -2491,7 +2491,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.ServiceDocumentUpdate.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -2992,7 +2992,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.UserDrivenDocumentUpdate.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -3032,7 +3032,7 @@
 </histogram>
 
 <histogram name="Blink.VisibleBeforeLoaded.LazyLoadImages.BelowTheFold"
-    enum="NQEEffectiveConnectionType" expires_after="2021-11-07">
+    enum="NQEEffectiveConnectionType" expires_after="2022-01-09">
   <owner>sclittle@chromium.org</owner>
   <owner>rajendrant@chromium.org</owner>
   <summary>
@@ -3086,7 +3086,7 @@
 </histogram>
 
 <histogram base="true" name="Blink.WaitForCommit.UpdateTime"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" -->
 
 <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" -->
@@ -3501,7 +3501,7 @@
 </histogram>
 
 <histogram name="BlinkGC.TimeForSweepingForeground" units="ms"
-    expires_after="M95">
+    expires_after="2022-01-09">
   <owner>bikineev@chromium.org</owner>
   <owner>oilpan-reviews@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/borealis/histograms.xml b/tools/metrics/histograms/histograms_xml/borealis/histograms.xml
index 5c8212a..36268ec 100644
--- a/tools/metrics/histograms/histograms_xml/borealis/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/borealis/histograms.xml
@@ -159,7 +159,7 @@
 </histogram>
 
 <histogram name="Borealis.Install.NumAttempts" enum="BooleanAttempted"
-    expires_after="2021-11-01">
+    expires_after="2022-01-09">
   <owner>danielng@google.com</owner>
   <owner>src/chrome/browser/ash/borealis/OWNERS</owner>
   <summary>
@@ -172,7 +172,7 @@
 </histogram>
 
 <histogram name="Borealis.Install.OverallTime" units="ms"
-    expires_after="2021-11-01">
+    expires_after="2022-01-09">
   <owner>danielng@google.com</owner>
   <owner>src/chrome/browser/ash/borealis/OWNERS</owner>
   <summary>
@@ -185,7 +185,7 @@
 </histogram>
 
 <histogram name="Borealis.Install.Result" enum="BorealisInstallResult"
-    expires_after="2021-11-01">
+    expires_after="2022-01-09">
   <owner>danielng@google.com</owner>
   <owner>src/chrome/browser/ash/borealis/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/browser/histograms.xml b/tools/metrics/histograms/histograms_xml/browser/histograms.xml
index 29c036d..80b6391f 100644
--- a/tools/metrics/histograms/histograms_xml/browser/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/browser/histograms.xml
@@ -302,7 +302,7 @@
 </histogram>
 
 <histogram name="Browser.PaintPreview.TabbedPlayer.FirstPaintBeforeTabLoad"
-    units="Boolean" expires_after="2021-11-07">
+    units="Boolean" expires_after="2022-01-09">
   <owner>ckitagawa@chromium.org</owner>
   <owner>mahmoudi@chromium.org</owner>
   <owner>fredmello@chromium.org</owner>
@@ -441,7 +441,7 @@
 </histogram>
 
 <histogram name="Browser.Responsiveness.JankyIntervalsPerThirtySeconds2"
-    units="janks" expires_after="2021-11-07">
+    units="janks" expires_after="2022-01-09">
 <!-- JankyIntervalsPerThirtySeconds3 is on probation to replace this -->
 
   <owner>erikchen@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/compositing/histograms.xml b/tools/metrics/histograms/histograms_xml/compositing/histograms.xml
index 527673f..794d7ec0 100644
--- a/tools/metrics/histograms/histograms_xml/compositing/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/compositing/histograms.xml
@@ -600,7 +600,7 @@
 </histogram>
 
 <histogram base="true" name="Compositing.ResourcePoolMemoryUsage" units="MB"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>sunnyps@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -610,7 +610,7 @@
 </histogram>
 
 <histogram name="Compositing.SurfaceAggregator.AggregateUs"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
   <owner>weiliangc@chromium.org</owner>
   <summary>
     Time spent aggregating compositor frames from different surfaces in
diff --git a/tools/metrics/histograms/histograms_xml/content/histograms.xml b/tools/metrics/histograms/histograms_xml/content/histograms.xml
index d847665b..5409a61 100644
--- a/tools/metrics/histograms/histograms_xml/content/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/content/histograms.xml
@@ -1385,7 +1385,7 @@
 </histogram>
 
 <histogram name="ContentSuggestions.Feed.VisitDuration" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>harringtond@chromium.org</owner>
   <owner>freedjm@chromium.org</owner>
   <owner>feed@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/cookie/histograms.xml b/tools/metrics/histograms/histograms_xml/cookie/histograms.xml
index ffee23b..0453da4 100644
--- a/tools/metrics/histograms/histograms_xml/cookie/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/cookie/histograms.xml
@@ -349,7 +349,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.OmniboxURLNavigation.Localhost"
-    enum="InterestingCookiePorts" expires_after="2021-11-04">
+    enum="InterestingCookiePorts" expires_after="2022-01-09">
   <owner>bingler@chromium.org</owner>
   <owner>chlily@chromium.org</owner>
   <summary>
@@ -370,7 +370,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.OmniboxURLNavigation.RemoteHost"
-    enum="InterestingCookiePorts" expires_after="2021-11-04">
+    enum="InterestingCookiePorts" expires_after="2022-01-09">
   <owner>bingler@chromium.org</owner>
   <owner>chlily@chromium.org</owner>
   <summary>
@@ -806,7 +806,7 @@
 </histogram>
 
 <histogram name="Cookie.TimeDatabaseMigrationToV14" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>wfh@chromium.org</owner>
   <owner>chlily@chromium.org</owner>
   <owner>morlovich@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/crostini/histograms.xml b/tools/metrics/histograms/histograms_xml/crostini/histograms.xml
index e29bfbf..6408a3f2 100644
--- a/tools/metrics/histograms/histograms_xml/crostini/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/crostini/histograms.xml
@@ -351,13 +351,30 @@
 
 <histogram name="Crostini.RestarterTimeInState.{state}" units="ms"
     expires_after="2022-01-06">
+  <obsolete>
+    Removed in M93, and had misleading data before M93. Do not use.
+  </obsolete>
+  <owner>clumptini@google.com</owner>
+  <owner>tbuckley@chromium.org</owner>
+  <summary>
+    Was intended to be time spent in each state in the restarter flow, but there
+    were some issues with how the metric was emitted. Use
+    Crostini.RestarterTimeInState2.* instead.
+  </summary>
+  <token key="state" variants="CrostiniState"/>
+</histogram>
+
+<histogram name="Crostini.RestarterTimeInState2.{state}" units="ms"
+    expires_after="2022-01-06">
   <owner>clumptini@google.com</owner>
   <owner>tbuckley@chromium.org</owner>
   <summary>
     Base histogram for measuring how much time the restarter flow spends in the
-    {state} state. Used to set timeouts. Note that this since this is for any
-    restarter run (no-op relaunch, installation, etc) the results are expected
-    to be multi-modal.
+    {state} state, used to set timeouts. Note that this since this is for any
+    restarter run (no-op relaunch, installation, success/failed) the results are
+    expected to be multi-modal. This is emitted by CrostiniRestarter every time
+    a state completes or restart completes, but not for a state that's been
+    aborted.
   </summary>
   <token key="state" variants="CrostiniState"/>
 </histogram>
diff --git a/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml b/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
index 980919da..4dfe79e 100644
--- a/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/cryptohome/histograms.xml
@@ -258,7 +258,7 @@
 </histogram>
 
 <histogram name="Cryptohome.GCache.FreedDiskSpaceInMb" units="MB"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>slangley@chromium.org</owner>
   <owner>weifangsun@chromium.org</owner>
   <summary>
@@ -288,7 +288,7 @@
 </histogram>
 
 <histogram base="true" name="Cryptohome.LECredential"
-    enum="CryptohomeLECredError" expires_after="2021-11-07">
+    enum="CryptohomeLECredError" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="LECredentialOps" -->
 
   <owner>pmalani@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml b/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml
index 1700f65..1a2ed17 100644
--- a/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/custom_tabs/histograms.xml
@@ -323,7 +323,7 @@
 </histogram>
 
 <histogram name="CustomTabs.WarmupStateOnLaunch" enum="WarmupStateOnLaunch"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>lizeb@chromium.org</owner>
   <summary>
     Recorded only on Android. Reports whether warmup() has been called when a
diff --git a/tools/metrics/histograms/histograms_xml/download/histograms.xml b/tools/metrics/histograms/histograms_xml/download/histograms.xml
index 379c384..96e1517 100644
--- a/tools/metrics/histograms/histograms_xml/download/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/download/histograms.xml
@@ -168,7 +168,7 @@
 </histogram>
 
 <histogram name="Download.DownloadDangerPrompt"
-    enum="SBClientDownloadExtensions" expires_after="2021-11-07">
+    enum="SBClientDownloadExtensions" expires_after="2022-01-09">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -454,7 +454,7 @@
 </histogram>
 
 <histogram name="Download.Later.Events" enum="DownloadLaterEvent"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>xingliu@chromium.org</owner>
   <owner>clank-downloads@google.com</owner>
   <summary>
@@ -463,7 +463,7 @@
 </histogram>
 
 <histogram name="Download.Later.ScheduledDownloadSize" units="Mb"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>xingliu@chromium.org</owner>
   <owner>clank-downloads@google.com</owner>
   <summary>
@@ -473,7 +473,7 @@
 </histogram>
 
 <histogram base="true" name="Download.Later.UI.DialogChoice"
-    enum="DownloadLaterDialogChoice" expires_after="2021-11-07">
+    enum="DownloadLaterDialogChoice" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="DownloadDialogSource" -->
 
   <owner>xingliu@chromium.org</owner>
@@ -486,7 +486,7 @@
 </histogram>
 
 <histogram name="Download.Later.UI.Events" enum="DownloadLaterUiEvent"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>xingliu@chromium.org</owner>
   <owner>clank-downloads@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
index 4b60b67..9707f1d 100644
--- a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
@@ -107,7 +107,7 @@
 </histogram>
 
 <histogram base="true" name="Enterprise.AutoEnrollmentHashDanceSuccessTime"
-    units="ms" expires_after="2021-11-07">
+    units="ms" expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="EnterpriseAutoEnrollmentType". -->
 
   <owner>amraboelkher@google.com</owner>
@@ -154,7 +154,7 @@
 </histogram>
 
 <histogram base="true" name="Enterprise.AutoEnrollmentProtocolTime" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="EnterpriseAutoEnrollmentType". -->
 
   <owner>pmarko@chromium.org</owner>
@@ -1147,7 +1147,7 @@
 </histogram>
 
 <histogram name="Enterprise.FirstRun.AppRestrictionLoadTime" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>wenyufu@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
@@ -1158,7 +1158,7 @@
 </histogram>
 
 <histogram name="Enterprise.FirstRun.AppRestrictionLoadTime.Medium" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>skym@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <owner>wenyufu@chromium.org</owner>
@@ -1345,7 +1345,7 @@
 </histogram>
 
 <histogram name="Enterprise.Policies.IgnoredByPolicyGroup"
-    enum="EnterprisePolicies" expires_after="2021-11-01">
+    enum="EnterprisePolicies" expires_after="2022-01-09">
   <owner>ydago@chromium.org</owner>
   <owner>pastarmovj@chromium.org</owner>
   <summary>
@@ -1941,7 +1941,7 @@
 </histogram>
 
 <histogram name="Enterprise.VpdUpdateStatus" units="units"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>igorcov@chromium.org</owner>
   <owner>tnagel@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/extensions/histograms.xml b/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
index a15d2e3..075cedd 100644
--- a/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
@@ -1636,7 +1636,7 @@
 
 <histogram
     name="Extensions.ForceInstalledFailureWithCrxHeaderInvalidIsFromCache"
-    enum="BooleanCacheHit" expires_after="2021-11-07">
+    enum="BooleanCacheHit" expires_after="2022-01-09">
   <owner>swapnilgupta@google.com</owner>
   <owner>burunduk@chromium.org</owner>
   <owner>snijhara@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/fingerprint/histograms.xml b/tools/metrics/histograms/histograms_xml/fingerprint/histograms.xml
index 365e0c5..2c423510 100644
--- a/tools/metrics/histograms/histograms_xml/fingerprint/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/fingerprint/histograms.xml
@@ -211,7 +211,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Unlock.Result" enum="FingerprintUnlockResult"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>rsorokin@chromium.org</owner>
   <owner>tomhughes@chromium.org</owner>
   <owner>cros-oac@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/gpu/histograms.xml b/tools/metrics/histograms/histograms_xml/gpu/histograms.xml
index 82ec6ee..455e491 100644
--- a/tools/metrics/histograms/histograms_xml/gpu/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/gpu/histograms.xml
@@ -1090,7 +1090,7 @@
 </histogram>
 
 <histogram name="GPU.ProcessLifetimeEvents.SwiftShader"
-    enum="GPUProcessLifetimeEvent" expires_after="2021-11-07">
+    enum="GPUProcessLifetimeEvent" expires_after="2022-01-09">
   <owner>vmiura@chromium.org</owner>
   <summary>
     Recorded once for every GPU process launch and crash when GPU process is
@@ -1503,7 +1503,7 @@
 </histogram>
 
 <histogram name="GPU.WatchdogThread.Event" enum="GpuWatchdogThreadEvent"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>magchen@chromium.org</owner>
   <owner>zmo@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/login/histograms.xml b/tools/metrics/histograms/histograms_xml/login/histograms.xml
index eb50e78..8d8ef55f 100644
--- a/tools/metrics/histograms/histograms_xml/login/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/login/histograms.xml
@@ -282,7 +282,7 @@
 </histogram>
 
 <histogram name="Login.UsersActive28Days" units="users"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>alemate@chromium.org</owner>
   <owner>achuith@chromium.org</owner>
   <summary>
@@ -292,7 +292,7 @@
 </histogram>
 
 <histogram name="Login.UsersActiveDaily" units="users"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>alemate@chromium.org</owner>
   <owner>achuith@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/media/histograms.xml b/tools/metrics/histograms/histograms_xml/media/histograms.xml
index ad31447..4d93aebd 100644
--- a/tools/metrics/histograms/histograms_xml/media/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/media/histograms.xml
@@ -163,7 +163,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Capture.FramesProvided" units="frames"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
   <summary>
@@ -542,7 +542,7 @@
 </histogram>
 
 <histogram name="Media.Audio.InputStartupSuccessMac" enum="BooleanSuccess"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>henrika@chromium.org</owner>
   <owner>webrtc-audio@google.com</owner>
   <summary>
@@ -3166,7 +3166,7 @@
 </histogram>
 
 <histogram name="Media.Notification.Source" enum="MediaNotificationSource"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>beccahughes@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -3402,7 +3402,7 @@
 </histogram>
 
 <histogram name="Media.Remoting.SessionDuration" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>jophba@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Measures the duration of each remoting session.</summary>
@@ -3416,7 +3416,7 @@
 </histogram>
 
 <histogram name="Media.Remoting.SessionStopTrigger" enum="RemotingStopTrigger"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
 <!-- Name completed by histogram_suffixes name="RemotingSessionDuration" -->
 
   <owner>jophba@chromium.org</owner>
@@ -3477,7 +3477,7 @@
 </histogram>
 
 <histogram name="Media.Remoting.VideoCodec" enum="VideoCodec"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>jophba@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Video codec used while remoting content.</summary>
@@ -4257,7 +4257,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.Error" enum="VideoCaptureError"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mcasas@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
@@ -4271,7 +4271,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.FrameDrop"
-    enum="VideoCaptureFrameDropReason" expires_after="2021-11-07">
+    enum="VideoCaptureFrameDropReason" expires_after="2022-01-09">
   <owner>mcasas@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
@@ -4288,7 +4288,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.FrameRate" units="fps"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mcasas@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
@@ -5014,7 +5014,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Cast.Channel.Error"
-    enum="MediaRouterCastChannelError" expires_after="2021-11-07">
+    enum="MediaRouterCastChannelError" expires_after="2022-01-09">
   <owner>mfoltz@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
@@ -5035,7 +5035,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Cast.Discovery.ConnectedDevicesCount"
-    units="devices" expires_after="2021-11-07">
+    units="devices" expires_after="2022-01-09">
   <owner>mfoltz@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
@@ -5055,7 +5055,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Cast.Discovery.SinkSource"
-    enum="MediaRouterCastSinkSource" expires_after="2021-11-07">
+    enum="MediaRouterCastSinkSource" expires_after="2022-01-09">
   <owner>btolsch@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>The source of discovery for a newly-created Cast sink.</summary>
diff --git a/tools/metrics/histograms/histograms_xml/mobile/histograms.xml b/tools/metrics/histograms/histograms_xml/mobile/histograms.xml
index a1f4a367..63a1274a 100644
--- a/tools/metrics/histograms/histograms_xml/mobile/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/mobile/histograms.xml
@@ -1137,7 +1137,7 @@
 </histogram>
 
 <histogram name="MobileStartup.DailyLaunchCount" units="units"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>tedchoc@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
@@ -1186,7 +1186,7 @@
 </histogram>
 
 <histogram name="MobileStartup.IntentToCreationTime" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>tedchoc@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
@@ -1211,7 +1211,7 @@
 </histogram>
 
 <histogram name="MobileStartup.LaunchType" enum="LaunchType"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>tedchoc@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/navigation/histograms.xml b/tools/metrics/histograms/histograms_xml/navigation/histograms.xml
index 789bb4d9..1c8b99e 100644
--- a/tools/metrics/histograms/histograms_xml/navigation/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/navigation/histograms.xml
@@ -749,7 +749,7 @@
 </histogram>
 
 <histogram name="Navigation.EngagementTime.HTTPS" units="ms"
-    expires_after="2021-10-31">
+    expires_after="2022-01-09">
   <owner>estark@chromium.org</owner>
   <owner>security-enamel@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/net/histograms.xml b/tools/metrics/histograms/histograms_xml/net/histograms.xml
index 8a9b976..c6d306e 100644
--- a/tools/metrics/histograms/histograms_xml/net/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/net/histograms.xml
@@ -704,7 +704,7 @@
 </histogram>
 
 <histogram name="Net.DNS.DnsConfig.SecureDnsMode" enum="SecureDnsModeDetails"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>ericorth@chromium.org</owner>
   <owner>doh-core@google.com</owner>
   <summary>
@@ -1204,7 +1204,7 @@
 </histogram>
 
 <histogram name="Net.DNS.InsecureDnsTask.FailureTime" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>ericorth@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -1532,7 +1532,7 @@
 </histogram>
 
 <histogram name="Net.DNS.UpgradeConfig.HasPublicInsecureNameserver"
-    enum="Boolean" expires_after="2021-11-07">
+    enum="Boolean" expires_after="2022-01-09">
   <owner>ericorth@chromium.org</owner>
   <owner>doh-core@google.com</owner>
   <summary>
@@ -1564,7 +1564,7 @@
 </histogram>
 
 <histogram name="Net.DNS.UpgradeConfig.InsecureUpgradeSucceeded" enum="Boolean"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>ericorth@chromium.org</owner>
   <owner>doh-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/network/histograms.xml b/tools/metrics/histograms/histograms_xml/network/histograms.xml
index 47df295f..411f01bb 100644
--- a/tools/metrics/histograms/histograms_xml/network/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/network/histograms.xml
@@ -2976,7 +2976,7 @@
 
 <histogram
     name="NetworkService.URLLoader.RequestInitiatorOriginLockCompatibility"
-    enum="RequestInitiatorOriginLockCompatibility" expires_after="2021-11-07">
+    enum="RequestInitiatorOriginLockCompatibility" expires_after="2022-01-09">
   <owner>lukasza@chromium.org</owner>
   <owner>creis@chromium.org</owner>
   <owner>jam@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml b/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml
index 87dfb90f..56e7e3f 100644
--- a/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml
@@ -22,7 +22,7 @@
 <histograms>
 
 <histogram name="NewTabPage.ActionAndroid2" enum="NewTabPageActionAndroid2"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>twellington@chromium.org</owner>
   <owner>finkm@chromium.org</owner>
   <summary>
@@ -208,7 +208,7 @@
 </histogram>
 
 <histogram name="NewTabPage.ContentSuggestions.ArticlesListVisible"
-    enum="BooleanVisible" expires_after="2021-11-07">
+    enum="BooleanVisible" expires_after="2022-01-09">
   <owner>freedjm@chromium.org</owner>
   <owner>feed@chromium.org</owner>
   <summary>
@@ -556,7 +556,7 @@
 </histogram>
 
 <histogram name="NewTabPage.ContentSuggestions.ShownAge" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>freedjm@chromium.org</owner>
   <owner>feed@chromium.org</owner>
   <summary>
@@ -1035,7 +1035,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Modules.Impression" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>tiborg@chromium.org</owner>
   <owner>yyushkina@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -1079,7 +1079,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Modules.Loaded" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>tiborg@chromium.org</owner>
   <owner>yyushkina@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -1224,7 +1224,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Promo.EnhancedProtectionPromo"
-    enum="AndroidEnhancedProtectionPromoAction" expires_after="2021-11-07">
+    enum="AndroidEnhancedProtectionPromoAction" expires_after="2022-01-09">
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-core@google.com</owner>
   <summary>
@@ -1931,7 +1931,7 @@
   </summary>
 </histogram>
 
-<histogram name="NewTabPage.TimeSpent" units="ms" expires_after="2021-11-07">
+<histogram name="NewTabPage.TimeSpent" units="ms" expires_after="2022-01-09">
   <owner>freedjm@chromium.org</owner>
   <owner>feed@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
@@ -2004,7 +2004,7 @@
 </histogram>
 
 <histogram name="NewTabPage.UserClassifier.AverageHoursToUseSuggestions"
-    units="hours" expires_after="2021-11-07">
+    units="hours" expires_after="2022-01-09">
   <owner>freedjm@chromium.org</owner>
   <owner>feed@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml
index 7fcfddf..ef225de 100644
--- a/tools/metrics/histograms/histograms_xml/others/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -344,7 +344,7 @@
 </histogram>
 
 <histogram name="AddSupervisionDialog.Enrollment"
-    enum="AddSupervisionEnrollment" expires_after="2021-11-07">
+    enum="AddSupervisionEnrollment" expires_after="2022-01-09">
   <owner>tobyhuang@chromium.org</owner>
   <owner>michaelpg@chromium.org</owner>
   <owner>danan@chromium.org</owner>
@@ -3462,7 +3462,7 @@
 </histogram>
 
 <histogram base="true" name="ContextMenu.SelectedOptionDesktop"
-    enum="ContextMenuOptionDesktop" expires_after="2021-11-07">
+    enum="ContextMenuOptionDesktop" expires_after="2022-01-09">
   <owner>avi@chromium.org</owner>
   <owner>mpearson@chromium.org</owner>
   <summary>
@@ -3654,7 +3654,7 @@
 </histogram>
 
 <histogram name="Conversions.RegisteredConversionsPerPage" units="conversions"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>johnidel@chromium.org</owner>
   <owner>csharrison@chromium.org</owner>
   <summary>
@@ -6097,7 +6097,7 @@
 
 <histogram name="Feedback.HappinessTrackingSurvey.ShouldShowSurveyReason"
     enum="HappinessTrackingSurveyShouldShowSurveyReasons"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>sauski@google.com</owner>
   <owner>msramek@chromium.org</owner>
   <summary>
@@ -10182,7 +10182,7 @@
 </histogram>
 
 <histogram name="Mojo.Channel.WriteMessageLatency" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>amistry@chromium.org</owner>
   <owner>bgeffon@chromium.org</owner>
   <owner>rockot@google.com</owner>
@@ -10193,7 +10193,7 @@
 </histogram>
 
 <histogram name="Mojo.Channel.WriteMessageSize" units="bytes"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>amistry@chromium.org</owner>
   <owner>bgeffon@chromium.org</owner>
   <owner>rockot@google.com</owner>
@@ -10222,7 +10222,7 @@
 </histogram>
 
 <histogram name="Mojo.Channel.WritevBatchedMessages" units="messages"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>amistry@chromium.org</owner>
   <owner>bgeffon@chromium.org</owner>
   <owner>rockot@google.com</owner>
@@ -10977,7 +10977,7 @@
 </histogram>
 
 <histogram name="OSCrypt.BackendUsage" enum="LinuxPasswordStoreUsage"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>cfroussios@chromium.org</owner>
   <owner>mamir@chromium.org</owner>
   <summary>
@@ -13981,7 +13981,7 @@
 </histogram>
 
 <histogram name="SB2.RemoteCall.CheckDelta" units="microseconds"
-    expires_after="2021-11-08">
+    expires_after="2022-01-09">
   <owner>vakh@chromium.org</owner>
   <owner>csharrison@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
@@ -13999,7 +13999,7 @@
   </summary>
 </histogram>
 
-<histogram name="SB2.RemoteCall.Elapsed" units="ms" expires_after="2021-11-07">
+<histogram name="SB2.RemoteCall.Elapsed" units="ms" expires_after="2022-01-09">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -14233,7 +14233,7 @@
 </histogram>
 
 <histogram name="SBIRS.UploadResult" enum="ReportProcessingResult"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>caitkp@google.com</owner>
   <summary>
     The result of an attempted report upload by the safe browsing incident
@@ -14440,7 +14440,7 @@
 </histogram>
 
 <histogram name="Servicification.Startup2" enum="ServicificationStartupMode"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>hanxi@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <owner>hnakashima@chromium.org</owner>
@@ -14453,7 +14453,7 @@
 </histogram>
 
 <histogram name="Servicification.Startup3" enum="ServicificationStartupMode"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>hanxi@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <owner>hnakashima@chromium.org</owner>
@@ -15444,7 +15444,7 @@
 
 <histogram
     name="SiteIsolation.ReusePendingOrCommittedSite.TimeSinceReusableProcessDestroyed"
-    units="ms" expires_after="2021-11-07">
+    units="ms" expires_after="2022-01-09">
   <owner>jessemckenna@google.com</owner>
   <owner>olivierli@chromium.org</owner>
   <summary>
@@ -15571,7 +15571,7 @@
 </histogram>
 
 <histogram name="Skia.SubmitRenderPasses" units="renderpasses"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>egdaniel@google.com</owner>
   <owner>bsalomon@google.com</owner>
   <summary>
@@ -15584,7 +15584,7 @@
 </histogram>
 
 <histogram name="Skia.VulkanMemoryAllocator.AmountAllocated" units="KB"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>egdaniel@google.com</owner>
   <owner>bsalomon@google.com</owner>
   <summary>
@@ -16232,7 +16232,7 @@
 </histogram>
 
 <histogram name="SupervisedUsers.ExtensionInstallDialog"
-    enum="SupervisedUserExtensionInstallDialog" expires_after="2021-11-07">
+    enum="SupervisedUserExtensionInstallDialog" expires_after="2022-01-09">
   <owner>tobyhuang@chromium.org</owner>
   <owner>agawronska@chromium.org</owner>
   <owner>danan@chromium.org</owner>
@@ -16315,7 +16315,7 @@
 </histogram>
 
 <histogram name="SupervisedUsers.ParentPermissionDialog"
-    enum="SupervisedUserParentPermissionDialog" expires_after="2021-11-07">
+    enum="SupervisedUserParentPermissionDialog" expires_after="2022-01-09">
   <owner>tobyhuang@chromium.org</owner>
   <owner>agawronska@chromium.org</owner>
   <owner>danan@chromium.org</owner>
@@ -18214,7 +18214,7 @@
 </histogram>
 
 <histogram name="Viz.DisplayCompositor.OverlayNumProposedCandidates"
-    units="units" expires_after="2021-11-07">
+    units="units" expires_after="2022-01-09">
   <owner>petermcneeley@chromium.org</owner>
   <owner>dcastagna@chromium.org</owner>
   <summary>
@@ -18225,7 +18225,7 @@
 </histogram>
 
 <histogram name="Viz.DisplayCompositor.OverlayQuadMaterial"
-    enum="OverlayQuadMaterial" expires_after="2021-11-07">
+    enum="OverlayQuadMaterial" expires_after="2022-01-09">
   <owner>petermcneeley@chromium.org</owner>
   <owner>dcastagna@chromium.org</owner>
   <summary>
@@ -18235,7 +18235,7 @@
 </histogram>
 
 <histogram name="Viz.DisplayCompositor.OverlayStrategy"
-    enum="OverlayStrategies" expires_after="2021-11-07">
+    enum="OverlayStrategies" expires_after="2022-01-09">
   <owner>dcastagna@chromium.org</owner>
   <owner>hoegsberg@chromium.org</owner>
   <summary>
@@ -18245,7 +18245,7 @@
 </histogram>
 
 <histogram name="Viz.DisplayCompositor.OverlaySwitchInterval" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>petermcneeley@chromium.org</owner>
   <owner>dcastagna@chromium.org</owner>
   <summary>
@@ -19095,7 +19095,7 @@
 </histogram>
 
 <histogram name="Webapp.WebAppUrlLoaderPrepareForLoadResult"
-    enum="WebAppUrlLoaderResult" expires_after="2021-11-07">
+    enum="WebAppUrlLoaderResult" expires_after="2022-01-09">
   <owner>qjw@chromium.org</owner>
   <owner>ortuno@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
@@ -19279,7 +19279,7 @@
 </histogram>
 
 <histogram name="WebFont.HadBlankText" enum="BooleanHadBlankText"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>kenjibaheux@chromium.org</owner>
   <owner>ksakamoto@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/page/histograms.xml b/tools/metrics/histograms/histograms_xml/page/histograms.xml
index 0f39d60..0331bf41 100644
--- a/tools/metrics/histograms/histograms_xml/page/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/page/histograms.xml
@@ -348,7 +348,7 @@
 </histogram>
 
 <histogram name="PageLoad.Clients.Ads.Resources.Bytes.Ads2" units="KB"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>johnidel@chromium.org</owner>
   <owner>jkarlin@chromium.org</owner>
   <summary>
@@ -614,6 +614,94 @@
   </summary>
 </histogram>
 
+<histogram name="PageLoad.Clients.Prerender.InteractiveTiming.FirstInputDelay4"
+    units="ms" expires_after="2022-01-27">
+  <owner>ksakamoto@chromium.org</owner>
+  <owner>src/content/browser/prerender/OWNERS</owner>
+  <summary>
+    PageLoad.InteractiveTiming.FirstInputDelay4, but for page loads that were
+    prerendered and were later activated. Note that prerendered page loads are
+    excluded from PageLoad.InteractiveTiming.FirstInputDelay4.
+  </summary>
+</histogram>
+
+<histogram
+    name="PageLoad.Clients.Prerender.LayoutInstability.CumulativeShiftScore"
+    units="ms" expires_after="2022-01-27">
+  <owner>ksakamoto@chromium.org</owner>
+  <owner>src/content/browser/prerender/OWNERS</owner>
+  <summary>
+    PageLoad.LayoutInstability.CumulativeShiftScore, but for page loads that
+    were prerendered and were later activated. Note that prerendered page loads
+    are excluded from PageLoad.LayoutInstability.CumulativeShiftScore.
+  </summary>
+</histogram>
+
+<histogram
+    name="PageLoad.Clients.Prerender.LayoutInstability.CumulativeShiftScore.MainFrame"
+    units="ms" expires_after="2022-01-27">
+  <owner>ksakamoto@chromium.org</owner>
+  <owner>src/content/browser/prerender/OWNERS</owner>
+  <summary>
+    PageLoad.LayoutInstability.CumulativeShiftScore.MainFrame, but for page
+    loads that were prerendered and were later activated. Note that prerendered
+    page loads are excluded from
+    PageLoad.LayoutInstability.CumulativeShiftScore.MainFrame.
+  </summary>
+</histogram>
+
+<histogram name="PageLoad.Clients.Prerender.NavigationToActivation" units="ms"
+    expires_after="2022-01-27">
+  <owner>ksakamoto@chromium.org</owner>
+  <owner>src/content/browser/prerender/OWNERS</owner>
+  <summary>
+    Measures the time from the start of initial prerendering navigation to the
+    start of activation navigation. This corresponds to the activationStart
+    attribute of PerformanceNavigationTiming. Recorded when a prerendered page
+    is activated.
+  </summary>
+</histogram>
+
+<histogram
+    name="PageLoad.Clients.Prerender.PaintTiming.ActivationToFirstContentfulPaint"
+    units="ms" expires_after="2022-01-27">
+  <owner>ksakamoto@chromium.org</owner>
+  <owner>src/content/browser/prerender/OWNERS</owner>
+  <summary>
+    PageLoad.PaintTiming.NavigationToFirstContentfulPaint, but for page loads
+    that were prerendered and were later activated. This measures the time
+    relative to the activation navigation start. Note that prerendered page
+    loads are excluded from
+    PageLoad.PaintTiming.NavigationToFirstContentfulPaint.
+  </summary>
+</histogram>
+
+<histogram name="PageLoad.Clients.Prerender.PaintTiming.ActivationToFirstPaint"
+    units="ms" expires_after="2022-01-27">
+  <owner>ksakamoto@chromium.org</owner>
+  <owner>src/content/browser/prerender/OWNERS</owner>
+  <summary>
+    PageLoad.PaintTiming.NavigationToFirstPaint, but for page loads that were
+    prerendered and were later activated. This measures the time relative to the
+    activation navigation start. Note that prerendered page loads are excluded
+    from PageLoad.PaintTiming.NavigationToFirstPaint.
+  </summary>
+</histogram>
+
+<histogram
+    name="PageLoad.Clients.Prerender.PaintTiming.ActivationToLargestContentfulPaint2"
+    units="ms" expires_after="2022-01-27">
+  <owner>ksakamoto@chromium.org</owner>
+  <owner>src/content/browser/prerender/OWNERS</owner>
+  <summary>
+    PageLoad.PaintTiming.NavigationToLargestContentfulPaint2, but for page loads
+    that were prerendered and were later activated. This measures the time
+    relative to the activation navigation start. Note that prerendered page
+    loads are excluded from
+    PageLoad.PaintTiming.NavigationToLargestContentfulPaint2.
+  </summary>
+</histogram>
+
 <histogram name="PageLoad.Clients.Scheme.HTTP.PaintTiming.UnderStat"
     enum="PageLoadTimingUnderStat" expires_after="2021-11-28">
   <owner>tbansal@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/password/histograms.xml b/tools/metrics/histograms/histograms_xml/password/histograms.xml
index 2a147fbb..d01d7b4 100644
--- a/tools/metrics/histograms/histograms_xml/password/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/password/histograms.xml
@@ -852,7 +852,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AutomaticChange.ForSitesWithScripts"
-    enum="PasswordCheckResolutionAction" expires_after="2021-11-07">
+    enum="PasswordCheckResolutionAction" expires_after="2022-01-09">
   <owner>kolos@chromium.org</owner>
   <owner>battre@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/platform/histograms.xml b/tools/metrics/histograms/histograms_xml/platform/histograms.xml
index 9d383c7..54e07da 100644
--- a/tools/metrics/histograms/histograms_xml/platform/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/platform/histograms.xml
@@ -22,7 +22,7 @@
 <histograms>
 
 <histogram name="Platform.AnyCrashesDaily" units="count per day"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>grundler@chromium.org</owner>
   <owner>groeck@chromium.org</owner>
   <owner>sonnyrao@chromium.org</owner>
@@ -34,7 +34,7 @@
 </histogram>
 
 <histogram name="Platform.AnyCrashesWeekly" units="count per week"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>grundler@chromium.org</owner>
   <owner>groeck@chromium.org</owner>
   <owner>sonnyrao@chromium.org</owner>
@@ -484,7 +484,7 @@
 </histogram>
 
 <histogram name="Platform.KernelCrashesDaily" units="count per day"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>grundler@chromium.org</owner>
   <owner>groeck@chromium.org</owner>
   <owner>sonnyrao@chromium.org</owner>
@@ -495,7 +495,7 @@
 </histogram>
 
 <histogram name="Platform.KernelCrashesPerActiveYear" units="count per year"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>grundler@chromium.org</owner>
   <owner>groeck@chromium.org</owner>
   <owner>sonnyrao@chromium.org</owner>
@@ -528,7 +528,7 @@
 </histogram>
 
 <histogram name="Platform.KernelCrashesWeekly" units="count per week"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>grundler@chromium.org</owner>
   <owner>groeck@chromium.org</owner>
   <owner>sonnyrao@chromium.org</owner>
@@ -540,7 +540,7 @@
 </histogram>
 
 <histogram name="Platform.KernelCrashInterval" units="seconds"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>grundler@chromium.org</owner>
   <owner>groeck@chromium.org</owner>
   <owner>sonnyrao@chromium.org</owner>
@@ -561,7 +561,7 @@
 </histogram>
 
 <histogram name="Platform.LogicalCpuCount" units="units"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>sonnyrao@chromium.org</owner>
   <owner>chromeos-performance@google.com</owner>
   <summary>
@@ -964,7 +964,7 @@
 </histogram>
 
 <histogram name="Platform.SwapInLong" units="pages/second"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>sonnyrao@chromium.org</owner>
   <owner>chromeos-memory@google.com</owner>
   <summary>
@@ -989,7 +989,7 @@
 </histogram>
 
 <histogram name="Platform.SwapOutLong" units="pages/second"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>sonnyrao@chromium.org</owner>
   <owner>chromeos-memory@google.com</owner>
   <summary>
@@ -998,7 +998,7 @@
 </histogram>
 
 <histogram name="Platform.SwapOutShort" units="pages/second"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>sonnyrao@chromium.org</owner>
   <owner>chromeos-memory@google.com</owner>
   <summary>
@@ -1124,7 +1124,7 @@
 </histogram>
 
 <histogram name="Platform.Thermal.Temperature.Cpu.0" units="Celsius"
-    expires_after="2021-10-31">
+    expires_after="2022-01-09">
   <owner>julanhsu@google.com</owner>
   <owner>caiz@google.com</owner>
   <summary>
@@ -1274,7 +1274,7 @@
 </histogram>
 
 <histogram name="Platform.TPM.VersionFingerprint" enum="TPMVersionFingerprint"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mnissler@chromium.org</owner>
   <owner>cros-hwsec+uma@chromium.org</owner>
   <summary>
@@ -1468,7 +1468,7 @@
 </histogram>
 
 <histogram name="Platform.ZramCompressionRatioPercent" units="%"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>sonnyrao@chromium.org</owner>
   <owner>chromeos-memory@google.com</owner>
   <summary>
@@ -1566,7 +1566,7 @@
 </histogram>
 
 <histogram name="PlatformThread.Mac.AttemptedRealtimePeriod"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
   <owner>olka@chromium.org</owner>
   <owner>handellm@chromium.org</owner>
   <summary>
@@ -1576,7 +1576,7 @@
 </histogram>
 
 <histogram name="PlatformThread.Mac.SucceededRealtimePeriod"
-    units="microseconds" expires_after="2021-11-07">
+    units="microseconds" expires_after="2022-01-09">
   <owner>olka@chromium.org</owner>
   <owner>handellm@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/profile/histograms.xml b/tools/metrics/histograms/histograms_xml/profile/histograms.xml
index abc1febd..9a7b345 100644
--- a/tools/metrics/histograms/histograms_xml/profile/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/profile/histograms.xml
@@ -84,7 +84,7 @@
 </histogram>
 
 <histogram name="Profile.Avatar" enum="ProfileAvatar"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>jkrcal@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <summary>The frequency of selection of each avatar.</summary>
@@ -171,7 +171,7 @@
 </histogram>
 
 <histogram name="Profile.DeleteProfileAction" enum="ProfileDeleteAction"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>msarda@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <owner>anthonyvd@chromium.org</owner>
@@ -475,7 +475,7 @@
 </histogram>
 
 <histogram name="Profile.NumberOfProfilesAtProfileSwitch" units="profiles"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>jkrcal@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
index 1c7ac5d..30888315 100644
--- a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
@@ -113,7 +113,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.AndroidTelemetry.ApkDownload.Outcome"
-    enum="ApkDownloadTelemetryOutcome" expires_after="2021-11-07">
+    enum="ApkDownloadTelemetryOutcome" expires_after="2022-01-09">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -978,7 +978,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.Pref.Daily.Extended" enum="BooleanEnabled"
-    expires_after="2021-11-04">
+    expires_after="2022-01-09">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -1488,7 +1488,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.Triggers.SuspiciousSite.Event"
-    enum="SuspiciousSiteTriggerEvent" expires_after="2021-11-07">
+    enum="SuspiciousSiteTriggerEvent" expires_after="2022-01-09">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -1720,7 +1720,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.V4ProcessPartialUpdate.AdditionsHashesCount"
-    units="entries" expires_after="2021-11-07">
+    units="entries" expires_after="2022-01-09">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/settings/histograms.xml b/tools/metrics/histograms/histograms_xml/settings/histograms.xml
index 312c9b7f..478c572 100644
--- a/tools/metrics/histograms/histograms_xml/settings/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/settings/histograms.xml
@@ -40,7 +40,7 @@
 </histogram>
 
 <histogram name="Settings.GivenShowHomeButton_HomePageIsNewTabPage"
-    enum="Boolean" expires_after="2021-11-07">
+    enum="Boolean" expires_after="2022-01-09">
   <owner>mpearson@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
@@ -297,7 +297,7 @@
 </histogram>
 
 <histogram name="Settings.ShowHomeButton" enum="BooleanEnabled"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mpearson@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/signin/histograms.xml b/tools/metrics/histograms/histograms_xml/signin/histograms.xml
index e4401cb..9dac3f02 100644
--- a/tools/metrics/histograms/histograms_xml/signin/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/signin/histograms.xml
@@ -205,7 +205,7 @@
 </histogram>
 
 <histogram name="Signin.AccountTracker.GaiaIdMigrationState"
-    enum="OAuth2LoginAccountRevokedMigrationState" expires_after="2021-11-07">
+    enum="OAuth2LoginAccountRevokedMigrationState" expires_after="2022-01-09">
   <owner>msarda@chromium.org</owner>
   <owner>sdefresne@chromium.org</owner>
   <summary>
@@ -370,7 +370,7 @@
 </histogram>
 
 <histogram base="true" name="Signin.CookieJar.SignedInCountWithPrimary"
-    units="accounts" expires_after="2021-11-07">
+    units="accounts" expires_after="2022-01-09">
   <owner>jkrcal@chromium.org</owner>
   <owner>droger@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/startup/histograms.xml b/tools/metrics/histograms/histograms_xml/startup/histograms.xml
index f9788cba..8bb190fc 100644
--- a/tools/metrics/histograms/histograms_xml/startup/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/startup/histograms.xml
@@ -22,7 +22,7 @@
 <histograms>
 
 <histogram name="Startup.AfterStartupTaskCount" units="units"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>michaeln@chromium.org</owner>
   <summary>
     The number of after-startup tasks that were queued prior to startup
@@ -636,7 +636,7 @@
 </histogram>
 
 <histogram name="Startup.MobileSessionStartAction"
-    enum="MobileSessionStartAction" expires_after="2021-11-07">
+    enum="MobileSessionStartAction" expires_after="2022-01-09">
   <owner>thegreenfrog@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -646,7 +646,7 @@
 </histogram>
 
 <histogram name="Startup.MobileSessionStartFromApps"
-    enum="MobileSessionCallerApp" expires_after="2021-11-07">
+    enum="MobileSessionCallerApp" expires_after="2022-01-09">
   <owner>thegreenfrog@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>The calling application (if any).</summary>
diff --git a/tools/metrics/histograms/histograms_xml/sync/histograms.xml b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
index 74526d71..6a54e156 100644
--- a/tools/metrics/histograms/histograms_xml/sync/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
@@ -770,7 +770,7 @@
 </histogram>
 
 <histogram base="true" name="Sync.ModelTypeMemoryKB" units="KB"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mastiz@chromium.org</owner>
   <owner>jkrcal@chromium.org</owner>
   <component>Services&gt;Sync</component>
@@ -1071,7 +1071,7 @@
 </histogram>
 
 <histogram name="Sync.PostedClientToServerMessageLatency" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mastiz@chromium.org</owner>
   <component>Services&gt;Sync</component>
   <summary>
@@ -1109,7 +1109,7 @@
 </histogram>
 
 <histogram name="Sync.PostedGetUpdatesOrigin" enum="SyncGetUpdatesOrigin"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mastiz@chromium.org</owner>
   <owner>jkrcal@chromium.org</owner>
   <component>Services&gt;Sync</component>
@@ -1414,7 +1414,7 @@
 </histogram>
 
 <histogram name="Sync.TrustedVaultKeyRetrievalTrigger"
-    enum="TrustedVaultKeyRetrievalTrigger" expires_after="2021-11-01">
+    enum="TrustedVaultUserActionTrigger" expires_after="2021-11-01">
   <owner>mmoskvitin@google.com</owner>
   <owner>mastiz@chromium.org</owner>
   <component>Services&gt;Sync</component>
diff --git a/tools/metrics/histograms/histograms_xml/tab/histograms.xml b/tools/metrics/histograms/histograms_xml/tab/histograms.xml
index f0e3393..a9dc34f3 100644
--- a/tools/metrics/histograms/histograms_xml/tab/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/tab/histograms.xml
@@ -465,7 +465,7 @@
 </histogram>
 
 <histogram name="Tab.StateAtRendererTermination" enum="TabForegroundState"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>gambard@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/translate/histograms.xml b/tools/metrics/histograms/histograms_xml/translate/histograms.xml
index fd4a244..a5a306d 100644
--- a/tools/metrics/histograms/histograms_xml/translate/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/translate/histograms.xml
@@ -82,7 +82,7 @@
 </histogram>
 
 <histogram name="Translate.CLD3.TopLanguageEvaluationDuration" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>mcrouse@chromium.org</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
@@ -426,7 +426,7 @@
 </histogram>
 
 <histogram name="Translate.MenuTranslation.UnavailableReasons"
-    enum="MenuTranslationUnavailableReason" expires_after="2021-11-07">
+    enum="MenuTranslationUnavailableReason" expires_after="2022-01-09">
   <owner>cuianthony@google.com</owner>
   <owner>chrome-language@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/ukm/histograms.xml b/tools/metrics/histograms/histograms_xml/ukm/histograms.xml
index 7617223..1ae0e902 100644
--- a/tools/metrics/histograms/histograms_xml/ukm/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/ukm/histograms.xml
@@ -92,7 +92,7 @@
 </histogram>
 
 <histogram name="UKM.Entries.Recorded.ByEntryHash" enum="UkmEventNameHash"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>yrsun@chromium.org</owner>
   <owner>ukm-team@google.com</owner>
   <summary>
@@ -225,7 +225,7 @@
 </histogram>
 
 <histogram name="UKM.ResetReason" enum="UkmResetReason"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>rkaplow@chromium.org</owner>
   <owner>ukm-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/uma/histograms.xml b/tools/metrics/histograms/histograms_xml/uma/histograms.xml
index d807633..a948d4b 100644
--- a/tools/metrics/histograms/histograms_xml/uma/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/uma/histograms.xml
@@ -693,7 +693,7 @@
 </histogram>
 
 <histogram name="UMA.UserDemographics.IsNoisedAgeOver21Under85"
-    enum="BooleanNoisedAgeOver21Under85" expires_after="2021-11-04">
+    enum="BooleanNoisedAgeOver21Under85" expires_after="2022-01-09">
   <owner>tobyhuang@chromium.org</owner>
   <owner>cros-families-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/v8/histograms.xml b/tools/metrics/histograms/histograms_xml/v8/histograms.xml
index 7226011..07bffa1 100644
--- a/tools/metrics/histograms/histograms_xml/v8/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/v8/histograms.xml
@@ -125,7 +125,7 @@
 </histogram>
 
 <histogram name="V8.CompileMicroSeconds" units="microseconds"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>yangguo@chromium.org</owner>
   <summary>
     Time spent in V8 compiler (full codegen) excluding parser.
@@ -1338,7 +1338,7 @@
 </histogram>
 
 <histogram name="V8.WasmCompileModuleAsyncMicroSeconds" units="microseconds"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>ecmziegler@chromium.org</owner>
   <owner>adamk@chromium.org</owner>
   <owner>clemensb@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
index 2abbb611..c774989 100644
--- a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
@@ -774,7 +774,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Encoder.CodecType" enum="WebRtcAudioCodecs"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>aleloi@chromium.org</owner>
   <summary>
     Histogram of audio codec usage. Every sample corresponds to 5 seconds of
@@ -852,7 +852,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.TargetBitrateInKbps" units="kbps"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>hlundin@chromium.org</owner>
   <summary>
     The target bitrate in kbps that the audio codec should try to produce on
@@ -892,7 +892,7 @@
 </histogram>
 
 <histogram name="WebRTC.AudioOutputSampleRate" enum="AudioSampleRate"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>henrika@chromium.org</owner>
   <owner>webrtc-audio@google.com</owner>
   <summary>Audio output sample rate for WebRTC (in Hz).</summary>
@@ -908,7 +908,7 @@
 </histogram>
 
 <histogram name="WebRTC.BWE.InitialBandwidthEstimate" units="kbps"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>holmer@chromium.org</owner>
   <summary>The bandwidth estimate 2 seconds into a WebRTC call.</summary>
 </histogram>
@@ -1521,7 +1521,7 @@
 </histogram>
 
 <histogram name="WebRTC.PeerConnection.KeyProtocol"
-    enum="PeerConnectionKeyProtocol" expires_after="2021-11-07">
+    enum="PeerConnectionKeyProtocol" expires_after="2022-01-09">
   <owner>hta@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -1532,7 +1532,7 @@
 </histogram>
 
 <histogram name="WebRTC.PeerConnection.KeyProtocolByMedia"
-    enum="PeerConnectionKeyProtocolByMedia" expires_after="2021-11-07">
+    enum="PeerConnectionKeyProtocolByMedia" expires_after="2022-01-09">
   <owner>hta@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -1921,7 +1921,7 @@
 </histogram>
 
 <histogram name="WebRTC.SentVideoTrackDuration" units="ms"
-    expires_after="2021-11-07">
+    expires_after="2022-01-09">
   <owner>perkj@chromium.org</owner>
   <summary>
     Durations of video tracks sent over a PeerConnection. The stopwatch starts
diff --git a/tools/metrics/histograms/update_histogram_enum.py b/tools/metrics/histograms/update_histogram_enum.py
index f2942c43..23beab6 100644
--- a/tools/metrics/histograms/update_histogram_enum.py
+++ b/tools/metrics/histograms/update_histogram_enum.py
@@ -218,7 +218,7 @@
   and returns both in XML format.
   """
   Log('Reading existing histograms from "{0}".'.format(ENUMS_PATH))
-  with open(ENUMS_PATH, 'rb') as f:
+  with open(ENUMS_PATH, 'r', encoding='utf-8') as f:
     histograms_doc = minidom.parse(f)
     f.seek(0)
     xml = f.read()
@@ -302,7 +302,7 @@
     Log('Cancelled.')
     return
 
-  with open(ENUMS_PATH, 'wb') as f:
+  with open(ENUMS_PATH, 'w', encoding='utf-8') as f:
     f.write(new_xml)
 
   Log('Done.')
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index f478a61..5bf0b4f6 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,8 +1,8 @@
 {
     "trace_processor_shell": {
         "win": {
-            "hash": "c1c9368721a4da0f38ec9d5b99ce0cb48c371450",
-            "remote_path": "perfetto_binaries/trace_processor_shell/win/9d04c12dbe18118cc78c8584508f9eac5ff757f9/trace_processor_shell.exe"
+            "hash": "1e40184a08982bb78e3cce7a2c21a975eb6b6e00",
+            "remote_path": "perfetto_binaries/trace_processor_shell/win/aecbd80f576686b67e29bdfae8c9c03bb9ce1996/trace_processor_shell.exe"
         },
         "mac": {
             "hash": "d7eb4c9af40a0bfbf9431c469c498da7f8195132",
@@ -10,7 +10,7 @@
         },
         "linux": {
             "hash": "cf2335e84a4ffd5b6205005e90fdd6c05211bf4c",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/b3d7d29922b664574fb5052980aa5d00d6e73428/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/aecbd80f576686b67e29bdfae8c9c03bb9ce1996/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/android/javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java b/ui/android/javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java
index 7bb953c..80c198d 100644
--- a/ui/android/javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java
+++ b/ui/android/javatests/src/org/chromium/ui/test/util/DisableAnimationsTestRule.java
@@ -11,6 +11,7 @@
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
+import org.chromium.base.BuildInfo;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 
@@ -23,7 +24,7 @@
 
 /**
  * {@link TestRule} to disable animations for UI testing, or enable animation with new
- * DisableAnimationsTestRule(true).
+ * DisableAnimationsTestRule(true). Does not work on Android S, see https://crbug.com/1225707.
  */
 public class DisableAnimationsTestRule implements TestRule {
     /**
@@ -67,7 +68,14 @@
             IBinder windowManagerBinder = (IBinder) getService.invoke(null, "window");
             mWindowManagerObject = asInterface.invoke(null, windowManagerBinder);
         } catch (Exception e) {
-            throw new RuntimeException("Failed to access animation methods", e);
+            // TODO(https://crbug.com/1225707): Always throw once this works on Android S. The above
+            // API is no longer accessible and will crash regardless of filter rules so just warn
+            // instead.
+            if (BuildInfo.isAtLeastS()) {
+                Log.w(TAG, "Failed to access animation methods", e);
+            } else {
+                throw new RuntimeException("Failed to access animation methods", e);
+            }
         }
     }
 
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn
index 391dda0..26a4183 100644
--- a/ui/file_manager/file_manager/background/js/BUILD.gn
+++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -375,6 +375,7 @@
     "//ui/file_manager/file_manager/common/js:file_operation_common",
     "//ui/file_manager/file_manager/common/js:trash",
     "//ui/file_manager/file_manager/common/js:util",
+    "//ui/file_manager/file_manager/common/js:volume_manager_types",
     "//ui/file_manager/file_manager/common/js:xfm",
     "//ui/file_manager/file_manager/externs:entry_location",
     "//ui/file_manager/file_manager/externs:files_app_entry_interfaces",
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager.js b/ui/file_manager/file_manager/background/js/file_operation_manager.js
index fad5596e..4b42ddf 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_manager.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_manager.js
@@ -8,9 +8,9 @@
 import {FileOperationError, FileOperationProgressEvent} from '../../common/js/file_operation_common.js';
 import {TrashEntry, TrashRootEntry} from '../../common/js/trash.js';
 import {util} from '../../common/js/util.js';
+import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
 import {xfm} from '../../common/js/xfm.js';
 import {FileOperationManager} from '../../externs/background/file_operation_manager.js';
-import {EntryLocation} from '../../externs/entry_location.js';
 import {FakeEntry} from '../../externs/files_app_entry_interfaces.js';
 import {VolumeManager} from '../../externs/volume_manager.js';
 
@@ -251,6 +251,13 @@
           if (entries.length === 0) {
             return;
           }
+          if (!this.volumeManager_) {
+            volumeManagerFactory.getInstance().then(volumeManager => {
+              this.volumeManager_ = volumeManager;
+              this.queueCopy_(targetEntry, entries, isMove, opt_taskId);
+            });
+            return;
+          }
           this.queueCopy_(targetEntry, entries, isMove, opt_taskId);
         })
         .catch(error => {
@@ -277,8 +284,26 @@
       // When moving between different volumes, moving is implemented as a copy
       // and delete. This is because moving between volumes is slow, and
       // moveTo() is not cancellable nor provides progress feedback.
-      if (util.isSameFileSystem(
-              entries[0].filesystem, targetDirEntry.filesystem)) {
+      const sameFileSystem = util.isSameFileSystem(
+          entries[0].filesystem, targetDirEntry.filesystem);
+      let moveBetweenDownloadsAndMyFiles = false;
+      if (sameFileSystem &&
+          this.volumeManager_.getLocationInfo(assert(entries[0]))
+                  .volumeInfo.volumeType ===
+              VolumeManagerCommon.VolumeType.DOWNLOADS) {
+        // My files and Downloads should be seen as different filesystems, since
+        // a local move is not possible between these locations
+        // (crbug.com/1200251).
+        // TODO(crbug/959083): Remove this special case when move between
+        // MyFiles and Downloads is atomic.
+        const sourceInDownloads = entries[0].fullPath.startsWith('/Downloads/');
+        const destinationInDownloads =
+            targetDirEntry.fullPath.startsWith('/Downloads/') ||
+            targetDirEntry.fullPath === '/Downloads';
+        moveBetweenDownloadsAndMyFiles =
+            sourceInDownloads !== destinationInDownloads;
+      }
+      if (sameFileSystem && !moveBetweenDownloadsAndMyFiles) {
         task = new fileOperationUtil.MoveTask(taskId, entries, targetDirEntry);
       } else {
         task = new fileOperationUtil.CopyTask(
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.m.js b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.m.js
index 8ca9519..0e69123 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.m.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_manager_unittest.m.js
@@ -3,11 +3,11 @@
 // found in the LICENSE file.
 
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import { assertArrayEquals, assertEquals, assertFalse,assertTrue} from 'chrome://test/chai_assert.js';
+import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from 'chrome://test/chai_assert.js';
 
 import {FileOperationProgressEvent} from '../../common/js/file_operation_common.js';
 import {installMockChrome} from '../../common/js/mock_chrome.js';
-import { joinPath, MockDirectoryEntry, MockEntry, MockFileEntry,MockFileSystem} from '../../common/js/mock_entry.js';
+import {joinPath, MockDirectoryEntry, MockEntry, MockFileEntry, MockFileSystem} from '../../common/js/mock_entry.js';
 import {reportPromise, waitUntil} from '../../common/js/test_error_reporting.js';
 import {util} from '../../common/js/util.js';
 import {FileOperationManager} from '../../externs/background/file_operation_manager.js';
@@ -867,6 +867,174 @@
 }
 
 /**
+ * Tests moving files within My files (Downloads excluded) or within Downloads.
+ * When the source and the destination volumes are the same, the local
+ * implementation of move should be used instead of copy + delete.
+ */
+export async function testMoveSameVolume(done) {
+  // Prepare entries.
+  const fileSystem = createTestFileSystem('downloads', {
+    '/dest': DIRECTORY_SIZE,
+    '/test.txt': 10,
+    '/Downloads': DIRECTORY_SIZE,
+    '/Downloads2': DIRECTORY_SIZE,
+    '/Downloads/dest': DIRECTORY_SIZE,
+    '/Downloads/test.txt': 10,
+    '/dummyEntry.txt': 10,
+  });
+  window.webkitResolveLocalFileSystemURL = (url, success, failure) => {
+    resolveTestFileSystemURL(fileSystem, url, success, failure);
+  };
+
+  /**
+   * Fake implementation of Entry.moveTo.
+   * @param {!DirectoryEntry} destination
+   * @param {string=} destinationName
+   * @param {function(!Entry)=} success_callback
+   * @param {function(!FileError)=} error_callback
+   */
+  const moveToFunc =
+      (destination, destinationName, success_callback, error_callback) => {
+        moveToCount++;
+        // The callback argument is meant to be the entry created by
+        // Entry.moveTo, it has no importance here.
+        success_callback(fileSystem.entries['/dummyEntry.txt']);
+      };
+
+  // Override the moveTo method of the entries to move, as well as
+  // fileManagerPrivate.startCopy. If the same-volume implementation is
+  // used, moveTo is called but not startCopy.
+  let moveToCount = 0;
+  fileSystem.entries['/test.txt'].moveTo = moveToFunc;
+  fileSystem.entries['/Downloads/test.txt'].moveTo = moveToFunc;
+
+  let startCopyCount = 0;
+  mockChrome.fileManagerPrivate.startCopy = () => {
+    startCopyCount++;
+  };
+
+  volumeManager = new FakeVolumeManager();
+  fileOperationManager = new FileOperationManagerImpl();
+
+  const isMove = true;
+
+  // Move /test.txt to /dest.
+  fileOperationManager.paste(
+      [fileSystem.entries['/test.txt']],
+      /** @type {!DirectoryEntry} */ (fileSystem.entries['/dest']), isMove);
+
+  // Wait until fileSystem.entries['/test.txt'].moveTo is called.
+  await waitUntil(() => moveToCount == 1 && !startCopyCount);
+
+  // Move /test.txt to /Downloads2, Downloads2 is not a Downloads location, so a
+  // local move can also be executed.
+  fileOperationManager.paste(
+      [fileSystem.entries['/test.txt']],
+      /** @type {!DirectoryEntry} */ (fileSystem.entries['/Downloads2']),
+      isMove);
+
+  // Wait until fileSystem.entries['/test.txt'].moveTo is called.
+  await waitUntil(() => moveToCount == 2 && !startCopyCount);
+
+  // Move /Downloads/test.txt to /Downloads/dest.
+  fileOperationManager.paste(
+      [fileSystem.entries['/Downloads/test.txt']],
+      /** @type {!DirectoryEntry} */ (fileSystem.entries['/Downloads/dest']),
+      isMove);
+
+  // Wait until fileSystem.entries['/Downloads/test.txt'].moveTo is called.
+  await waitUntil(() => moveToCount == 3 && !startCopyCount);
+
+  done();
+}
+
+/**
+ * Tests moving files between My files and Downloads: Downloads being a bind
+ * mount into My files, the copy + delete implementation of move should be used.
+ */
+export async function testMoveBetweenMyFilesDownloads(done) {
+  // Prepare entries and their resolver.
+  const fileSystem = createTestFileSystem('downloads', {
+    '/Downloads': DIRECTORY_SIZE,
+    '/Downloads/test.txt': 10,
+    '/test.txt': 10,
+  });
+  window.webkitResolveLocalFileSystemURL = (url, success, failure) => {
+    resolveTestFileSystemURL(fileSystem, url, success, failure);
+  };
+
+  /**
+   * Fake implementation of fileManagerPrivate.startCopy.
+   * @param {!Entry} source
+   * @param {!Entry} destination
+   * @param {string} newName
+   * @param {function(number)} callback
+   */
+  const startCopyFunc = (source, destination, newName, callback) => {
+    const makeStatus = type => {
+      return {
+        type: type,
+        sourceUrl: source.toURL(),
+        destinationUrl: destination.toURL()
+      };
+    };
+
+    startCopyCount++;
+
+    // To signal to the background that the copy is finished, we need to
+    // provide its copyId first.
+    callback(copyId);
+
+    const listener = mockChrome.fileManagerPrivate.onCopyProgress.listener_;
+    // The success status is dispatched to the background to indicate that
+    // the copy associated with copyId has terminated.
+    listener(copyId, makeStatus('success'));
+
+    copyId++;
+  };
+
+  // Override the moveTo method of the entries to move, as well as
+  // fileManagerPrivate.startCopy. If the cross-filesystem implementation is
+  // used, startCopy is called (followed by the removal of the source entry) but
+  // not moveTo.
+  let moveToCount = 0;
+  fileSystem.entries['/test.txt'].moveTo = () => {
+    moveToCount++;
+  };
+  fileSystem.entries['/Downloads/test.txt'].moveTo = () => {
+    moveToCount++;
+  };
+
+  let startCopyCount = 0;
+  let copyId = 0;
+  mockChrome.fileManagerPrivate.startCopy = startCopyFunc;
+
+  volumeManager = new FakeVolumeManager();
+  fileOperationManager = new FileOperationManagerImpl();
+
+  const isMove = true;
+
+  // Move /test.txt to /Downloads/.
+  fileOperationManager.paste(
+      [fileSystem.entries['/test.txt']],
+      /** @type {!DirectoryEntry} */ (fileSystem.entries['/Downloads']),
+      isMove);
+
+  // Wait until fileManagerPrivate.startCopy is called
+  await waitUntil(() => startCopyCount == 1 && !moveToCount);
+
+  // Move /Downloads/test.txt to /.
+  fileOperationManager.paste(
+      [fileSystem.entries['/Downloads/test.txt']],
+      /** @type {!DirectoryEntry} */ (fileSystem.entries['/']), isMove);
+
+  // Wait until fileManagerPrivate.startCopy is called a second time.
+  await waitUntil(() => startCopyCount == 2 && !moveToCount);
+
+  done();
+}
+
+/**
  * Tests fileOperationManager.deleteEntries.
  * @param {function(boolean)} callback Callback to be passed true on error.
  */
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js
index 2e8701f..bb2827e 100644
--- a/ui/file_manager/file_manager/common/js/util.js
+++ b/ui/file_manager/file_manager/common/js/util.js
@@ -324,12 +324,12 @@
 
 /**
  * Extracts path from filesystem: URL.
- * @param {string} url Filesystem URL.
- * @return {?string} The path.
+ * @param {?string=} url Filesystem URL.
+ * @return {?string} The path if it can be parsed, null if it cannot.
  */
 util.extractFilePath = url => {
   const match =
-      /^filesystem:[\w-]*:\/\/[\w]*\/(external|persistent|temporary)(\/.*)$/
+      /^filesystem:[\w-]*:\/\/[\w-]*\/(external|persistent|temporary)(\/.*)$/
           .exec(url);
   const path = match && match[2];
   if (!path) {
diff --git a/ui/file_manager/file_manager/common/js/util_unittest.m.js b/ui/file_manager/file_manager/common/js/util_unittest.m.js
index 6be2c7e4..44698a2 100644
--- a/ui/file_manager/file_manager/common/js/util_unittest.m.js
+++ b/ui/file_manager/file_manager/common/js/util_unittest.m.js
@@ -344,3 +344,20 @@
   i18nErrorName = util.getFileErrorString('PathExistsError');
   assertEquals(i18nErrorName, 'FILE_ERROR_PATH_EXISTS');
 }
+
+export function testExtractFilePath() {
+  let url = '';
+
+  assertEquals(util.extractFilePath(''), null);
+  assertEquals(util.extractFilePath(null), null);
+  assertEquals(util.extractFilePath(undefined), null);
+
+  // In the Extension:
+  url =
+      'filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/external/Downloads-u/Downloads/f.zip';
+  assertEquals(util.extractFilePath(url), '/Downloads-u/Downloads/f.zip');
+
+  // In the SWA:
+  url = 'filesystem:chrome://file-manager/external/Downloads-u/Downloads/f.zip';
+  assertEquals(util.extractFilePath(url), '/Downloads-u/Downloads/f.zip');
+}
diff --git a/ui/file_manager/file_manager/foreground/js/constants.js b/ui/file_manager/file_manager/foreground/js/constants.js
index 4555e6e..f755213 100644
--- a/ui/file_manager/file_manager/foreground/js/constants.js
+++ b/ui/file_manager/file_manager/foreground/js/constants.js
@@ -3,10 +3,10 @@
 // found in the LICENSE file.
 
 /**
- * Namespace for common constnats used in Files app.
+ * Namespace for common constants used in Files app.
  * @namespace
  */
-const constants = {};
+export const constants = {};
 
 /**
  * @const {!Array<string>}
@@ -110,4 +110,5 @@
  */
 constants.CROSTINI_CONNECT_ERR = 'CrostiniConnectErr';
 
-export {constants};
+/** @const {string} */
+constants.FILES_APP_EXTENSION_ID = 'hhaomjibdihmijegdhdafkllkbggdgoj';
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js
index 1bc209a..f62344d 100644
--- a/ui/file_manager/file_manager/foreground/js/file_tasks.js
+++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -328,7 +328,7 @@
    */
   static isInternalTask_(descriptor) {
     const {appId, taskType, actionId} = descriptor;
-    if (appId !== chrome.runtime.id || taskType !== 'app') {
+    if (appId !== constants.FILES_APP_EXTENSION_ID || taskType !== 'app') {
       return false;
     }
     switch (actionId) {
@@ -374,7 +374,7 @@
    */
   static annotateTasks_(tasks, entries) {
     const result = [];
-    const id = chrome.runtime.id;
+    const id = constants.FILES_APP_EXTENSION_ID;
     for (const task of tasks) {
       const {appId, taskType, actionId} = task.descriptor;
 
@@ -646,7 +646,7 @@
 
     this.checkAvailability_(() => {
       const descriptor = {
-        appId: chrome.runtime.id,
+        appId: constants.FILES_APP_EXTENSION_ID,
         taskType: 'file',
         actionId: 'view-in-browser'
       };
@@ -1317,7 +1317,7 @@
  * @const {!chrome.fileManagerPrivate.FileTaskDescriptor}
  */
 FileTasks.INSTALL_LINUX_PACKAGE_TASK_DESCRIPTOR = {
-  appId: chrome.runtime.id,
+  appId: constants.FILES_APP_EXTENSION_ID,
   taskType: 'app',
   actionId: 'install-linux-package'
 };
@@ -1327,7 +1327,7 @@
  * @const {!chrome.fileManagerPrivate.FileTaskDescriptor}
  */
 FileTasks.FILES_OPEN_ZIP_TASK_DESCRIPTOR = {
-  appId: chrome.runtime.id,
+  appId: constants.FILES_APP_EXTENSION_ID,
   taskType: 'app',
   actionId: 'open-zip'
 };
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.m.js b/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.m.js
index a5f500b0..92c5c90 100644
--- a/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.m.js
+++ b/ui/file_manager/file_manager/foreground/js/file_tasks_unittest.m.js
@@ -18,6 +18,7 @@
 import {VolumeManager} from '../../externs/volume_manager.js';
 import {FilesPasswordDialog} from '../elements/files_password_dialog.js';
 
+import {constants} from './constants.js';
 import {DirectoryModel} from './directory_model.js';
 import {FileTasks} from './file_tasks.js';
 import {FileTransferController} from './file_transfer_controller.js';
@@ -168,9 +169,7 @@
         callback();
       },
     },
-    runtime: {
-      id: 'test-extension-id',
-    },
+    runtime: {},
   };
 
   installMockChrome(mockChrome);
@@ -594,7 +593,7 @@
   };
   const fileTask = {
     descriptor: {
-      appId: 'test-extension-id',
+      appId: constants.FILES_APP_EXTENSION_ID,
       taskType: 'app',
       actionId: 'install-linux-package'
     },
@@ -651,7 +650,7 @@
             [
               {
                 descriptor: {
-                  appId: 'test-extension-id',
+                  appId: constants.FILES_APP_EXTENSION_ID,
                   taskType: 'app',
                   actionId: 'import-crostini-image'
                 },
diff --git a/ui/gfx/geometry/mojom/BUILD.gn b/ui/gfx/geometry/mojom/BUILD.gn
index 5bb3781..787c0aac 100644
--- a/ui/gfx/geometry/mojom/BUILD.gn
+++ b/ui/gfx/geometry/mojom/BUILD.gn
@@ -77,6 +77,7 @@
   }
   cpp_typemaps = [ shared_cpp_typemap ]
   blink_cpp_typemaps = [ shared_cpp_typemap ]
+  webui_module_path = "chrome://resources/mojo/ui/gfx/geometry/mojom"
 }
 
 mojom("test_interfaces") {
diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc
index a02662f..40d441f 100644
--- a/ui/native_theme/native_theme_win.cc
+++ b/ui/native_theme/native_theme_win.cc
@@ -1524,13 +1524,17 @@
     case kInnerSpinButton:
       switch (state) {
         case kDisabled:
-          return extra.inner_spin.spin_up ? UPS_DISABLED : DNS_DISABLED;
+          return extra.inner_spin.spin_up ? static_cast<int>(UPS_DISABLED)
+                                          : static_cast<int>(DNS_DISABLED);
         case kHovered:
-          return extra.inner_spin.spin_up ? UPS_HOT : DNS_HOT;
+          return extra.inner_spin.spin_up ? static_cast<int>(UPS_HOT)
+                                          : static_cast<int>(DNS_HOT);
         case kNormal:
-          return extra.inner_spin.spin_up ? UPS_NORMAL : DNS_NORMAL;
+          return extra.inner_spin.spin_up ? static_cast<int>(UPS_NORMAL)
+                                          : static_cast<int>(DNS_NORMAL);
         case kPressed:
-          return extra.inner_spin.spin_up ? UPS_PRESSED : DNS_PRESSED;
+          return extra.inner_spin.spin_up ? static_cast<int>(UPS_PRESSED)
+                                          : static_cast<int>(DNS_PRESSED);
         case kNumStates:
           NOTREACHED();
           return 0;
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
index ed8ac17..e2f18a9 100644
--- a/ui/ozone/platform/wayland/BUILD.gn
+++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -154,6 +154,8 @@
     "host/xdg_surface_wrapper_impl.h",
     "host/xdg_toplevel_wrapper_impl.cc",
     "host/xdg_toplevel_wrapper_impl.h",
+    "host/zwp_idle_inhibit_manager.cc",
+    "host/zwp_idle_inhibit_manager.h",
     "host/zwp_primary_selection_device.cc",
     "host/zwp_primary_selection_device.h",
     "host/zwp_primary_selection_device_manager.cc",
@@ -194,6 +196,7 @@
     "//third_party/wayland-protocols:extended_drag",
     "//third_party/wayland-protocols:gtk_primary_selection_protocol",
     "//third_party/wayland-protocols:gtk_shell_protocol",
+    "//third_party/wayland-protocols:idle_inhibit_protocol",
     "//third_party/wayland-protocols:keyboard_extension_protocol",
     "//third_party/wayland-protocols:linux_dmabuf_protocol",
     "//third_party/wayland-protocols:linux_explicit_synchronization_protocol",
diff --git a/ui/ozone/platform/wayland/common/wayland_object.cc b/ui/ozone/platform/wayland/common/wayland_object.cc
index 929f239..5bde887 100644
--- a/ui/ozone/platform/wayland/common/wayland_object.cc
+++ b/ui/ozone/platform/wayland/common/wayland_object.cc
@@ -10,6 +10,7 @@
 #include <gtk-primary-selection-client-protocol.h>
 #include <gtk-shell-client-protocol.h>
 #include <idle-client-protocol.h>
+#include <idle-inhibit-unstable-v1-client-protocol.h>
 #include <keyboard-extension-unstable-v1-client-protocol.h>
 #include <linux-dmabuf-unstable-v1-client-protocol.h>
 #include <linux-explicit-synchronization-unstable-v1-client-protocol.h>
@@ -120,6 +121,16 @@
 void (*ObjectTraits<org_kde_kwin_idle_timeout>::deleter)(
     org_kde_kwin_idle_timeout*) = &org_kde_kwin_idle_timeout_destroy;
 
+const wl_interface* ObjectTraits<zwp_idle_inhibit_manager_v1>::interface =
+    &zwp_idle_inhibit_manager_v1_interface;
+void (*ObjectTraits<zwp_idle_inhibit_manager_v1>::deleter)(
+    zwp_idle_inhibit_manager_v1*) = &zwp_idle_inhibit_manager_v1_destroy;
+
+const wl_interface* ObjectTraits<zwp_idle_inhibitor_v1>::interface =
+    &zwp_idle_inhibitor_v1_interface;
+void (*ObjectTraits<zwp_idle_inhibitor_v1>::deleter)(zwp_idle_inhibitor_v1*) =
+    &zwp_idle_inhibitor_v1_destroy;
+
 const wl_interface*
     ObjectTraits<zwp_primary_selection_device_manager_v1>::interface =
         &zwp_primary_selection_device_manager_v1_interface;
diff --git a/ui/ozone/platform/wayland/common/wayland_object.h b/ui/ozone/platform/wayland/common/wayland_object.h
index 23f8b25..fcf4fb9 100644
--- a/ui/ozone/platform/wayland/common/wayland_object.h
+++ b/ui/ozone/platform/wayland/common/wayland_object.h
@@ -17,6 +17,8 @@
 struct gtk_surface1;
 struct org_kde_kwin_idle;
 struct org_kde_kwin_idle_timeout;
+struct zwp_idle_inhibit_manager_v1;
+struct zwp_idle_inhibitor_v1;
 struct zwp_primary_selection_device_v1;
 struct zwp_primary_selection_device_manager_v1;
 struct zwp_primary_selection_offer_v1;
@@ -149,6 +151,18 @@
 };
 
 template <>
+struct ObjectTraits<zwp_idle_inhibit_manager_v1> {
+  static const wl_interface* interface;
+  static void (*deleter)(zwp_idle_inhibit_manager_v1*);
+};
+
+template <>
+struct ObjectTraits<zwp_idle_inhibitor_v1> {
+  static const wl_interface* interface;
+  static void (*deleter)(zwp_idle_inhibitor_v1*);
+};
+
+template <>
 struct ObjectTraits<zwp_primary_selection_device_manager_v1> {
   static const wl_interface* interface;
   static void (*deleter)(zwp_primary_selection_device_manager_v1*);
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
index 61825e3e..36e6823 100644
--- a/ui/ozone/platform/wayland/host/wayland_connection.cc
+++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -53,6 +53,7 @@
 #include "ui/ozone/platform/wayland/host/wayland_zwp_pointer_gestures.h"
 #include "ui/ozone/platform/wayland/host/wayland_zwp_relative_pointer_manager.h"
 #include "ui/ozone/platform/wayland/host/xdg_foreign_wrapper.h"
+#include "ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.h"
 #include "ui/ozone/platform/wayland/host/zwp_primary_selection_device_manager.h"
 #include "ui/platform_window/common/platform_window_defaults.h"
 
@@ -118,6 +119,7 @@
 constexpr uint32_t kMaxGtkShell1Version = 4;
 
 constexpr uint32_t kMaxOrgKdeKwinIdleVersion = 1;
+constexpr uint32_t kMaxZwpIdleInhibitManagerVersion = 1;
 
 int64_t ConvertTimespecToMicros(const struct timespec& ts) {
   // On 32-bit systems, the calculation cannot overflow int64_t.
@@ -549,6 +551,16 @@
     }
     connection->gtk_shell1_ = std::make_unique<GtkShell1>(gtk_shell1.release());
     ReportShellUMA(UMALinuxWaylandShell::kGtkShell1);
+  } else if (!connection->zwp_idle_inhibit_manager_ &&
+             strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) {
+    auto manager = wl::Bind<zwp_idle_inhibit_manager_v1>(
+        registry, name, std::min(version, kMaxZwpIdleInhibitManagerVersion));
+    if (!manager) {
+      LOG(ERROR) << "Failed to bind zwp_idle_inhibit_manager_v1";
+      return;
+    }
+    connection->zwp_idle_inhibit_manager_ =
+        std::make_unique<ZwpIdleInhibitManager>(manager.release(), connection);
   } else if (!connection->zwp_primary_selection_device_manager_ &&
              strcmp(interface, "zwp_primary_selection_device_manager_v1") ==
                  0) {
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h
index 6e416c6a..1565ae8 100644
--- a/ui/ozone/platform/wayland/host/wayland_connection.h
+++ b/ui/ozone/platform/wayland/host/wayland_connection.h
@@ -54,6 +54,7 @@
 class WaylandWindowDragController;
 class GtkPrimarySelectionDeviceManager;
 class GtkShell1;
+class ZwpIdleInhibitManager;
 class ZwpPrimarySelectionDeviceManager;
 class XdgForeignWrapper;
 
@@ -216,6 +217,10 @@
 
   XdgForeignWrapper* xdg_foreign() const { return xdg_foreign_.get(); }
 
+  ZwpIdleInhibitManager* zwp_idle_inhibit_manager() const {
+    return zwp_idle_inhibit_manager_.get();
+  }
+
   // Returns true when dragging is entered or started.
   bool IsDragInProgress() const;
 
@@ -319,6 +324,7 @@
   std::unique_ptr<WaylandShm> shm_;
   std::unique_ptr<WaylandBufferManagerHost> buffer_manager_host_;
   std::unique_ptr<XdgForeignWrapper> xdg_foreign_;
+  std::unique_ptr<ZwpIdleInhibitManager> zwp_idle_inhibit_manager_;
 
   // Clipboard-related objects. |clipboard_| must be declared after all
   // DeviceManager instances it depends on, otherwise tests may crash with
diff --git a/ui/ozone/platform/wayland/host/wayland_screen.cc b/ui/ozone/platform/wayland/host/wayland_screen.cc
index a962b88e..2789dbe 100644
--- a/ui/ozone/platform/wayland/host/wayland_screen.cc
+++ b/ui/ozone/platform/wayland/host/wayland_screen.cc
@@ -26,6 +26,7 @@
 #include "ui/ozone/platform/wayland/host/wayland_connection.h"
 #include "ui/ozone/platform/wayland/host/wayland_cursor_position.h"
 #include "ui/ozone/platform/wayland/host/wayland_window.h"
+#include "ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.h"
 
 #if defined(USE_DBUS)
 #include "ui/ozone/platform/wayland/host/org_gnome_mutter_idle_monitor.h"
@@ -249,6 +250,36 @@
   return display_matching ? *display_matching : GetPrimaryDisplay();
 }
 
+void WaylandScreen::SetScreenSaverSuspended(bool suspend) {
+  if (!connection_->zwp_idle_inhibit_manager())
+    return;
+
+  if (suspend) {
+    // Wayland inhibits idle behaviour on certain output, and implies that a
+    // surface bound to that output should obtain the inhibitor and hold it
+    // until it no longer needs to prevent the output to go idle.
+    // We assume that the idle lock is initiated by the user, and therefore the
+    // surface that we should use is the one owned by the window that is focused
+    // currently.
+    const auto* window_manager = connection_->wayland_window_manager();
+    DCHECK(window_manager);
+    const auto* current_window = window_manager->GetCurrentFocusedWindow();
+    if (!current_window) {
+      LOG(WARNING) << "Cannot inhibit going idle when no window is focused";
+      return;
+    }
+    DCHECK(current_window->root_surface());
+    idle_inhibitor_ = connection_->zwp_idle_inhibit_manager()->CreateInhibitor(
+        current_window->root_surface()->surface());
+  } else {
+    idle_inhibitor_.reset();
+  }
+}
+
+bool WaylandScreen::IsScreenSaverActive() const {
+  return idle_inhibitor_ != nullptr;
+}
+
 base::TimeDelta WaylandScreen::CalculateIdleTime() const {
   // Try the org_kde_kwin_idle Wayland protocol extension (KWin).
   if (const auto* kde_idle = connection_->org_kde_kwin_idle()) {
diff --git a/ui/ozone/platform/wayland/host/wayland_screen.h b/ui/ozone/platform/wayland/host/wayland_screen.h
index 979cf76e..0e84a900 100644
--- a/ui/ozone/platform/wayland/host/wayland_screen.h
+++ b/ui/ozone/platform/wayland/host/wayland_screen.h
@@ -16,6 +16,7 @@
 #include "ui/display/tablet_state.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/geometry/point.h"
+#include "ui/ozone/platform/wayland/common/wayland_object.h"
 #include "ui/ozone/public/platform_screen.h"
 
 namespace gfx {
@@ -62,6 +63,8 @@
       const gfx::Point& point) const override;
   display::Display GetDisplayMatching(
       const gfx::Rect& match_rect) const override;
+  void SetScreenSaverSuspended(bool suspend) override;
+  bool IsScreenSaverActive() const override;
   base::TimeDelta CalculateIdleTime() const override;
   void AddObserver(display::DisplayObserver* observer) override;
   void RemoveObserver(display::DisplayObserver* observer) override;
@@ -97,6 +100,8 @@
   // accordingly.
   float additional_scale_ = 0.f;
 
+  wl::Object<zwp_idle_inhibitor_v1> idle_inhibitor_;
+
   base::WeakPtrFactory<WaylandScreen> weak_factory_;
 };
 
diff --git a/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.cc b/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.cc
new file mode 100644
index 0000000..e431da6
--- /dev/null
+++ b/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.cc
@@ -0,0 +1,26 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.h"
+
+#include <idle-inhibit-unstable-v1-client-protocol.h>
+
+#include "ui/ozone/platform/wayland/host/wayland_connection.h"
+
+namespace ui {
+
+ZwpIdleInhibitManager::ZwpIdleInhibitManager(
+    zwp_idle_inhibit_manager_v1* manager,
+    WaylandConnection* connection)
+    : manager_(manager) {}
+
+ZwpIdleInhibitManager::~ZwpIdleInhibitManager() = default;
+
+wl::Object<zwp_idle_inhibitor_v1> ZwpIdleInhibitManager::CreateInhibitor(
+    wl_surface* surface) {
+  return wl::Object<zwp_idle_inhibitor_v1>(
+      zwp_idle_inhibit_manager_v1_create_inhibitor(manager_.get(), surface));
+}
+
+}  // namespace ui
diff --git a/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.h b/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.h
new file mode 100644
index 0000000..eabda81
--- /dev/null
+++ b/ui/ozone/platform/wayland/host/zwp_idle_inhibit_manager.h
@@ -0,0 +1,33 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_IDLE_INHIBIT_MANAGER_H_
+#define UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_IDLE_INHIBIT_MANAGER_H_
+
+#include "ui/ozone/platform/wayland/common/wayland_object.h"
+
+namespace ui {
+
+class WaylandConnection;
+
+// Wraps the idle inhibit manager, which is provided via
+// zwp_idle_inhibit_manager_v1 interface.
+class ZwpIdleInhibitManager {
+ public:
+  explicit ZwpIdleInhibitManager(zwp_idle_inhibit_manager_v1* manager,
+                                 WaylandConnection* connection);
+  ZwpIdleInhibitManager(const ZwpIdleInhibitManager&) = delete;
+  ZwpIdleInhibitManager& operator=(const ZwpIdleInhibitManager&) = delete;
+  ~ZwpIdleInhibitManager();
+
+  wl::Object<zwp_idle_inhibitor_v1> CreateInhibitor(wl_surface* surface);
+
+ private:
+  // Wayland object wrapped by this class.
+  wl::Object<zwp_idle_inhibit_manager_v1> manager_;
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_ZWP_IDLE_INHIBIT_MANAGER_H_
diff --git a/ui/ozone/platform/wayland/test/mock_xdg_shell.cc b/ui/ozone/platform/wayland/test/mock_xdg_shell.cc
index 6edad19..a9b1af5e 100644
--- a/ui/ozone/platform/wayland/test/mock_xdg_shell.cc
+++ b/ui/ozone/platform/wayland/test/mock_xdg_shell.cc
@@ -24,8 +24,8 @@
   auto* surface = GetUserDataAs<MockSurface>(surface_resource);
   if (surface->xdg_surface()) {
     uint32_t xdg_error = implementation == &kMockXdgSurfaceImpl
-                             ? XDG_WM_BASE_ERROR_ROLE
-                             : ZXDG_SHELL_V6_ERROR_ROLE;
+                             ? static_cast<uint32_t>(XDG_WM_BASE_ERROR_ROLE)
+                             : static_cast<uint32_t>(ZXDG_SHELL_V6_ERROR_ROLE);
     wl_resource_post_error(resource, xdg_error, "surface already has a role");
     return;
   }
diff --git a/ui/ozone/public/platform_screen.h b/ui/ozone/public/platform_screen.h
index 91a9b58..6e3367d 100644
--- a/ui/ozone/public/platform_screen.h
+++ b/ui/ozone/public/platform_screen.h
@@ -84,6 +84,9 @@
       const gfx::Rect& match_rect) const = 0;
 
   // Suspends the platform-specific screensaver, if applicable.
+  // Can be called more than once with the same value for |suspend|, but those
+  // states should not stack: the first alternating value should toggle the
+  // state of the suspend.
   virtual void SetScreenSaverSuspended(bool suspend);
 
   // Returns whether the screensaver is currently running.
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc
index 5549091..41e9c83 100644
--- a/ui/views/bubble/bubble_frame_view.cc
+++ b/ui/views/bubble/bubble_frame_view.cc
@@ -311,13 +311,6 @@
 
 void BubbleFrameView::SizeConstraintsChanged() {}
 
-void BubbleFrameView::InsertClientView(ClientView* client_view) {
-  // Place the client view before any footnote view for focus order.
-  footnote_container_
-      ? AddChildViewAt(client_view, GetIndexOf(footnote_container_))
-      : AddChildView(client_view);
-}
-
 void BubbleFrameView::SetTitleView(std::unique_ptr<View> title_view) {
   DCHECK(title_view);
   delete default_title_;
@@ -562,9 +555,13 @@
   delete footnote_container_;
   footnote_container_ = nullptr;
   if (view) {
+    // Insert the footnote container before |close_| so that the footnote is
+    // inserted before caption buttons in the focus cycle.
     int radius = bubble_border_ ? bubble_border_->corner_radius() : 0;
-    footnote_container_ = AddChildView(std::make_unique<FootnoteContainerView>(
-        footnote_margins_, std::move(view), radius));
+    footnote_container_ =
+        AddChildViewAt(std::make_unique<FootnoteContainerView>(
+                           footnote_margins_, std::move(view), radius),
+                       GetIndexOf(close_));
   }
   InvalidateLayout();
 }
diff --git a/ui/views/bubble/bubble_frame_view.h b/ui/views/bubble/bubble_frame_view.h
index c526a05..515987d 100644
--- a/ui/views/bubble/bubble_frame_view.h
+++ b/ui/views/bubble/bubble_frame_view.h
@@ -64,7 +64,6 @@
   void UpdateWindowIcon() override;
   void UpdateWindowTitle() override;
   void SizeConstraintsChanged() override;
-  void InsertClientView(ClientView* client_view) override;
 
   // Sets a custom view to be the dialog title instead of the |default_title_|
   // label. If there is an existing title view it will be deleted.
diff --git a/ui/views/window/non_client_view.cc b/ui/views/window/non_client_view.cc
index 299191b5..2d0e850 100644
--- a/ui/views/window/non_client_view.cc
+++ b/ui/views/window/non_client_view.cc
@@ -7,7 +7,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/containers/cxx20_erase.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/hit_test.h"
@@ -126,24 +125,6 @@
     client_view->SetClipPath(client_clip);
 }
 
-View::Views NonClientFrameView::GetChildrenInZOrder() {
-  View::Views paint_order = View::GetChildrenInZOrder();
-  views::ClientView* client_view =
-      GetWidget() ? GetWidget()->client_view() : nullptr;
-
-  // Move the client view to the beginning of the Z-order to ensure that the
-  // other children of the frame view draw on top of it.
-  if (client_view && base::Erase(paint_order, client_view)) {
-    paint_order.insert(paint_order.begin(), client_view);
-  }
-
-  return paint_order;
-}
-
-void NonClientFrameView::InsertClientView(ClientView* client_view) {
-  AddChildView(client_view);
-}
-
 NonClientFrameView::NonClientFrameView() {
   SetEventTargeter(std::make_unique<views::ViewTargeter>(this));
 }
@@ -177,7 +158,7 @@
   frame_view_ = std::move(frame_view);
   if (parent()) {
     AddChildViewAt(frame_view_.get(), 0);
-    frame_view_->InsertClientView(client_view_);
+    frame_view_->AddChildViewAt(client_view_, 0);
   }
 
   if (old_frame_view)
@@ -308,7 +289,7 @@
   // constructor.
   if (details.is_add && GetWidget() && details.child == this) {
     AddChildViewAt(frame_view_.get(), 0);
-    frame_view_->InsertClientView(client_view_);
+    frame_view_->AddChildViewAt(client_view_, 0);
     if (overlay_view_)
       AddChildView(overlay_view_);
   }
diff --git a/ui/views/window/non_client_view.h b/ui/views/window/non_client_view.h
index ab99cda..932a530 100644
--- a/ui/views/window/non_client_view.h
+++ b/ui/views/window/non_client_view.h
@@ -101,12 +101,6 @@
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
   void OnThemeChanged() override;
   void Layout() override;
-  Views GetChildrenInZOrder() override;
-
-  // Inserts the passed client view into this NonClientFrameView. Subclasses can
-  // override this method to indicate a specific insertion spot for the client
-  // view.
-  virtual void InsertClientView(ClientView* client_view);
 
  private:
 #if defined(OS_WIN)
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn
index d40afb7..0c5c6ba 100644
--- a/ui/webui/resources/BUILD.gn
+++ b/ui/webui/resources/BUILD.gn
@@ -47,12 +47,14 @@
   if (include_polymer) {
     deps += [
       "cr_components:build_grdp",
+      "cr_components/customize_themes:build_grdp",
       "cr_elements:build_grdp",
       "//third_party/polymer/v3_0:build_grdp",
     ]
     grdp_files += [
       "$root_gen_dir/third_party/polymer/v3_0/polymer_3_0_resources.grdp",
       "$root_gen_dir/ui/webui/resources/cr_components/cr_components_resources.grdp",
+      "$root_gen_dir/ui/webui/resources/cr_components/customize_themes/resources.grdp",
       "$root_gen_dir/ui/webui/resources/cr_elements/cr_elements_resources.grdp",
     ]
 
diff --git a/ui/webui/resources/cr_components/BUILD.gn b/ui/webui/resources/cr_components/BUILD.gn
index a1d83210..3d5d2b7b 100644
--- a/ui/webui/resources/cr_components/BUILD.gn
+++ b/ui/webui/resources/cr_components/BUILD.gn
@@ -21,13 +21,9 @@
   grd_prefix = "cr_components"
   out_grd = "$target_gen_dir/${grd_prefix}_resources.grdp"
   deps = [ ":preprocess" ]
-  input_files_base_dir = rebase_path(".", "//")
-  input_files = [
-    "customize_themes/colorize.svg",
-    "customize_themes/brush.svg",
-  ]
   if (is_chromeos_ash) {
-    input_files += [
+    input_files_base_dir = rebase_path(".", "//")
+    input_files = [
       "chromeos/multidevice_setup/all_set_1x.svg",
       "chromeos/multidevice_setup/all_set_2x.svg",
       "chromeos/multidevice_setup/start_setup_icon_1x.png",
@@ -94,24 +90,17 @@
   out_folder = "$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_src_manifest"
   in_files = [
-    "customize_themes/browser_proxy.js",
     "most_visited/browser_proxy.js",
     "most_visited/window_proxy.js",
   ]
 }
 
 preprocess_if_expr("preprocess_mojom") {
-  deps = [
-    "//ui/webui/resources/cr_components/customize_themes:mojom_webui_js",
-    "//ui/webui/resources/cr_components/most_visited:mojom_webui_js",
-  ]
+  deps = [ "//ui/webui/resources/cr_components/most_visited:mojom_webui_js" ]
   in_folder = "$root_gen_dir/mojom-webui/ui/webui/resources/cr_components"
   out_folder = "$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_mojom_manifest"
-  in_files = [
-    "customize_themes/customize_themes.mojom-webui.js",
-    "most_visited/most_visited.mojom-webui.js",
-  ]
+  in_files = [ "most_visited/most_visited.mojom-webui.js" ]
 }
 
 preprocess_if_expr("preprocess_generated") {
@@ -120,10 +109,8 @@
   out_folder = "$preprocess_folder"
   out_manifest = "$target_gen_dir/$preprocess_gen_manifest"
   in_files = [
-    "customize_themes/customize_themes.js",
     "most_visited/most_visited.mojom-lite.js",
     "most_visited/most_visited.js",
-    "customize_themes/theme_icon.js",
     "managed_dialog/managed_dialog.js",
     "managed_footnote/managed_footnote.js",
     "omnibox/cr_autocomplete_match_list.js",
@@ -381,7 +368,6 @@
 
 group("closure_compile") {
   deps = [
-    "customize_themes:closure_compile",
     "managed_dialog:closure_compile",
     "managed_footnote:closure_compile",
     "most_visited:closure_compile",
diff --git a/ui/webui/resources/cr_components/chromeos/traffic_counters/traffic_counters.html b/ui/webui/resources/cr_components/chromeos/traffic_counters/traffic_counters.html
index 6e190f5..11001963 100644
--- a/ui/webui/resources/cr_components/chromeos/traffic_counters/traffic_counters.html
+++ b/ui/webui/resources/cr_components/chromeos/traffic_counters/traffic_counters.html
@@ -29,5 +29,12 @@
         [[countersToString_(network.counters)]]
       </span>
     </div>
+    <div class="network-attribute-container">
+      <div class="button-group">
+        <cr-button on-click="onResetTrafficCountersClick_">
+          [[i18n('TrafficCountersResetTrafficCounters')]]
+        </cr-button>
+      </div>
+    </div>
   </network-health-container>
 </template>
diff --git a/ui/webui/resources/cr_components/chromeos/traffic_counters/traffic_counters.js b/ui/webui/resources/cr_components/chromeos/traffic_counters/traffic_counters.js
index 0fc61bb..7a4a1dd 100644
--- a/ui/webui/resources/cr_components/chromeos/traffic_counters/traffic_counters.js
+++ b/ui/webui/resources/cr_components/chromeos/traffic_counters/traffic_counters.js
@@ -118,6 +118,26 @@
   }
 
   /**
+   * Handles requests to reset traffic counters.
+   * @param {!Event} event
+   * @private
+   */
+  async onResetTrafficCountersClick_(event) {
+    const network = event.model.network;
+    this.networkConfig_.resetTrafficCounters(network.guid);
+    const trafficCounters =
+        await this.getTrafficCountersForNetwork_(network.guid);
+    const foundIdx = this.networks_.findIndex(n => n.guid === network.guid);
+    if (foundIdx === -1) {
+      return;
+    }
+    this.splice(
+        'networks_', foundIdx, 1,
+        createNetwork(
+            network.guid, network.name, network.type, trafficCounters));
+  }
+
+  /**
    * Requests traffic counters for networks.
    * @private
    */
@@ -143,6 +163,19 @@
   }
 
   /**
+   * Requests and sets traffic counters for the given network.
+   * @param {string} guid
+   * @return {!Promise<!Array<!Object>>} traff counters for network with guid
+   * @private
+   */
+  async getTrafficCountersForNetwork_(guid) {
+    const trafficCountersObj =
+        await this.networkConfig_.requestTrafficCounters(guid);
+    this.convertSourceEnumToString_(trafficCountersObj.trafficCounters);
+    return trafficCountersObj.trafficCounters;
+  }
+
+  /**
    * @param {!chromeos.networkConfig.mojom.NetworkType} type
    * @return {string} A string for the given NetworkType.
    * @private
diff --git a/ui/webui/resources/cr_components/customize_themes/BUILD.gn b/ui/webui/resources/cr_components/customize_themes/BUILD.gn
index 72c74036..b1d2e8132 100644
--- a/ui/webui/resources/cr_components/customize_themes/BUILD.gn
+++ b/ui/webui/resources/cr_components/customize_themes/BUILD.gn
@@ -3,8 +3,10 @@
 # found in the LICENSE file.
 
 import("//mojo/public/tools/bindings/mojom.gni")
-import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/grit/preprocess_if_expr.gni")
 import("//tools/polymer/html_to_js.gni")
+import("//tools/typescript/ts_library.gni")
+import("//ui/webui/resources/tools/generate_grd.gni")
 
 group("web_components") {
   public_deps = [
@@ -26,44 +28,71 @@
 
 html_to_js("web_components_local") {
   js_files = [
-    "customize_themes.js",
-    "theme_icon.js",
+    "customize_themes.ts",
+    "theme_icon.ts",
   ]
 }
 
-js_type_check("closure_compile") {
-  is_polymer3 = true
-  closure_flags = default_closure_args + mojom_js_args
+# Output folder used to hold preprocess_if_expr() output.
+preprocess_folder_tmp = "$root_gen_dir/ui/webui/resources/preprocessed/cr_components/customize_themes_tmp"
+
+# Output folder used to hold ts_library() output.
+preprocess_folder = "$root_gen_dir/ui/webui/resources/preprocessed/cr_components/customize_themes"
+
+ts_library("build_ts") {
+  root_dir = preprocess_folder_tmp
+  out_dir = preprocess_folder
+  tsconfig_base = "tsconfig_base.json"
+  in_files = [
+    "browser_proxy.ts",
+    "customize_themes.ts",
+    "customize_themes.mojom-webui.js",
+    "theme_icon.ts",
+  ]
+
   deps = [
-    ":browser_proxy",
-    ":customize_themes",
-    ":theme_icon",
+    "//third_party/polymer/v3_0:library",
+    "//ui/webui/resources:library",
+    "//ui/webui/resources/mojo:library",
+  ]
+  extra_deps = [
+    ":copy_mojom",
+    ":preprocess_generated",
+    ":preprocess_src",
   ]
 }
 
-js_library("customize_themes") {
-  deps = [
-    ":browser_proxy",
-    ":mojom_webui_js",
-    ":theme_icon",
-    "//skia/public/mojom:mojom_webui_js",
-    "//third_party/polymer/v3_0/components-chromium/paper-tooltip:paper-tooltip",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/cr_components/managed_dialog",
-    "//ui/webui/resources/cr_elements/cr_grid",
-    "//ui/webui/resources/js:i18n_behavior.m",
+preprocess_if_expr("preprocess_src") {
+  in_folder = "./"
+  out_folder = preprocess_folder_tmp
+  in_files = [ "browser_proxy.ts" ]
+}
+
+preprocess_if_expr("preprocess_generated") {
+  deps = [ ":web_components_local" ]
+  in_folder = target_gen_dir
+  out_folder = preprocess_folder_tmp
+  in_files = [
+    "customize_themes.ts",
+    "theme_icon.ts",
   ]
 }
 
-js_library("theme_icon") {
-  deps = [
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
+copy("copy_mojom") {
+  deps = [ ":mojom_webui_js" ]
+  sources = [ "$root_gen_dir/mojom-webui/ui/webui/resources/cr_components/customize_themes/customize_themes.mojom-webui.js" ]
+  outputs = [ "$preprocess_folder_tmp/{{source_file_part}}" ]
 }
 
-js_library("browser_proxy") {
-  deps = [
-    ":mojom_webui_js",
-    "//ui/webui/resources/js:cr.m",
+generate_grd("build_grdp") {
+  grd_prefix = "cr_components_customize_themes"
+  out_grd = "$target_gen_dir/resources.grdp"
+  input_files_base_dir = rebase_path(".", "//")
+  input_files = [
+    "colorize.svg",
+    "brush.svg",
   ]
+  deps = [ ":build_ts" ]
+  manifest_files = [ "$target_gen_dir/tsconfig.manifest" ]
+  resource_path_prefix = "cr_components/customize_themes"
 }
diff --git a/ui/webui/resources/cr_components/customize_themes/browser_proxy.js b/ui/webui/resources/cr_components/customize_themes/browser_proxy.js
deleted file mode 100644
index ae7a46b..0000000
--- a/ui/webui/resources/cr_components/customize_themes/browser_proxy.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview A helper object used by the customize-themes component to
- * interact with the browser.
- */
-
-import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
-
-import {CustomizeThemesClientCallbackRouter, CustomizeThemesHandlerFactory, CustomizeThemesHandlerFactoryRemote, CustomizeThemesHandlerInterface, CustomizeThemesHandlerRemote} from './customize_themes.mojom-webui.js';
-
-/** @interface */
-export class CustomizeThemesBrowserProxy {
-  /** @return {CustomizeThemesHandlerInterface} */
-  handler() {}
-
-  /** @return {CustomizeThemesClientCallbackRouter} */
-  callbackRouter() {}
-
-  /** @param {string} url */
-  open(url) {}
-}
-
-/** @implements {CustomizeThemesBrowserProxy} */
-export class CustomizeThemesBrowserProxyImpl {
-  constructor() {
-    /** @private {!CustomizeThemesHandlerRemote} */
-    this.handler_ = new CustomizeThemesHandlerRemote();
-
-    /** @private {!CustomizeThemesClientCallbackRouter} */
-    this.callbackRouter_ = new CustomizeThemesClientCallbackRouter();
-
-    /** @type {!CustomizeThemesHandlerFactoryRemote} */
-    const factory = CustomizeThemesHandlerFactory.getRemote();
-    factory.createCustomizeThemesHandler(
-        this.callbackRouter_.$.bindNewPipeAndPassRemote(),
-        this.handler_.$.bindNewPipeAndPassReceiver());
-  }
-
-  /** @override */
-  handler() {
-    return this.handler_;
-  }
-
-  /** @override */
-  callbackRouter() {
-    return this.callbackRouter_;
-  }
-
-  /** @override */
-  open(url) {
-    window.open(url, '_blank');
-  }
-}
-
-addSingletonGetter(CustomizeThemesBrowserProxyImpl);
diff --git a/ui/webui/resources/cr_components/customize_themes/browser_proxy.ts b/ui/webui/resources/cr_components/customize_themes/browser_proxy.ts
new file mode 100644
index 0000000..a4bd7a8
--- /dev/null
+++ b/ui/webui/resources/cr_components/customize_themes/browser_proxy.ts
@@ -0,0 +1,55 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview A helper object used by the customize-themes component to
+ * interact with the browser.
+ */
+
+import {CustomizeThemesClientCallbackRouter, CustomizeThemesHandlerFactory, CustomizeThemesHandlerRemote} from './customize_themes.mojom-webui.js';
+
+export interface CustomizeThemesBrowserProxy {
+  handler(): CustomizeThemesHandlerRemote;
+  callbackRouter(): CustomizeThemesClientCallbackRouter;
+  open(url: string): void;
+}
+
+export class CustomizeThemesBrowserProxyImpl implements
+    CustomizeThemesBrowserProxy {
+  private handler_: CustomizeThemesHandlerRemote;
+  private callbackRouter_: CustomizeThemesClientCallbackRouter;
+
+  constructor() {
+    this.handler_ = new CustomizeThemesHandlerRemote();
+
+    this.callbackRouter_ = new CustomizeThemesClientCallbackRouter();
+
+    const factory = CustomizeThemesHandlerFactory.getRemote();
+    factory.createCustomizeThemesHandler(
+        this.callbackRouter_.$.bindNewPipeAndPassRemote(),
+        this.handler_.$.bindNewPipeAndPassReceiver());
+  }
+
+  handler() {
+    return this.handler_;
+  }
+
+  callbackRouter() {
+    return this.callbackRouter_;
+  }
+
+  open(url: string) {
+    window.open(url, '_blank');
+  }
+
+  static getInstance(): CustomizeThemesBrowserProxy {
+    return instance || (instance = new CustomizeThemesBrowserProxyImpl());
+  }
+
+  static setInstance(obj: CustomizeThemesBrowserProxy) {
+    instance = obj;
+  }
+}
+
+let instance: CustomizeThemesBrowserProxy|null = null;
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.js b/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
similarity index 71%
rename from ui/webui/resources/cr_components/customize_themes/customize_themes.js
rename to ui/webui/resources/cr_components/customize_themes/customize_themes.ts
index c6267cf..3e2103c 100644
--- a/ui/webui/resources/cr_components/customize_themes/customize_themes.js
+++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
@@ -13,6 +13,7 @@
 import '//resources/polymer/v3_0/paper-tooltip/paper-tooltip.js';
 
 import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
+import {DomRepeat} from 'chrome://resources/polymer/v3_0/polymer/lib/elements/dom-repeat.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {assert} from '../../js/assert.m.js';
@@ -21,27 +22,33 @@
 
 import {CustomizeThemesBrowserProxyImpl} from './browser_proxy.js';
 import {ChromeTheme, CustomizeThemesClientCallbackRouter, CustomizeThemesHandlerRemote, Theme, ThemeType} from './customize_themes.mojom-webui.js';
+import {ThemeIconElement} from './theme_icon.js';
+
+export interface CustomizeThemesElement {
+  $: {
+    autogeneratedTheme: ThemeIconElement,
+    colorPicker: HTMLElement,
+    colorPickerIcon: HTMLElement,
+    themes: DomRepeat,
+  };
+}
+
+const CustomizeThemesElementBase =
+    mixinBehaviors([I18nBehavior], PolymerElement) as
+    {new (): PolymerElement & I18nBehavior};
 
 /**
  * Element that lets the user configure the autogenerated theme.
- * @polymer
- * @extends {PolymerElement}
  */
-export class CustomizeThemesElement extends mixinBehaviors
-([I18nBehavior], PolymerElement) {
+export class CustomizeThemesElement extends CustomizeThemesElementBase {
   static get is() {
     return 'cr-customize-themes';
   }
 
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
   static get properties() {
     return {
       /**
        * An object describing the currently selected theme.
-       * @type {?Theme}
        */
       selectedTheme: {
         type: Object,
@@ -54,17 +61,14 @@
        * If false, confirmThemeChanges() should be called after applying a theme
        * to permanently apply the change. Otherwise, theme changes are confirmed
        * automatically.
-       * @type {Boolean}
        */
       autoConfirmThemeChanges: {
         type: Boolean,
         value: false,
       },
 
-      /** @private {!Array<!ChromeTheme>} */
       chromeThemes_: Array,
 
-      /** @private */
       showManagedThemeDialog_: {
         type: Boolean,
         value: false,
@@ -72,20 +76,17 @@
     };
   }
 
-  constructor() {
-    super();
-    /** @private {CustomizeThemesHandlerRemote} */
-    this.handler_ = CustomizeThemesBrowserProxyImpl.getInstance().handler();
+  selectedTheme: Theme|null;
+  autoConfirmThemeChanges: boolean;
+  private chromeThemes_: Array<ChromeTheme>;
+  private showManagedThemeDialog_: boolean;
 
-    /** @private {CustomizeThemesClientCallbackRouter} */
-    this.callbackRouter_ =
-        CustomizeThemesBrowserProxyImpl.getInstance().callbackRouter();
+  private handler_: CustomizeThemesHandlerRemote =
+      CustomizeThemesBrowserProxyImpl.getInstance().handler();
+  private callbackRouter_: CustomizeThemesClientCallbackRouter =
+      CustomizeThemesBrowserProxyImpl.getInstance().callbackRouter();
+  private setThemeListenerId_: number|null = null;
 
-    /** @private {?number} */
-    this.setThemeListenerId_ = null;
-  }
-
-  /** @override */
   connectedCallback() {
     super.connectedCallback();
     this.handler_.initializeTheme();
@@ -94,15 +95,14 @@
     });
 
     this.setThemeListenerId_ =
-        this.callbackRouter_.setTheme.addListener(theme => {
+        this.callbackRouter_.setTheme.addListener((theme: Theme) => {
           this.selectedTheme = theme;
         });
   }
 
-  /** @override */
   disconnectedCallback() {
     this.revertThemeChanges();
-    this.callbackRouter_.removeListener(assert(this.setThemeListenerId_));
+    this.callbackRouter_.removeListener(assert(this.setThemeListenerId_!));
     super.disconnectedCallback();
   }
 
@@ -114,19 +114,15 @@
     this.handler_.revertThemeChanges();
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onCustomFrameColorChange_(e) {
-    this.handler_.applyAutogeneratedTheme(hexColorToSkColor(e.target.value));
+  private onCustomFrameColorChange_(e: Event) {
+    this.handler_.applyAutogeneratedTheme(
+        hexColorToSkColor((e.target as HTMLInputElement).value));
     if (this.autoConfirmThemeChanges) {
       this.handler_.confirmThemeChanges();
     }
   }
 
-  /** @private */
-  onAutogeneratedThemeClick_() {
+  private onAutogeneratedThemeClick_() {
     if (this.isForcedTheme_()) {
       // If the applied theme is managed, show a dialog to inform the user.
       this.showManagedThemeDialog_ = true;
@@ -135,8 +131,7 @@
     this.$.colorPicker.click();
   }
 
-  /** @private */
-  onDefaultThemeClick_() {
+  private onDefaultThemeClick_() {
     if (this.isForcedTheme_()) {
       // If the applied theme is managed, show a dialog to inform the user.
       this.showManagedThemeDialog_ = true;
@@ -148,32 +143,28 @@
     }
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onChromeThemeClick_(e) {
+  private onChromeThemeClick_(e: Event) {
     if (this.isForcedTheme_()) {
       // If the applied theme is managed, show a dialog to inform the user.
       this.showManagedThemeDialog_ = true;
       return;
     }
-    this.handler_.applyChromeTheme(this.$.themes.itemForElement(e.target).id);
+    this.handler_.applyChromeTheme(
+        this.$.themes.itemForElement((e.target as HTMLElement)).id);
     if (this.autoConfirmThemeChanges) {
       this.handler_.confirmThemeChanges();
     }
   }
 
-  /** @private */
-  onThemeChange_() {
+  private onThemeChange_() {
     if (!this.selectedTheme ||
         this.selectedTheme.type !== ThemeType.kAutogenerated) {
       return;
     }
     const rgbaFrameColor =
-        skColorToRgba(this.selectedTheme.info.autogeneratedThemeColors.frame);
+        skColorToRgba(this.selectedTheme.info.autogeneratedThemeColors!.frame);
     const rgbaActiveTabColor = skColorToRgba(
-        this.selectedTheme.info.autogeneratedThemeColors.activeTab);
+        this.selectedTheme.info.autogeneratedThemeColors!.activeTab);
     this.$.autogeneratedTheme.style.setProperty(
         '--cr-theme-icon-frame-color', rgbaFrameColor);
     this.$.autogeneratedTheme.style.setProperty(
@@ -183,31 +174,21 @@
     this.$.colorPickerIcon.style.setProperty(
         'background-color',
         skColorToRgba(
-            this.selectedTheme.info.autogeneratedThemeColors.activeTabText));
+            this.selectedTheme.info.autogeneratedThemeColors!.activeTabText));
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onUninstallThirdPartyThemeClick_(e) {
+  private onUninstallThirdPartyThemeClick_() {
     this.handler_.applyDefaultTheme();
     this.handler_.confirmThemeChanges();
   }
 
-  /** @private */
-  onThirdPartyLinkButtonClick_() {
+  private onThirdPartyLinkButtonClick_() {
     CustomizeThemesBrowserProxyImpl.getInstance().open(
         `https://chrome.google.com/webstore/detail/${
-            this.selectedTheme.info.thirdPartyThemeInfo.id}`);
+            this.selectedTheme!.info.thirdPartyThemeInfo!.id}`);
   }
 
-  /**
-   * @param {string|number} id
-   * @return {boolean}
-   * @private
-   */
-  isThemeIconSelected_(id) {
+  private isThemeIconSelected_(id: string|number): boolean {
     if (!this.selectedTheme) {
       return false;
     }
@@ -221,12 +202,7 @@
     }
   }
 
-  /**
-   * @param {string|number} id
-   * @return {string}
-   * @private
-   */
-  getTabIndex_(id) {
+  private getTabIndex_(id: string|number): string {
     if (!this.selectedTheme ||
         this.selectedTheme.type === ThemeType.kThirdParty) {
       return id === 'autogenerated' ? '0' : '-1';
@@ -235,45 +211,30 @@
     return this.isThemeIconSelected_(id) ? '0' : '-1';
   }
 
-  /**
-   * @param {string|number} id
-   * @return {string}
-   * @private
-   */
-  getThemeIconCheckedStatus_(id) {
+  private getThemeIconCheckedStatus_(id: string|number): string {
     return this.isThemeIconSelected_(id) ? 'true' : 'false';
   }
 
-  /**
-   * @return {boolean}
-   * @private
-   */
-  isThirdPartyTheme_() {
+  private isThirdPartyTheme_(): boolean {
     return !!this.selectedTheme &&
         this.selectedTheme.type === ThemeType.kThirdParty;
   }
 
-  /**
-   * @return {boolean}
-   * @private
-   */
-  isForcedTheme_() {
+  private isForcedTheme_(): boolean {
     return !!this.selectedTheme && this.selectedTheme.isForced;
   }
 
-  /**
-   * @param {SkColor} skColor
-   * @return {string}
-   * @private
-   */
-  skColorToRgba_(skColor) {
+  private skColorToRgba_(skColor: SkColor): string {
     return skColorToRgba(skColor);
   }
 
-  /** @private */
-  onManagedDialogClosed_() {
+  private onManagedDialogClosed_() {
     this.showManagedThemeDialog_ = false;
   }
+
+  static get template() {
+    return html`{__html_template__}`;
+  }
 }
 
 customElements.define(CustomizeThemesElement.is, CustomizeThemesElement);
diff --git a/ui/webui/resources/cr_components/customize_themes/theme_icon.js b/ui/webui/resources/cr_components/customize_themes/theme_icon.ts
similarity index 100%
rename from ui/webui/resources/cr_components/customize_themes/theme_icon.js
rename to ui/webui/resources/cr_components/customize_themes/theme_icon.ts
diff --git a/ui/webui/resources/cr_components/customize_themes/tsconfig_base.json b/ui/webui/resources/cr_components/customize_themes/tsconfig_base.json
new file mode 100644
index 0000000..3f69ccee
--- /dev/null
+++ b/ui/webui/resources/cr_components/customize_themes/tsconfig_base.json
@@ -0,0 +1,9 @@
+{
+  "extends": "../../../../../tools/typescript/tsconfig_base.json",
+  "compilerOptions": {
+    "allowJs": true,
+    "noUncheckedIndexedAccess": false,
+    "noUnusedLocals": false,
+    "strictPropertyInitialization": false
+  }
+}
diff --git a/ui/webui/resources/mojo/BUILD.gn b/ui/webui/resources/mojo/BUILD.gn
index 6da3352..09b336e 100644
--- a/ui/webui/resources/mojo/BUILD.gn
+++ b/ui/webui/resources/mojo/BUILD.gn
@@ -16,11 +16,13 @@
     "mojo/public/mojom/base/big_buffer.mojom-webui.js",
     "mojo/public/mojom/base/string16.mojom-webui.js",
     "mojo/public/mojom/base/time.mojom-webui.js",
+    "skia/public/mojom/skcolor.mojom-webui.js",
     "url/mojom/url.mojom-webui.js",
   ]
 
   extra_deps = [
     "//mojo/public/mojom/base:base_js__generator",
+    "//skia/public/mojom:mojom_js__generator",
     "//url/mojom:url_mojom_gurl_js__generator",
   ]
 }