diff --git a/DEPS b/DEPS
index 20b65ff4..98253ef 100644
--- a/DEPS
+++ b/DEPS
@@ -194,7 +194,7 @@
   'dawn_standalone': False,
 
   # reclient CIPD package version
-  'reclient_version': 're_client_version:0.29.0.83d9585',
+  'reclient_version': 're_client_version:0.31.0.caaa265',
 
   'android_git': 'https://android.googlesource.com',
   'aomedia_git': 'https://aomedia.googlesource.com',
@@ -209,11 +209,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': '491f412c944fe78611e5591c97c3270816e19b8c',
+  'skia_revision': '12eb0ee65c328f9fc98baf56528d134338025da0',
   # 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': '808bb34a575274543a9cf6a9fba9dc275dbb5721',
+  'v8_revision': '0fca2670052f229eb7f634d53cb0f0daa042bcbb',
   # 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.
@@ -221,7 +221,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '6c328417207e7081af29536c1286e95bd5b108b0',
+  'angle_revision': 'c072daec5ffb06580e4bf45500a8b2d802d09ee2',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -280,7 +280,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': '12d96cda9ccc11826cce0a6390cc55576838e6ce',
+  'catapult_revision': '26af1f63b6cbcb76d5a7045d6c1ea71f651cbdae',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -288,7 +288,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': 'cb880dd6f2dc2baf34d1d9a96b34aab95276add4',
+  'devtools_frontend_revision': '287be69dde16b717a964ddac62fec207c0b85548',
   # 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.
@@ -966,7 +966,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '424504a1b2e7c201af9b9dd1084537add80b8a2a',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '30cde45e06283ef80e0b5ce970cd5da9509cc0e8',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1349,7 +1349,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '0d6614b33d5318efd97120182405c700a25cb5ae',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'd53f42ae593851c3d4762dd4dd8ba49be17c52ed',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1547,7 +1547,7 @@
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '22ba62ffe79c3881581ab430368bf3764d9533eb',
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@3f59a9b275fbae45d3388732b2345c112a1e0a45',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@83d509240cca255b5917bcb869f1d03e6325eb14',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '732a76d9d3c70d6aa487216495eeb28518349c3a',
@@ -1571,7 +1571,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a0b8774ce8cec1dc8f4308810bf05eb8867c62de',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '43c0f51e87ddec8a014a48428e485b07a3be46f2',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '7c0e4f92088f8230bd63a81b9b924fb9dadc5be8',
 
   'src/third_party/webrtc':
     Var('webrtc_git') + '/src.git' + '@' + '376cf07ea25449cb41eef33457cddbcc197cb5ce',
@@ -1635,7 +1635,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d5fd0064dc78163ea8405b0b95589a5dd65d440e',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9cfcb47ec4fa1b1c4af7d77dc8ed485f7dd1a0a9',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java
index 7be8e47..b7d5a686 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
 
@@ -188,6 +189,8 @@
      */
     @GuardedBy("mLock")
     private void sendToServiceLocked(HistogramRecord record) {
+        // Clear the calling identity for cases when this is called locally in the same process.
+        long token = Binder.clearCallingIdentity();
         try {
             // We are not punting this to a background thread since the cost of IPC itself
             // should be relatively cheap, and the remote method does its work
@@ -195,6 +198,8 @@
             mServiceStub.recordMetrics(record.toByteArray());
         } catch (RemoteException e) {
             Log.e(TAG, "Remote Exception calling IMetricsBridgeService#recordMetrics", e);
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
diff --git a/ash/app_list/PRESUBMIT.py b/ash/app_list/PRESUBMIT.py
index 0ab4eb6..67cf3ecc 100644
--- a/ash/app_list/PRESUBMIT.py
+++ b/ash/app_list/PRESUBMIT.py
@@ -8,6 +8,8 @@
 for more details about the presubmit API built into depot_tools.
 """
 
+USE_PYTHON3 = True
+
 INCLUDE_CPP_FILES_ONLY = (
   r'.*\.(cc|h)$',
 )
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h
index 5dc94427b..cdea1c3 100644
--- a/ash/app_list/app_list_controller_impl.h
+++ b/ash/app_list/app_list_controller_impl.h
@@ -198,7 +198,6 @@
   void ViewShown(int64_t display_id) override;
   bool AppListTargetVisibility() const override;
   void ViewClosing() override;
-  void ViewClosed() override {}
   const std::vector<SkColor>& GetWallpaperProminentColors() override;
   void ActivateItem(const std::string& id,
                     int event_flags,
diff --git a/ash/app_list/app_list_presenter_impl.cc b/ash/app_list/app_list_presenter_impl.cc
index af049ec5..534693d 100644
--- a/ash/app_list/app_list_presenter_impl.cc
+++ b/ash/app_list/app_list_presenter_impl.cc
@@ -482,7 +482,6 @@
 void AppListPresenterImpl::OnClosed() {
   if (!is_target_visibility_show_)
     shelf_observation_.RemoveAllObservations();
-  controller_->ViewClosed();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ash/app_list/app_list_test_view_delegate.h b/ash/app_list/app_list_test_view_delegate.h
index af81384e..327f2c48 100644
--- a/ash/app_list/app_list_test_view_delegate.h
+++ b/ash/app_list/app_list_test_view_delegate.h
@@ -78,7 +78,6 @@
   void ViewShown(int64_t display_id) override {}
   void DismissAppList() override;
   void ViewClosing() override {}
-  void ViewClosed() override {}
   const std::vector<SkColor>& GetWallpaperProminentColors() override;
   void ActivateItem(const std::string& id,
                     int event_flags,
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h
index e43db59..2c9a5f3 100644
--- a/ash/app_list/app_list_view_delegate.h
+++ b/ash/app_list/app_list_view_delegate.h
@@ -101,9 +101,6 @@
   // Invoked when the app list is closing.
   virtual void ViewClosing() = 0;
 
-  // Invoked when the app list is closed.
-  virtual void ViewClosed() = 0;
-
   // Gets the wallpaper prominent colors.
   virtual const std::vector<SkColor>& GetWallpaperProminentColors() = 0;
 
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
index 358c6446..182553e9 100644
--- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc
+++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -2957,7 +2957,7 @@
 
   trace_analyzer::Start("*");
   {
-    trace_event::BlameContext blame_context("cat", "name", "type", "scope", 0,
+    trace_event::BlameContext blame_context("base", "name", "type", "scope", 0,
                                             nullptr);
     blame_context.Initialize();
     queue->SetBlameContext(&blame_context);
diff --git a/base/test/trace_test_utils.cc b/base/test/trace_test_utils.cc
index 374a99f..bb69658a 100644
--- a/base/test/trace_test_utils.cc
+++ b/base/test/trace_test_utils.cc
@@ -7,6 +7,7 @@
 #include "base/sequenced_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/tracing/perfetto_platform.h"
+#include "third_party/perfetto/include/perfetto/tracing.h"
 
 namespace base {
 namespace test {
@@ -66,11 +67,25 @@
 
 }  // namespace
 
+TracingEnvironment::TracingEnvironment() {
+  if (perfetto::Tracing::IsInitialized())
+    return;
+  static tracing::PerfettoPlatform perfetto_platform(
+      tracing::PerfettoPlatform::TaskRunnerType::kBuiltin);
+  perfetto::TracingInitArgs init_args;
+  init_args.backends = perfetto::BackendType::kInProcessBackend;
+  init_args.platform = &perfetto_platform;
+  perfetto::Tracing::Initialize(init_args);
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  perfetto::TrackEvent::Register();
+#endif
+}
+
 TracingEnvironment::TracingEnvironment(
     TaskEnvironment& task_environment,
     scoped_refptr<SequencedTaskRunner> task_runner,
     tracing::PerfettoPlatform* perfetto_platform)
-    : task_environment_(task_environment) {
+    : task_environment_(&task_environment) {
   // Since Perfetto's platform backend can only be initialized once in a
   // process, we give it a task runner that can outlive the per-test task
   // environment.
@@ -80,12 +95,26 @@
   client_lib_task_runner->set_task_runner(std::move(task_runner));
 
   // Wait for any posted construction tasks to execute.
-  task_environment_.RunUntilIdle();
+  task_environment_->RunUntilIdle();
 }
 
 TracingEnvironment::~TracingEnvironment() {
-  // Wait for any posted destruction tasks to execute.
-  task_environment_.RunUntilIdle();
+  if (task_environment_) {
+    // Wait for any posted destruction tasks to execute.
+    task_environment_->RunUntilIdle();
+  }
+}
+
+// static
+perfetto::protos::gen::TraceConfig TracingEnvironment::GetDefaultTraceConfig() {
+  perfetto::protos::gen::TraceConfig trace_config;
+  auto* buffer_config = trace_config.add_buffers();
+  buffer_config->set_size_kb(1024 * 1024);
+  auto* data_source = trace_config.add_data_sources();
+  auto* source_config = data_source->mutable_config();
+  source_config->set_name("track_event");
+  source_config->set_target_buffer(0);
+  return trace_config;
 }
 
 }  // namespace test
diff --git a/base/test/trace_test_utils.h b/base/test/trace_test_utils.h
index 39bba71..0d224ce 100644
--- a/base/test/trace_test_utils.h
+++ b/base/test/trace_test_utils.h
@@ -8,6 +8,7 @@
 #include "base/task/thread_pool.h"
 #include "base/test/task_environment.h"
 #include "base/trace_event/trace_log.h"
+#include "third_party/perfetto/protos/perfetto/config/trace_config.gen.h"
 
 namespace base {
 namespace tracing {
@@ -21,14 +22,23 @@
 // //services/tracing for recording traces in multiprocess configurations.
 class TracingEnvironment {
  public:
+  // Construct a tracing environment using the default Perfetto tracing
+  // platform.
+  TracingEnvironment();
+
+  // Constructs a tracing environment with the given task runner and Perfetto
+  // tracing platform.
   explicit TracingEnvironment(TaskEnvironment&,
                               scoped_refptr<SequencedTaskRunner> =
                                   ThreadPool::CreateSequencedTaskRunner({}),
                               base::tracing::PerfettoPlatform* = nullptr);
   ~TracingEnvironment();
 
+  // Builds a default Perfetto trace config with track events enabled.
+  static perfetto::protos::gen::TraceConfig GetDefaultTraceConfig();
+
  private:
-  TaskEnvironment& task_environment_;
+  TaskEnvironment* task_environment_ = nullptr;
 };
 
 }  // namespace test
diff --git a/base/trace_event/blame_context_unittest.cc b/base/trace_event/blame_context_unittest.cc
index 00768f2..0769e8d 100644
--- a/base/trace_event/blame_context_unittest.cc
+++ b/base/trace_event/blame_context_unittest.cc
@@ -14,8 +14,8 @@
 namespace trace_event {
 namespace {
 
-const char kTestBlameContextCategory[] = "test";
-const char kDisabledTestBlameContextCategory[] = "disabled-by-default-test";
+const char kTestBlameContextCategory[] = "base";
+const char kDisabledTestBlameContextCategory[] = "disabled-by-default-base";
 const char kTestBlameContextName[] = "TestBlameContext";
 const char kTestBlameContextType[] = "TestBlameContextType";
 const char kTestBlameContextScope[] = "TestBlameContextScope";
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
index 4b990db1b..c0bcfbab 100644
--- a/base/trace_event/builtin_categories.h
+++ b/base/trace_event/builtin_categories.h
@@ -392,20 +392,12 @@
  public:
   // Returns a built-in category name at |index| in the registry.
   static constexpr const char* At(size_t index) {
-#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
-    return perfetto::internal::kCategories[index].name;
-#else
     return kBuiltinCategories[index];
-#endif
   }
 
   // Returns the amount of built-in categories in the registry.
   static constexpr size_t Size() {
-#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
-    return perfetto::internal::kCategoryCount;
-#else
     return base::size(kBuiltinCategories);
-#endif
   }
 
   // Where in the builtin category list to start when populating the
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
index b05d263a..96bc1e5c 100644
--- a/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
+++ b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
@@ -19,6 +19,9 @@
 namespace base {
 namespace trace_event {
 
+// Pseudostack-based heap profiling isn't supported with Perfetto.
+#if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+
 // Define all strings once, because the pseudo stack requires pointer equality,
 // and string interning is unreliable.
 const char kThreadName[] = "TestThread";
@@ -347,5 +350,7 @@
                    ->GetContextSnapshot(&ctx));
 }
 
+#endif  // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+
 }  // namespace trace_event
 }  // namespace base
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
index 6b0dc41..cbabbc9 100644
--- a/base/trace_event/trace_log.cc
+++ b/base/trace_event/trace_log.cc
@@ -297,6 +297,23 @@
         WriteDebugAnnotations(trace_event, ctx.event());
         auto* legacy_event = ctx.event()->set_legacy_event();
         legacy_event->set_phase(trace_event->phase());
+        uint32_t id_flags =
+            trace_event->flags() &
+            (TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_HAS_LOCAL_ID |
+             TRACE_EVENT_FLAG_HAS_GLOBAL_ID);
+        switch (id_flags) {
+          case TRACE_EVENT_FLAG_HAS_ID:
+            legacy_event->set_unscoped_id(trace_event->id());
+            break;
+          case TRACE_EVENT_FLAG_HAS_LOCAL_ID:
+            legacy_event->set_local_id(trace_event->id());
+            break;
+          case TRACE_EVENT_FLAG_HAS_GLOBAL_ID:
+            legacy_event->set_global_id(trace_event->id());
+            break;
+          default:
+            break;
+        }
       });
 }
 #endif  // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
diff --git a/base/trace_event/typed_macros_unittest.cc b/base/trace_event/typed_macros_unittest.cc
index 89b0f965..08b446a 100644
--- a/base/trace_event/typed_macros_unittest.cc
+++ b/base/trace_event/typed_macros_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/location.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/test/trace_test_utils.h"
 #include "base/trace_event/interned_args_helper.h"
 #include "base/trace_event/trace_log.h"
 #include "base/trace_event/typed_macros_embedder_support.h"
@@ -14,17 +15,38 @@
 #include "third_party/perfetto/include/perfetto/protozero/scattered_heap_buffer.h"
 #include "third_party/perfetto/include/perfetto/tracing/track_event_interned_data_index.h"
 #include "third_party/perfetto/protos/perfetto/trace/interned_data/interned_data.pb.h"
+#include "third_party/perfetto/protos/perfetto/trace/trace.pb.h"
 #include "third_party/perfetto/protos/perfetto/trace/track_event/log_message.pbzero.h"
 #include "third_party/perfetto/protos/perfetto/trace/track_event/source_location.pb.h"
 #include "third_party/perfetto/protos/perfetto/trace/track_event/source_location.pbzero.h"
 
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+#include "base/tracing/perfetto_platform.h"
+#endif
+
 namespace base {
 namespace trace_event {
 
 namespace {
 
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+std::unique_ptr<perfetto::TracingSession> g_tracing_session;
+#else
 constexpr const char kRecordAllCategoryFilter[] = "*";
+#endif
 
+void EnableTrace() {
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  g_tracing_session = perfetto::Tracing::NewTrace();
+  g_tracing_session->Setup(test::TracingEnvironment::GetDefaultTraceConfig());
+  g_tracing_session->StartBlocking();
+#else   // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
+                                      TraceLog::RECORDING_MODE);
+#endif  // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+}
+
+#if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
 void CancelTraceAsync(WaitableEvent* flush_complete_event) {
   TraceLog::GetInstance()->CancelTracing(base::BindRepeating(
       [](WaitableEvent* complete_event,
@@ -34,12 +56,17 @@
       },
       base::Unretained(flush_complete_event)));
 }
+#endif  // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
 
 void CancelTrace() {
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  g_tracing_session.reset();
+#else  // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
   WaitableEvent flush_complete_event(WaitableEvent::ResetPolicy::AUTOMATIC,
                                      WaitableEvent::InitialState::NOT_SIGNALED);
   CancelTraceAsync(&flush_complete_event);
   flush_complete_event.Wait();
+#endif
 }
 
 struct TestTrackEvent;
@@ -113,7 +140,40 @@
 
   ~TypedTraceEventTest() override { ResetTypedTraceEventsForTesting(); }
 
+  void FlushTrace() {
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+    perfetto::TrackEvent::Flush();
+    g_tracing_session->StopBlocking();
+    std::vector<char> serialized_data = g_tracing_session->ReadTraceBlocking();
+    perfetto::protos::Trace trace;
+    EXPECT_TRUE(
+        trace.ParseFromArray(serialized_data.data(), serialized_data.size()));
+    for (const auto& packet : trace.packet()) {
+      if (packet.has_track_event()) {
+        std::string serialized_event = packet.track_event().SerializeAsString();
+        event_.prepare_called = true;
+        event_.event->AppendRawProtoBytes(serialized_event.data(),
+                                          serialized_event.size());
+        event_.OnTrackEventCompleted();
+
+        std::string serialized_interned_data =
+            packet.interned_data().SerializeAsString();
+        event_.incremental_state.serialized_interned_data->AppendRawProtoBytes(
+            serialized_interned_data.data(), serialized_interned_data.size());
+
+        std::string serialized_packet = packet.SerializeAsString();
+        packet_.prepare_called = true;
+        packet_.packet->AppendRawProtoBytes(serialized_packet.data(),
+                                            serialized_packet.size());
+        packet_.OnTracePacketCompleted();
+        break;
+      }
+    }
+#endif  // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  }
+
   perfetto::protos::TrackEvent ParseTrackEvent() {
+    FlushTrace();
     auto serialized_data = event_.event.SerializeAsArray();
     perfetto::protos::TrackEvent track_event;
     EXPECT_TRUE(track_event.ParseFromArray(serialized_data.data(),
@@ -122,6 +182,9 @@
   }
 
  protected:
+#if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
+  test::TracingEnvironment tracing_environment_;
+#endif
   TestTrackEvent event_;
   TestTracePacket packet_;
 };
@@ -129,14 +192,16 @@
 }  // namespace
 
 TEST_F(TypedTraceEventTest, CallbackExecutedWhenTracingEnabled) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
 
-  TRACE_EVENT("cat", "Name", [this](perfetto::EventContext ctx) {
+  TRACE_EVENT("cat", "Name", [&](perfetto::EventContext ctx) {
+#if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
     EXPECT_EQ(ctx.event(), event_.event.get());
+#endif
     perfetto::protos::pbzero::LogMessage* log = ctx.event()->set_log_message();
     log->set_body_iid(1);
   });
+  FlushTrace();
 
   EXPECT_TRUE(event_.prepare_called);
   EXPECT_FALSE(event_.event.empty());
@@ -158,11 +223,11 @@
 }
 
 TEST_F(TypedTraceEventTest, DescriptorPacketWrittenForEventWithTrack) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
 
   TRACE_EVENT("cat", "Name", perfetto::Track(1234));
 
+  FlushTrace();
   EXPECT_TRUE(event_.prepare_called);
   EXPECT_FALSE(event_.event.empty());
   EXPECT_TRUE(event_.event_completed);
@@ -175,8 +240,7 @@
 }
 
 TEST_F(TypedTraceEventTest, InternedData) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
   const TraceSourceLocation location("TestFunction", "test.cc", 123);
   size_t iid = 0;
 
@@ -204,6 +268,7 @@
     size_t iid4 = InternedSourceLocation::Get(&ctx, location3);
     EXPECT_EQ(iid, iid4);
   });
+  FlushTrace();
 
   auto serialized_data =
       event_.incremental_state.serialized_interned_data.SerializeAsArray();
@@ -230,6 +295,7 @@
     EXPECT_NE(0u, iid);
     log->set_body_iid(iid);
   });
+  FlushTrace();
 
   // No new data should have been interned the second time around.
   EXPECT_EQ(
@@ -240,8 +306,7 @@
 }
 
 TEST_F(TypedTraceEventTest, InstantThreadEvent) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
 
   TRACE_EVENT_INSTANT("cat", "ThreadEvent", [](perfetto::EventContext) {});
   auto track_event = ParseTrackEvent();
@@ -251,8 +316,7 @@
 }
 
 TEST_F(TypedTraceEventTest, InstantProcessEvent) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
 
   TRACE_EVENT_INSTANT("cat", "ProcessEvent", perfetto::ProcessTrack::Current(),
                       [](perfetto::EventContext) {});
@@ -264,8 +328,7 @@
 }
 
 TEST_F(TypedTraceEventTest, InstantGlobalEvent) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
 
   TRACE_EVENT_INSTANT("cat", "GlobalEvent", perfetto::Track::Global(1234),
                       [](perfetto::EventContext) {});
@@ -277,8 +340,7 @@
 }
 
 TEST_F(TypedTraceEventTest, InstantGlobalDefaultEvent) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
 
   TRACE_EVENT_INSTANT("cat", "GlobalDefaultEvent", perfetto::Track::Global(0),
                       [](perfetto::EventContext) {});
@@ -290,8 +352,7 @@
 }
 
 TEST_F(TypedTraceEventTest, BeginEventOnDefaultTrackDoesNotWriteTrackUuid) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
 
   TRACE_EVENT_BEGIN("cat", "Name");
   auto begin_event = ParseTrackEvent();
@@ -301,8 +362,7 @@
 }
 
 TEST_F(TypedTraceEventTest, EndEventOnDefaultTrackDoesNotWriteTrackUuid) {
-  TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
-                                      TraceLog::RECORDING_MODE);
+  EnableTrace();
 
   TRACE_EVENT_END("cat");
   auto end_event = ParseTrackEvent();
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 711d5401..3dc9e9b 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-4.20210601.1.1
+4.20210601.2.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 711d5401..3dc9e9b 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-4.20210601.1.1
+4.20210601.2.1
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedStreamViewResizer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedStreamViewResizer.java
index d468c5e..f0ca17a 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedStreamViewResizer.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedStreamViewResizer.java
@@ -14,6 +14,7 @@
 import androidx.core.view.ViewCompat;
 
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
 import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
 import org.chromium.components.browser_ui.widget.displaystyle.ViewResizer;
 
@@ -65,7 +66,8 @@
     @Override
     public void onDisplayStyleChanged(UiConfig.DisplayStyle newDisplayStyle) {
         if (mUiConfig.getContext().getResources().getConfiguration().orientation
-                != Configuration.ORIENTATION_LANDSCAPE) {
+                        != Configuration.ORIENTATION_LANDSCAPE
+                || MultiWindowUtils.getInstance().isInMultiWindowMode(mActivity)) {
             super.onDisplayStyleChanged(newDisplayStyle);
             return;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/DEPS
index 39bd1ce..3cd874b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/DEPS
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DEPS
@@ -35,9 +35,6 @@
   "NavigationPopup\.java": [
     "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
   ],
-  "ServiceTabLauncher\.java": [
-    "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
-  ],
   "TabbedModeTabDelegateFactory\.java": [
     "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
   ],
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/messages/ChromeMessageQueueMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/messages/ChromeMessageQueueMediator.java
index 4e4d3f6..f37e9a70 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/messages/ChromeMessageQueueMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/messages/ChromeMessageQueueMediator.java
@@ -133,14 +133,9 @@
     public void destroy() {
         mFullscreenManager.removeObserver(mFullScreenObserver);
         mBrowserControlsManager.removeObserver(mBrowserControlsObserver);
-        if (mLayoutStateProvider != null) {
-            mLayoutStateProvider.removeObserver(mLayoutStateObserver);
-        }
-        if (mModalDialogManager != null) {
-            mModalDialogManager.removeObserver(mModalDialogManagerObserver);
-        }
+        setLayoutStateProvider(null);
+        setModalDialogManager(null);
         mActivityTabProvider = null;
-        mLayoutStateProvider = null;
         mQueueController = null;
         mContainerCoordinator = null;
         if (mBrowserControlsToken != TokenHolder.INVALID_TOKEN) {
@@ -149,7 +144,6 @@
         }
         mBrowserControlsManager = null;
         mFullscreenManager = null;
-        mModalDialogManager = null;
     }
 
     @Override
@@ -198,6 +192,12 @@
         }
         mLayoutStateProvider = layoutStateProvider;
         if (layoutStateProvider == null) return;
+        // TODO(crbug.com/1199059): The crash is possible when #setLayoutStateProvider() is called
+        // after #destroy() was called. This sequence of calls is unexpected. Below check throws an
+        // exception to help identify the caller.
+        if (mQueueController == null) {
+            throw new IllegalStateException("setLayoutStateProvider() is called after destroy()");
+        }
         mLayoutStateProvider.addObserver(mLayoutStateObserver);
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java
index e38986f8d..d233903 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetControllerTest.java
@@ -37,6 +37,7 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabLaunchType;
 import org.chromium.chrome.browser.tab.TabSelectionType;
+import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModelObserver;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
@@ -398,11 +399,11 @@
             @Override
             public void onSheetClosed(@StateChangeReason int reason) {
                 closedHelper.notifyCalled();
+                mSheetController.removeObserver(this);
             }
         });
 
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> mTestSupport.setSheetState(SheetState.HIDDEN, false));
+        ThreadUtils.runOnUiThread(() -> mTestSupport.setSheetState(SheetState.HIDDEN, false));
 
         closedHelper.waitForFirst();
 
@@ -661,14 +662,16 @@
      */
     private void openNewTabInBackground() throws TimeoutException {
         CallbackHelper tabSelectedHelper = new CallbackHelper();
-        mActivity.getTabModelSelector().getCurrentModel().addObserver(new TabModelObserver() {
+        TabModel tabModel = mActivity.getTabModelSelector().getCurrentModel();
+        tabModel.addObserver(new TabModelObserver() {
             @Override
             public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) {
                 tabSelectedHelper.notifyCalled();
+                tabModel.removeObserver(this);
             }
         });
 
-        ThreadUtils.runOnUiThreadBlocking(() -> {
+        ThreadUtils.runOnUiThread(() -> {
             mActivity.getTabCreator(false).createNewTab(new LoadUrlParams("about:blank"),
                     TabLaunchType.FROM_LONGPRESS_BACKGROUND, null);
         });
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 43fffa4..b4acb5d 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1744,8 +1744,6 @@
     "sync/glue/sync_start_util.h",
     "sync/model_type_store_service_factory.cc",
     "sync/model_type_store_service_factory.h",
-    "sync/profile_sync_service_factory.cc",
-    "sync/profile_sync_service_factory.h",
     "sync/send_tab_to_self_sync_service_factory.cc",
     "sync/send_tab_to_self_sync_service_factory.h",
     "sync/session_sync_service_factory.cc",
@@ -1760,6 +1758,8 @@
     "sync/sync_encryption_keys_tab_helper.h",
     "sync/sync_invalidations_service_factory.cc",
     "sync/sync_invalidations_service_factory.h",
+    "sync/sync_service_factory.cc",
+    "sync/sync_service_factory.h",
     "sync/sync_startup_tracker.cc",
     "sync/sync_startup_tracker.h",
     "sync/user_event_service_factory.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 18240ea..0bef22b 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4873,6 +4873,12 @@
          chrome::android::kConditionalTabStripAndroid,
          kConditionalTabStripAndroidVariations,
          "ConditioanlTabStrip")},
+
+    {"enable-quick-action-search-widget-android",
+     flag_descriptions::kQuickActionSearchWidgetAndroidName,
+     flag_descriptions::kQuickActionSearchWidgetAndroidDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kQuickActionSearchWidgetAndroid)},
+
 #endif  // OS_ANDROID
 
     {"enable-layout-ng", flag_descriptions::kEnableLayoutNGName,
diff --git a/chrome/browser/android/browsing_data/browsing_data_bridge.cc b/chrome/browser/android/browsing_data/browsing_data_bridge.cc
index 89e6bed..51357a0 100644
--- a/chrome/browser/android/browsing_data/browsing_data_bridge.cc
+++ b/chrome/browser/android/browsing_data/browsing_data_bridge.cc
@@ -29,7 +29,7 @@
 #include "chrome/browser/history/web_history_service_factory.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/channel_info.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/browsing_data/core/history_notice_utils.h"
@@ -203,7 +203,7 @@
   // The one-time notice in the dialog.
   Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile);
   browsing_data::ShouldPopupDialogAboutOtherFormsOfBrowsingHistory(
-      ProfileSyncServiceFactory::GetForProfile(profile),
+      SyncServiceFactory::GetForProfile(profile),
       WebHistoryServiceFactory::GetForProfile(profile), chrome::GetChannel(),
       base::BindOnce(&EnableDialogAboutOtherFormsOfBrowsingHistory,
                      ScopedJavaGlobalRef<jobject>(env, listener)));
diff --git a/chrome/browser/android/foreign_session_helper.cc b/chrome/browser/android/foreign_session_helper.cc
index 1ef48c4..0db9c5c 100644
--- a/chrome/browser/android/foreign_session_helper.cc
+++ b/chrome/browser/android/foreign_session_helper.cc
@@ -14,8 +14,8 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/sessions/session_restore.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/session_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/android/tab_model/tab_model.h"
 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
 #include "chrome/common/pref_names.h"
@@ -177,8 +177,7 @@
 }
 
 void ForeignSessionHelper::TriggerSessionSync(JNIEnv* env) {
-  syncer::SyncService* service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
   if (!service)
     return;
 
@@ -299,8 +298,7 @@
 void ForeignSessionHelper::SetInvalidationsForSessionsEnabled(
     JNIEnv* env,
     jboolean enabled) {
-  syncer::SyncService* service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
   if (!service)
     return;
 
diff --git a/chrome/browser/android/history/browsing_history_bridge.cc b/chrome/browser/android/history/browsing_history_bridge.cc
index eef5b783..b5a6829 100644
--- a/chrome/browser/android/history/browsing_history_bridge.cc
+++ b/chrome/browser/android/history/browsing_history_bridge.cc
@@ -16,7 +16,7 @@
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/history/core/browser/browsing_history_service.h"
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/url_formatter/url_formatter.h"
@@ -35,7 +35,7 @@
   history::HistoryService* local_history = HistoryServiceFactory::GetForProfile(
       profile_, ServiceAccessType::EXPLICIT_ACCESS);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   browsing_history_service_ = std::make_unique<BrowsingHistoryService>(
       this, local_history, sync_service);
 
diff --git a/chrome/browser/android/metrics/android_session_durations_service_factory.cc b/chrome/browser/android/metrics/android_session_durations_service_factory.cc
index ec6c5b65..53b8ba4 100644
--- a/chrome/browser/android/metrics/android_session_durations_service_factory.cc
+++ b/chrome/browser/android/metrics/android_session_durations_service_factory.cc
@@ -10,7 +10,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 namespace {
@@ -66,7 +66,7 @@
     : BrowserContextKeyedServiceFactory(
           "AndroidSessionDurationsService",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
 }
 
@@ -88,7 +88,7 @@
 
   auto* service = new AndroidSessionDurationsService();
   service->InitializeForRegularProfile(
-      ProfileSyncServiceFactory::GetForProfile(profile),
+      SyncServiceFactory::GetForProfile(profile),
       IdentityManagerFactory::GetForProfile(profile));
   return service;
 }
diff --git a/chrome/browser/android/signin/unified_consent_service_bridge.cc b/chrome/browser/android/signin/unified_consent_service_bridge.cc
index 3537c9a..4107484 100644
--- a/chrome/browser/android/signin/unified_consent_service_bridge.cc
+++ b/chrome/browser/android/signin/unified_consent_service_bridge.cc
@@ -6,7 +6,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/signin/services/android/jni_headers/UnifiedConsentServiceBridge_jni.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/unified_consent/unified_consent_service_factory.h"
 #include "components/prefs/pref_service.h"
 #include "components/sync/driver/sync_service.h"
@@ -48,7 +48,7 @@
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& profileAndroid) {
   Profile* profile = ProfileAndroid::FromProfileAndroid(profileAndroid);
-  auto* syncService = ProfileSyncServiceFactory::GetForProfile(profile);
+  auto* syncService = SyncServiceFactory::GetForProfile(profile);
   unified_consent::metrics::RecordSyncSetupDataTypesHistrogam(
       syncService->GetUserSettings(), profile->GetPrefs());
 }
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
index ee487db..0432f55 100644
--- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
+++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.h"
 #include "chrome/browser/ash/arc/tracing/arc_app_performance_tracing_uma_session.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
@@ -417,7 +417,7 @@
   }
 
   const syncer::SyncUserSettings* sync_user_settings =
-      ProfileSyncServiceFactory::GetForProfile(profile)->GetUserSettings();
+      SyncServiceFactory::GetForProfile(profile)->GetUserSettings();
 
   if (sync_user_settings->IsUsingExplicitPassphrase()) {
     VLOG(1) << "Cannot trace: User has a sync passphrase.";
diff --git a/chrome/browser/ash/login/screens/sync_consent_browsertest.cc b/chrome/browser/ash/login/screens/sync_consent_browsertest.cc
index 9a3d66d..6ea288fc 100644
--- a/chrome/browser/ash/login/screens/sync_consent_browsertest.cc
+++ b/chrome/browser/ash/login/screens/sync_consent_browsertest.cc
@@ -28,7 +28,7 @@
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/marketing_opt_in_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
@@ -69,7 +69,7 @@
 
 syncer::SyncUserSettings* GetSyncUserSettings() {
   Profile* profile = ProfileManager::GetPrimaryUserProfile();
-  return ProfileSyncServiceFactory::GetForProfile(profile)->GetUserSettings();
+  return SyncServiceFactory::GetForProfile(profile)->GetUserSettings();
 }
 
 class ConsentRecordedWaiter
diff --git a/chrome/browser/ash/login/screens/sync_consent_screen.cc b/chrome/browser/ash/login/screens/sync_consent_screen.cc
index 5fb6ee7..bac1dc9 100644
--- a/chrome/browser/ash/login/screens/sync_consent_screen.cc
+++ b/chrome/browser/ash/login/screens/sync_consent_screen.cc
@@ -16,7 +16,7 @@
 #include "chrome/browser/consent_auditor/consent_auditor_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/unified_consent/unified_consent_service_factory.h"
 #include "chrome/common/pref_names.h"
@@ -42,8 +42,8 @@
     base::TimeDelta::FromSeconds(3);
 
 syncer::SyncService* GetSyncService(Profile* profile) {
-  if (ProfileSyncServiceFactory::HasSyncService(profile))
-    return ProfileSyncServiceFactory::GetForProfile(profile);
+  if (SyncServiceFactory::HasSyncService(profile))
+    return SyncServiceFactory::GetForProfile(profile);
   return nullptr;
 }
 
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc
index ac5ae85a..f3df4bf 100644
--- a/chrome/browser/ash/login/session/user_session_manager.cc
+++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -105,7 +105,7 @@
 #include "chrome/browser/site_isolation/about_flags.h"
 #include "chrome/browser/supervised_user/child_accounts/child_account_service.h"
 #include "chrome/browser/supervised_user/child_accounts/child_account_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/app_list_client_impl.h"
 #include "chrome/browser/ui/startup/launch_mode_recorder.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
@@ -418,7 +418,7 @@
     const SyncTrustedVaultKeys& trusted_vault_keys,
     Profile* profile) {
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   if (!sync_service) {
     return;
   }
@@ -1724,7 +1724,7 @@
   quirks::QuirksManager::Get()->OnLoginCompleted();
 
   if (features::ShouldUseBrowserSyncConsent() &&
-      ProfileSyncServiceFactory::IsSyncAllowed(profile)) {
+      SyncServiceFactory::IsSyncAllowed(profile)) {
     turn_sync_on_helper_ = std::make_unique<TurnSyncOnHelper>(profile);
   }
 
diff --git a/chrome/browser/ash/login/signin/auth_error_observer.cc b/chrome/browser/ash/login/signin/auth_error_observer.cc
index fc4da71..0900b17 100644
--- a/chrome/browser/ash/login/signin/auth_error_observer.cc
+++ b/chrome/browser/ash/login/signin/auth_error_observer.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_error_controller_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/signin/public/identity_manager/consent_level.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/sync/driver/sync_service.h"
@@ -38,7 +38,7 @@
 
 void AuthErrorObserver::StartObserving() {
   syncer::SyncService* const sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   if (sync_service)
     sync_service->AddObserver(this);
 
@@ -52,7 +52,7 @@
 
 void AuthErrorObserver::Shutdown() {
   syncer::SyncService* const sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   if (sync_service)
     sync_service->RemoveObserver(this);
 
diff --git a/chrome/browser/ash/login/signin/auth_error_observer_factory.cc b/chrome/browser/ash/login/signin/auth_error_observer_factory.cc
index 14dd1d09..e1689894 100644
--- a/chrome/browser/ash/login/signin/auth_error_observer_factory.cc
+++ b/chrome/browser/ash/login/signin/auth_error_observer_factory.cc
@@ -7,7 +7,7 @@
 #include "chrome/browser/ash/login/signin/auth_error_observer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/signin_error_controller_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 namespace chromeos {
@@ -16,7 +16,7 @@
     : BrowserContextKeyedServiceFactory(
           "AuthErrorObserver",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(SigninErrorControllerFactory::GetInstance());
 }
 
diff --git a/chrome/browser/ash/login/webview_login_browsertest.cc b/chrome/browser/ash/login/webview_login_browsertest.cc
index 489ebc0..878602e 100644
--- a/chrome/browser/ash/login/webview_login_browsertest.cc
+++ b/chrome/browser/ash/login/webview_login_browsertest.cc
@@ -56,7 +56,7 @@
 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/chromeos/scoped_test_system_nss_key_slot_mixin.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/login/login_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
@@ -622,8 +622,7 @@
   test::WaitForPrimaryUserSessionStart();
 
   syncer::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
-          browser->profile());
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(browser->profile());
   syncer::TrustedVaultClient* trusted_vault_client =
       sync_service->GetSyncClientForTest()->GetTrustedVaultClient();
 
diff --git a/chrome/browser/ash/sync/turn_sync_on_helper.cc b/chrome/browser/ash/sync/turn_sync_on_helper.cc
index aefa1941..b7ac552 100644
--- a/chrome/browser/ash/sync/turn_sync_on_helper.cc
+++ b/chrome/browser/ash/sync/turn_sync_on_helper.cc
@@ -9,7 +9,7 @@
 #include "ash/constants/ash_features.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -220,7 +220,7 @@
 }
 
 syncer::SyncService* TurnSyncOnHelper::GetSyncService() {
-  return ProfileSyncServiceFactory::IsSyncAllowed(profile_)
-             ? ProfileSyncServiceFactory::GetForProfile(profile_)
+  return SyncServiceFactory::IsSyncAllowed(profile_)
+             ? SyncServiceFactory::GetForProfile(profile_)
              : nullptr;
 }
diff --git a/chrome/browser/ash/sync/turn_sync_on_helper_unittest.cc b/chrome/browser/ash/sync/turn_sync_on_helper_unittest.cc
index febe1ca..2193330 100644
--- a/chrome/browser/ash/sync/turn_sync_on_helper_unittest.cc
+++ b/chrome/browser/ash/sync/turn_sync_on_helper_unittest.cc
@@ -8,7 +8,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "components/signin/public/identity_manager/consent_level.h"
@@ -63,7 +63,7 @@
         std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile());
 
     sync_service_ = static_cast<syncer::TestSyncService*>(
-        ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+        SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
             profile(), base::BindRepeating(&BuildTestSyncService)));
     // Reset the sync service to the pre-setup state.
     sync_service_->SetFirstSetupComplete(false);
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
index 22d4908..1bb487f 100644
--- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
+++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -35,7 +35,7 @@
 #include "chrome/browser/query_tiles/tile_service_factory.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "components/history/core/browser/history_service.h"
@@ -186,10 +186,9 @@
     Profile* profile)
     : profile_(profile),
       scheme_classifier_(profile),
-      url_consent_helper_(
-          unified_consent::UrlKeyedDataCollectionConsentHelper::
-              NewPersonalizedDataCollectionConsentHelper(
-                  ProfileSyncServiceFactory::GetForProfile(profile_))),
+      url_consent_helper_(unified_consent::UrlKeyedDataCollectionConsentHelper::
+                              NewPersonalizedDataCollectionConsentHelper(
+                                  SyncServiceFactory::GetForProfile(profile_))),
       storage_partition_(nullptr),
       omnibox_triggered_feature_service_(
           std::make_unique<OmniboxTriggeredFeatureService>()) {
@@ -398,8 +397,7 @@
 }
 
 bool ChromeAutocompleteProviderClient::IsSyncActive() const {
-  syncer::SyncService* sync =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  syncer::SyncService* sync = SyncServiceFactory::GetForProfile(profile_);
   return sync && sync->IsSyncFeatureActive();
 }
 
diff --git a/chrome/browser/autofill/autofill_keyboard_accessory_adapter.cc b/chrome/browser/autofill/autofill_keyboard_accessory_adapter.cc
index e5ec011..bbb7092 100644
--- a/chrome/browser/autofill/autofill_keyboard_accessory_adapter.cc
+++ b/chrome/browser/autofill/autofill_keyboard_accessory_adapter.cc
@@ -98,10 +98,16 @@
   return controller_->GetSuggestionAt(OffsetIndexFor(row));
 }
 
-const std::u16string& AutofillKeyboardAccessoryAdapter::GetSuggestionValueAt(
+std::u16string AutofillKeyboardAccessoryAdapter::GetSuggestionMainTextAt(
     int row) const {
-  DCHECK(controller_) << "Call GetSuggestionValueAt only from its owner!";
-  return controller_->GetSuggestionValueAt(OffsetIndexFor(row));
+  DCHECK(controller_) << "Call GetSuggestionMainTextAt only from its owner!";
+  return controller_->GetSuggestionMainTextAt(OffsetIndexFor(row));
+}
+
+std::u16string AutofillKeyboardAccessoryAdapter::GetSuggestionMinorTextAt(
+    int row) const {
+  DCHECK(controller_) << "Call GetSuggestionMinorTextAt only from its owner!";
+  return controller_->GetSuggestionMinorTextAt(OffsetIndexFor(row));
 }
 
 const std::u16string& AutofillKeyboardAccessoryAdapter::GetSuggestionLabelAt(
diff --git a/chrome/browser/autofill/autofill_keyboard_accessory_adapter.h b/chrome/browser/autofill/autofill_keyboard_accessory_adapter.h
index 8ee518b0..93e9022 100644
--- a/chrome/browser/autofill/autofill_keyboard_accessory_adapter.h
+++ b/chrome/browser/autofill/autofill_keyboard_accessory_adapter.h
@@ -68,7 +68,8 @@
   void AcceptSuggestion(int index) override;
   int GetLineCount() const override;
   const autofill::Suggestion& GetSuggestionAt(int row) const override;
-  const std::u16string& GetSuggestionValueAt(int row) const override;
+  std::u16string GetSuggestionMainTextAt(int row) const override;
+  std::u16string GetSuggestionMinorTextAt(int row) const override;
   const std::u16string& GetSuggestionLabelAt(int row) const override;
   bool GetRemovalConfirmationText(int index,
                                   std::u16string* title,
diff --git a/chrome/browser/autofill/mock_autofill_popup_controller.h b/chrome/browser/autofill/mock_autofill_popup_controller.h
index 864a1056..1466d9d4 100644
--- a/chrome/browser/autofill/mock_autofill_popup_controller.h
+++ b/chrome/browser/autofill/mock_autofill_popup_controller.h
@@ -55,8 +55,12 @@
     return suggestions_[row];
   }
 
-  const std::u16string& GetSuggestionValueAt(int i) const override {
-    return suggestions_[i].value;
+  std::u16string GetSuggestionMainTextAt(int row) const override {
+    return suggestions_[row].value;
+  }
+
+  std::u16string GetSuggestionMinorTextAt(int row) const override {
+    return std::u16string();
   }
 
   const std::u16string& GetSuggestionLabelAt(int row) const override {
diff --git a/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc b/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc
index b619693..65eaac7 100644
--- a/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc
+++ b/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc
@@ -189,8 +189,10 @@
 TEST_F(ManagedBookmarkServiceTest, SwapNodes) {
   // Swap the Google bookmark with the Folder.
   std::unique_ptr<base::ListValue> updated(CreateTestTree());
-  std::unique_ptr<base::Value> removed;
-  ASSERT_TRUE(updated->Remove(0, &removed));
+  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));
 
   // These two nodes should just be swapped.
@@ -209,7 +211,7 @@
 TEST_F(ManagedBookmarkServiceTest, RemoveNode) {
   // Remove the Folder.
   std::unique_ptr<base::ListValue> updated(CreateTestTree());
-  ASSERT_TRUE(updated->Remove(1, NULL));
+  ASSERT_TRUE(updated->EraseListIter(updated->GetList().begin() + 1));
 
   const BookmarkNode* parent = managed_->managed_node();
   EXPECT_CALL(observer_, BookmarkNodeRemoved(model_, parent, 1, _, _));
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager.cc b/chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager.cc
index 43683f0..e6070832 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager.cc
@@ -22,7 +22,7 @@
 #include "chrome/browser/lifetime/browser_shutdown.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -278,7 +278,7 @@
   auto* data_types = profile_->GetPrefs()->GetList(
       browsing_data::prefs::kClearBrowsingDataOnExitList);
   if (data_types && !data_types->GetList().empty() &&
-      !ProfileSyncServiceFactory::IsSyncAllowed(profile_)) {
+      !SyncServiceFactory::IsSyncAllowed(profile_)) {
     profile_->GetPrefs()->SetBoolean(
         browsing_data::prefs::kClearBrowsingDataOnExitDeletionPending, true);
     auto* remover = profile_->GetBrowsingDataRemover();
@@ -322,7 +322,7 @@
     if (removal_settings.time_to_live_in_hours <= 0)
       continue;
 
-    if (ProfileSyncServiceFactory::IsSyncAllowed(profile_))
+    if (SyncServiceFactory::IsSyncAllowed(profile_))
       continue;
 
     auto deletion_end_time = end_time_for_testing_.value_or(
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 f8731f4a..54ff3062 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
@@ -61,7 +61,7 @@
 #include "chrome/browser/ssl/stateful_ssl_host_state_delegate_factory.h"
 #include "chrome/browser/storage/durable_storage_permission_context.h"
 #include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_features.h"
@@ -1644,7 +1644,7 @@
   RemoveAutofillTester tester(GetProfile());
   // Initialize sync service so that PersonalDatabaseHelper::server_database_
   // gets initialized:
-  ProfileSyncServiceFactory::GetForProfile(GetProfile());
+  SyncServiceFactory::GetForProfile(GetProfile());
 
   ASSERT_FALSE(tester.HasProfile());
   tester.AddProfilesAndCards();
@@ -1666,7 +1666,7 @@
   RemoveAutofillTester tester(GetProfile());
   // Initialize sync service so that PersonalDatabaseHelper::server_database_
   // gets initialized:
-  ProfileSyncServiceFactory::GetForProfile(GetProfile());
+  SyncServiceFactory::GetForProfile(GetProfile());
 
   const base::Time k32DaysOld = base::Time::Now();
   task_environment()->AdvanceClock(base::TimeDelta::FromDays(1));
@@ -1704,7 +1704,7 @@
   RemoveAutofillTester tester(GetProfile());
   // Initialize sync service so that PersonalDatabaseHelper::server_database_
   // gets initialized:
-  ProfileSyncServiceFactory::GetForProfile(GetProfile());
+  SyncServiceFactory::GetForProfile(GetProfile());
 
   ASSERT_FALSE(tester.HasProfile());
   tester.AddProfilesAndCards();
@@ -1725,7 +1725,7 @@
   RemoveAutofillTester tester(GetProfile());
   // Initialize sync service so that PersonalDatabaseHelper::server_database_
   // gets initialized:
-  ProfileSyncServiceFactory::GetForProfile(GetProfile());
+  SyncServiceFactory::GetForProfile(GetProfile());
 
   ASSERT_FALSE(tester.HasProfile());
   tester.AddProfilesAndCards();
@@ -1751,7 +1751,7 @@
   RemoveAutofillTester tester(GetProfile());
   // Initialize sync service so that PersonalDatabaseHelper::server_database_
   // gets initialized:
-  ProfileSyncServiceFactory::GetForProfile(GetProfile());
+  SyncServiceFactory::GetForProfile(GetProfile());
 
   tester.AddProfilesAndCards();
   EXPECT_FALSE(tester.HasOrigin(std::string()));
diff --git a/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc b/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
index 6a757df..bbe3758 100644
--- a/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
+++ b/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
@@ -20,7 +20,7 @@
 #include "chrome/browser/password_manager/account_password_store_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
 #include "components/browsing_data/core/counters/autofill_counter.h"
@@ -63,7 +63,7 @@
             profile, ServiceAccessType::EXPLICIT_ACCESS),
         base::BindRepeating(&GetUpdatedWebHistoryService,
                             base::Unretained(profile)),
-        ProfileSyncServiceFactory::GetForProfile(profile));
+        SyncServiceFactory::GetForProfile(profile));
   }
   if (pref_name == browsing_data::prefs::kDeleteBrowsingHistoryBasic) {
     // The history option on the basic tab doesn't use a counter.
@@ -97,7 +97,7 @@
                                             ServiceAccessType::EXPLICIT_ACCESS),
         AccountPasswordStoreFactory::GetForProfile(
             profile, ServiceAccessType::EXPLICIT_ACCESS),
-        ProfileSyncServiceFactory::GetForProfile(profile),
+        SyncServiceFactory::GetForProfile(profile),
         std::move(credential_store));
   }
 
@@ -105,7 +105,7 @@
     return std::make_unique<browsing_data::AutofillCounter>(
         WebDataServiceFactory::GetAutofillWebDataForProfile(
             profile, ServiceAccessType::EXPLICIT_ACCESS),
-        ProfileSyncServiceFactory::GetForProfile(profile));
+        SyncServiceFactory::GetForProfile(profile));
   }
 
   if (pref_name == browsing_data::prefs::kDeleteDownloadHistory) {
diff --git a/chrome/browser/browsing_data/counters/browsing_data_counter_utils.cc b/chrome/browser/browsing_data/counters/browsing_data_counter_utils.cc
index fcf31ba..61838bb 100644
--- a/chrome/browser/browsing_data/counters/browsing_data_counter_utils.cc
+++ b/chrome/browser/browsing_data/counters/browsing_data_counter_utils.cc
@@ -30,7 +30,6 @@
 #endif
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #endif
 
diff --git a/chrome/browser/browsing_data/counters/browsing_data_counter_utils_browsertest.cc b/chrome/browser/browsing_data/counters/browsing_data_counter_utils_browsertest.cc
index 3626615..43a5af7 100644
--- a/chrome/browser/browsing_data/counters/browsing_data_counter_utils_browsertest.cc
+++ b/chrome/browser/browsing_data/counters/browsing_data_counter_utils_browsertest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/browsing_data/counters/browsing_data_counter_utils.h"
 
 #include "build/chromeos_buildflags.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/browser/ui/browser.h"
@@ -37,7 +37,7 @@
   Profile* profile = browser()->profile();
 
   syncer::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(profile);
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile);
 
   sync_service->OverrideNetworkForTest(
       fake_server::CreateFakeServerHttpPostProviderFactory(
diff --git a/chrome/browser/browsing_data/counters/browsing_data_counter_utils_unittest.cc b/chrome/browser/browsing_data/counters/browsing_data_counter_utils_unittest.cc
index 573cb5c..381ceca 100644
--- a/chrome/browser/browsing_data/counters/browsing_data_counter_utils_unittest.cc
+++ b/chrome/browser/browsing_data/counters/browsing_data_counter_utils_unittest.cc
@@ -12,7 +12,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/browsing_data/counters/cache_counter.h"
 #include "chrome/browser/browsing_data/counters/signin_data_counter.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/password_manager/core/browser/test_password_store.h"
@@ -140,8 +140,8 @@
   // This counter does not really count anything; we just need a reference to
   // pass to the SigninDataResult ctor.
   browsing_data::SigninDataCounter counter(
-      password_store, nullptr,
-      ProfileSyncServiceFactory::GetForProfile(GetProfile()), nullptr);
+      password_store, nullptr, SyncServiceFactory::GetForProfile(GetProfile()),
+      nullptr);
 
   // Use a separate struct for input to make test cases easier to read after
   // auto formatting.
diff --git a/chrome/browser/browsing_data/counters/history_counter_browsertest.cc b/chrome/browser/browsing_data/counters/history_counter_browsertest.cc
index 399aee51..47f1510 100644
--- a/chrome/browser/browsing_data/counters/history_counter_browsertest.cc
+++ b/chrome/browser/browsing_data/counters/history_counter_browsertest.cc
@@ -11,7 +11,7 @@
 #include "base/run_loop.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/history/web_history_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
@@ -162,7 +162,7 @@
       GetHistoryService(),
       base::BindRepeating(&HistoryCounterTest::GetRealWebHistoryService,
                           base::Unretained(this), base::Unretained(profile)),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
 
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
@@ -210,7 +210,7 @@
       GetHistoryService(),
       base::BindRepeating(&HistoryCounterTest::GetRealWebHistoryService,
                           base::Unretained(this), base::Unretained(profile)),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
 
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
@@ -257,7 +257,7 @@
       GetHistoryService(),
       base::BindRepeating(&HistoryCounterTest::GetRealWebHistoryService,
                           base::Unretained(this), base::Unretained(profile)),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
 
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
@@ -300,7 +300,7 @@
       base::BindRepeating(&HistoryCounterTest::GetFakeWebHistoryService,
                           base::Unretained(this), base::Unretained(profile),
                           false),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
 
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
diff --git a/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc b/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
index 58fe39330..02a7060 100644
--- a/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
+++ b/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
@@ -10,7 +10,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "chrome/browser/password_manager/account_password_store_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/passwords_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -161,7 +161,7 @@
                                           ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -185,7 +185,7 @@
                                           ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
 
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
@@ -211,7 +211,7 @@
                                           ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -234,7 +234,7 @@
                                           ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -271,7 +271,7 @@
                                           ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -321,7 +321,7 @@
                                           ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      ProfileSyncServiceFactory::GetForProfile(profile));
+      SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
diff --git a/chrome/browser/browsing_data/counters/site_data_counter.cc b/chrome/browser/browsing_data/counters/site_data_counter.cc
index 506952a..99fcacc 100644
--- a/chrome/browser/browsing_data/counters/site_data_counter.cc
+++ b/chrome/browser/browsing_data/counters/site_data_counter.cc
@@ -7,7 +7,7 @@
 #include "base/bind.h"
 #include "chrome/browser/browsing_data/counters/browsing_data_counter_utils.h"
 #include "chrome/browser/browsing_data/counters/site_data_counting_helper.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/browsing_data/core/pref_names.h"
 #include "components/sync/driver/sync_service.h"
 #include "content/public/browser/browser_thread.h"
@@ -22,7 +22,7 @@
 
 SiteDataCounter::SiteDataCounter(Profile* profile)
     : profile_(profile),
-      sync_tracker_(this, ProfileSyncServiceFactory::GetForProfile(profile)) {}
+      sync_tracker_(this, SyncServiceFactory::GetForProfile(profile)) {}
 
 SiteDataCounter::~SiteDataCounter() {}
 
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index 0901a550..450df5d 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -193,6 +193,7 @@
 #include "chromeos/components/connectivity_diagnostics/connectivity_diagnostics_ui.h"
 #include "chromeos/components/diagnostics_ui/diagnostics_ui.h"
 #include "chromeos/components/diagnostics_ui/mojom/input_data_provider.mojom.h"
+#include "chromeos/components/diagnostics_ui/mojom/network_health_provider.mojom.h"
 #include "chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom.h"
 #include "chromeos/components/diagnostics_ui/mojom/system_routine_controller.mojom.h"
 #include "chromeos/components/eche_app_ui/eche_app_ui.h"
@@ -808,6 +809,12 @@
       chromeos::diagnostics::mojom::InputDataProvider,
       chromeos::DiagnosticsDialogUI>(map);
 
+  if (chromeos::features::IsNetworkingInDiagnosticsAppEnabled()) {
+    RegisterWebUIControllerInterfaceBinder<
+        chromeos::diagnostics::mojom::NetworkHealthProvider,
+        chromeos::DiagnosticsDialogUI>(map);
+  }
+
   RegisterWebUIControllerInterfaceBinder<
       chromeos::diagnostics::mojom::SystemDataProvider,
       chromeos::DiagnosticsDialogUI>(map);
diff --git a/chrome/browser/chromeos/extensions/input_method_api.cc b/chrome/browser/chromeos/extensions/input_method_api.cc
index 4fe3fcf..d15f790 100644
--- a/chrome/browser/chromeos/extensions/input_method_api.cc
+++ b/chrome/browser/chromeos/extensions/input_method_api.cc
@@ -26,7 +26,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/spellchecker/spellcheck_factory.h"
 #include "chrome/browser/spellchecker/spellcheck_service.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -247,7 +247,7 @@
 
 ExtensionFunction::ResponseAction
 InputMethodPrivateGetEncryptSyncEnabledFunction::Run() {
-  syncer::SyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(
+  syncer::SyncService* sync_service = SyncServiceFactory::GetForProfile(
       Profile::FromBrowserContext(browser_context()));
   if (!sync_service)
     return RespondNow(Error(
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
index 60259bdd..3ff6b957 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -30,7 +30,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/file_manager/path_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client_impl.h"
 #include "chrome/browser/ui/webui/settings/chromeos/pref_names.h"
 #include "chrome/common/chrome_paths.h"
@@ -286,7 +286,7 @@
 
   Profile* profile =  Profile::FromBrowserContext(browser_context());
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   if (!sync_service) {
     // Sync flag is disabled (perhaps prohibited by policy).
     dict->SetBoolean(kSyncThemes, false);
diff --git a/chrome/browser/chromeos/full_restore/full_restore_prefs.cc b/chrome/browser/chromeos/full_restore/full_restore_prefs.cc
index 2ffefe78..6aefc6e 100644
--- a/chrome/browser/chromeos/full_restore/full_restore_prefs.cc
+++ b/chrome/browser/chromeos/full_restore/full_restore_prefs.cc
@@ -10,7 +10,6 @@
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
-#include "components/user_manager/user_manager.h"
 
 namespace chromeos {
 namespace full_restore {
@@ -40,6 +39,10 @@
   return prefs->HasPrefPath(kRestoreAppsAndPagesPrefName);
 }
 
+bool HasSessionStartupPref(PrefService* prefs) {
+  return prefs->HasPrefPath(prefs::kRestoreOnStartup);
+}
+
 bool CanPerformRestore(PrefService* prefs) {
   if (!HasRestorePref(prefs))
     return true;
@@ -53,8 +56,7 @@
 void SetDefaultRestorePrefIfNecessary(PrefService* prefs) {
   DCHECK(!HasRestorePref(prefs));
 
-  if (user_manager::UserManager::Get()->IsCurrentUserNew() ||
-      !prefs->HasPrefPath(prefs::kRestoreOnStartup)) {
+  if (!HasSessionStartupPref(prefs)) {
     prefs->SetInteger(kRestoreAppsAndPagesPrefName,
                       static_cast<int>(RestoreOption::kAskEveryTime));
     return;
diff --git a/chrome/browser/chromeos/full_restore/full_restore_prefs.h b/chrome/browser/chromeos/full_restore/full_restore_prefs.h
index 018fcb4..589bb02 100644
--- a/chrome/browser/chromeos/full_restore/full_restore_prefs.h
+++ b/chrome/browser/chromeos/full_restore/full_restore_prefs.h
@@ -37,6 +37,10 @@
 // return false.
 bool HasRestorePref(PrefService* prefs);
 
+// Returns true if the pref has |kRestoreOnStartup|. Otherwise,
+// return false.
+bool HasSessionStartupPref(PrefService* prefs);
+
 // Returns true if the restore pref doesn't exist or the pref is 'Always' or
 // 'Ask every time'. Otherwise, return false for 'Do not restore'.
 bool CanPerformRestore(PrefService* prefs);
diff --git a/chrome/browser/chromeos/full_restore/full_restore_service.cc b/chrome/browser/chromeos/full_restore/full_restore_service.cc
index ec8afe22..5df1bc8 100644
--- a/chrome/browser/chromeos/full_restore/full_restore_service.cc
+++ b/chrome/browser/chromeos/full_restore/full_restore_service.cc
@@ -24,7 +24,6 @@
 #include "components/full_restore/full_restore_info.h"
 #include "components/full_restore/full_restore_save_handler.h"
 #include "components/prefs/pref_service.h"
-#include "components/user_manager/user_manager.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/message_center/public/cpp/notification.h"
 
@@ -158,9 +157,10 @@
     return;
   }
 
-  // If it is the first time to run Chrome OS, we don't have restore data, so we
-  // don't need to consider restoration.
-  if (user_manager::UserManager::Get()->IsCurrentUserNew()) {
+  // If either OS pref setting nor Chrome pref setting exist, that means we
+  // don't have restore data, so we don't need to consider restoration, and call
+  // NewUserRestorePrefHandler to set OS pref setting.
+  if (!HasRestorePref(prefs) && !HasSessionStartupPref(prefs)) {
     new_user_pref_handler_ =
         std::make_unique<NewUserRestorePrefHandler>(profile_);
     return;
diff --git a/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc b/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc
index 8fe5a45b0d..8f49d770 100644
--- a/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc
+++ b/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc
@@ -15,8 +15,8 @@
 #include "chrome/browser/chromeos/secure_channel/secure_channel_client_provider.h"
 #include "chrome/browser/favicon/history_ui_favicon_request_handler_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/session_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
 #include "chromeos/components/phonehub/multidevice_setup_state_updater.h"
 #include "chromeos/components/phonehub/notification_access_manager_impl.h"
@@ -73,7 +73,7 @@
   DependsOn(secure_channel::NearbyConnectorFactory::GetInstance());
   DependsOn(SessionSyncServiceFactory::GetInstance());
   DependsOn(HistoryUiFaviconRequestHandlerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 PhoneHubManagerFactory::~PhoneHubManagerFactory() = default;
@@ -100,7 +100,7 @@
       std::make_unique<BrowserTabsModelProviderImpl>(
           multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(
               profile),
-          ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile),
+          SyncServiceFactory::GetInstance()->GetForProfile(profile),
           SessionSyncServiceFactory::GetInstance()->GetForProfile(profile),
           std::make_unique<BrowserTabsMetadataFetcherImpl>(
               HistoryUiFaviconRequestHandlerFactory::GetInstance()
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
index b76b04a..18ddc13b 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
@@ -552,9 +552,7 @@
   }
 };
 
-// Flaky: crbug.com/1195297
-IN_PROC_BROWSER_TEST_F(DataTransferDlpBlinkBrowserTest,
-                       DISABLED_ProceedOnWarn) {
+IN_PROC_BROWSER_TEST_F(DataTransferDlpBlinkBrowserTest, ProceedOnWarn) {
   ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -626,13 +624,16 @@
   run_loop.Run();
 
   ASSERT_TRUE(dlp_controller.ObserveWidget());
+
+  EXPECT_CALL(dlp_controller, OnWidgetClosing);
   helper.BlinkProceedPressed(dlp_controller.blink_data_dst_.value());
 
   EXPECT_EQ(kClipboardText1, EvalJs(GetActiveWebContents(), "p"));
+
+  testing::Mock::VerifyAndClearExpectations(&dlp_controller);
 }
 
-// Flaky: crbug.com/1195297
-IN_PROC_BROWSER_TEST_F(DataTransferDlpBlinkBrowserTest, DISABLED_CancelWarn) {
+IN_PROC_BROWSER_TEST_F(DataTransferDlpBlinkBrowserTest, CancelWarn) {
   ASSERT_TRUE(embedded_test_server()->Start());
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -705,9 +706,13 @@
 
   ASSERT_TRUE(dlp_controller.ObserveWidget());
   ASSERT_TRUE(dlp_controller.blink_data_dst_.has_value());
+
+  EXPECT_CALL(dlp_controller, OnWidgetClosing);
   helper.CancelWarningPressed(dlp_controller.blink_data_dst_.value());
 
   EXPECT_EQ("", EvalJs(GetActiveWebContents(), "p"));
+
+  testing::Mock::VerifyAndClearExpectations(&dlp_controller);
 }
 
 // crbug.com/1213143
diff --git a/chrome/browser/download/download_shelf_context_menu.cc b/chrome/browser/download/download_shelf_context_menu.cc
index 197461a4..55bc2b6 100644
--- a/chrome/browser/download/download_shelf_context_menu.cc
+++ b/chrome/browser/download/download_shelf_context_menu.cc
@@ -35,7 +35,8 @@
 }
 
 DownloadShelfContextMenu::DownloadShelfContextMenu(DownloadUIModel* download)
-    : download_(download), download_commands_(new DownloadCommands(download_)) {
+    : download_(download->GetWeakPtr()),
+      download_commands_(new DownloadCommands(download)) {
   DCHECK(download_);
   download_->AddObserver(this);
 }
@@ -46,7 +47,7 @@
   if (!download_)
     return nullptr;
 
-  DCHECK(WantsContextMenu(download_));
+  DCHECK(WantsContextMenu(download_.get()));
 
   bool is_download = download_->download() != nullptr;
 
diff --git a/chrome/browser/download/download_shelf_context_menu.h b/chrome/browser/download/download_shelf_context_menu.h
index de160be2..f40da5f 100644
--- a/chrome/browser/download/download_shelf_context_menu.h
+++ b/chrome/browser/download/download_shelf_context_menu.h
@@ -10,6 +10,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
 #include "chrome/browser/download/download_commands.h"
 #include "chrome/browser/download/download_ui_model.h"
@@ -75,7 +76,8 @@
   std::unique_ptr<ui::SimpleMenuModel> mixed_content_download_menu_model_;
 
   // Information source.
-  DownloadUIModel* download_;
+  // Use WeakPtr because the context menu may outlive |download_|.
+  base::WeakPtr<DownloadUIModel> download_;
   std::unique_ptr<DownloadCommands> download_commands_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadShelfContextMenu);
diff --git a/chrome/browser/download/download_ui_model.cc b/chrome/browser/download/download_ui_model.cc
index 7c78d3d4..043c976 100644
--- a/chrome/browser/download/download_ui_model.cc
+++ b/chrome/browser/download/download_ui_model.cc
@@ -152,6 +152,10 @@
   observers_.RemoveObserver(observer);
 }
 
+base::WeakPtr<DownloadUIModel> DownloadUIModel::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 bool DownloadUIModel::HasSupportedImageMimeType() const {
   if (blink::IsSupportedImageMimeType(GetMimeType()))
     return true;
diff --git a/chrome/browser/download/download_ui_model.h b/chrome/browser/download/download_ui_model.h
index 48473a7e..60a3488 100644
--- a/chrome/browser/download/download_ui_model.h
+++ b/chrome/browser/download/download_ui_model.h
@@ -11,6 +11,7 @@
 
 #include "base/files/file_path.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/sequenced_task_runner.h"
 #include "build/build_config.h"
@@ -49,6 +50,8 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
+  base::WeakPtr<DownloadUIModel> GetWeakPtr();
+
   // Does this download have a MIME type (either explicit or inferred from its
   // extension) suggesting that it is a supported image type?
   bool HasSupportedImageMimeType() const;
@@ -330,6 +333,8 @@
   // Returns a string indicating the status of an in-progress download.
   std::u16string GetInProgressStatusString() const;
 
+  base::WeakPtrFactory<DownloadUIModel> weak_ptr_factory_{this};
+
   DISALLOW_COPY_AND_ASSIGN(DownloadUIModel);
 };
 
diff --git a/chrome/browser/drive/drive_notification_manager_factory.cc b/chrome/browser/drive/drive_notification_manager_factory.cc
index 5d2901b..5b9583fd 100644
--- a/chrome/browser/drive/drive_notification_manager_factory.cc
+++ b/chrome/browser/drive/drive_notification_manager_factory.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/drive/drive_notification_manager.h"
 #include "components/invalidation/impl/profile_invalidation_provider.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -63,7 +63,7 @@
     : BrowserContextKeyedServiceFactory(
         "DriveNotificationManager",
         BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(invalidation::ProfileInvalidationProviderFactory::GetInstance());
 }
 
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
index e20e7dc..aef34456 100644
--- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
+++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/account_reconcilor_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
index ed0e9a0..7924f4f3 100644
--- a/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
+++ b/chrome/browser/extensions/api/browsing_data/browsing_data_test.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/account_reconcilor_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -103,7 +103,7 @@
 
   // Sync is running.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   sync_service->GetUserSettings()->SetSyncRequested(true);
   sync_service->GetUserSettings()->SetFirstSetupComplete(
       syncer::SyncFirstSetupCompleteSource::BASIC_FLOW);
diff --git a/chrome/browser/extensions/api/gcm/gcm_apitest.cc b/chrome/browser/extensions/api/gcm/gcm_apitest.cc
index 3f8c816..ad5389c 100644
--- a/chrome/browser/extensions/api/gcm/gcm_apitest.cc
+++ b/chrome/browser/extensions/api/gcm/gcm_apitest.cc
@@ -78,7 +78,7 @@
 
 void GcmApiTest::SetUpCommandLine(base::CommandLine* command_line) {
   // We now always create the GCMProfileService instance in
-  // ProfileSyncServiceFactory that is called when a profile is being
+  // SyncServiceFactory that is called when a profile is being
   // initialized. In order to prevent it from being created, we add the switch
   // to disable the sync logic.
   command_line->AppendSwitch(switches::kDisableSync);
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
index 387d0ee..292b700 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
@@ -16,7 +16,6 @@
 #include "base/values.h"
 #include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/common/extensions/api/passwords_private.h"
 #include "components/password_manager/core/browser/manage_passwords_referrer.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.cc
index b39d378..2fead96c 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.cc
@@ -9,7 +9,7 @@
 #include "chrome/browser/password_manager/bulk_leak_check_service_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "extensions/browser/extension_system_provider.h"
 
@@ -38,7 +38,7 @@
           BrowserContextDependencyManager::GetInstance()) {
   DependsOn(BulkLeakCheckServiceFactory::GetInstance());
   DependsOn(PasswordStoreFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 PasswordsPrivateDelegateFactory::~PasswordsPrivateDelegateFactory() = default;
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
index 3794a4c..56c80cb 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
@@ -22,7 +22,7 @@
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/common/extensions/api/passwords_private.h"
 #include "chrome/common/pref_names.h"
@@ -170,7 +170,7 @@
           std::make_unique<
               password_manager::PasswordAccountStorageSettingsWatcher>(
               profile_->GetPrefs(),
-              ProfileSyncServiceFactory::GetForProfile(profile_),
+              SyncServiceFactory::GetForProfile(profile_),
               base::BindRepeating(&PasswordsPrivateDelegateImpl::
                                       OnAccountStorageOptInStateChanged,
                                   base::Unretained(this)))),
@@ -485,7 +485,7 @@
 
 bool PasswordsPrivateDelegateImpl::IsOptedInForAccountStorage() {
   return password_manager::features_util::IsOptedInForAccountStorage(
-      profile_->GetPrefs(), ProfileSyncServiceFactory::GetForProfile(profile_));
+      profile_->GetPrefs(), SyncServiceFactory::GetForProfile(profile_));
 }
 
 void PasswordsPrivateDelegateImpl::SetAccountStorageOptIn(
diff --git a/chrome/browser/extensions/api/settings_private/generated_prefs_factory.cc b/chrome/browser/extensions/api/settings_private/generated_prefs_factory.cc
index 7891898b..5f4483b 100644
--- a/chrome/browser/extensions/api/settings_private/generated_prefs_factory.cc
+++ b/chrome/browser/extensions/api/settings_private/generated_prefs_factory.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 namespace extensions {
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager_unittest.cc b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager_unittest.cc
index 719a4bd..ba06c75e 100644
--- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager_unittest.cc
+++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/extensions/api/signed_in_devices.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
@@ -32,7 +32,7 @@
   adaptor.identity_test_env()->SetPrimaryAccount("foo@test.com",
                                                  signin::ConsentLevel::kSync);
 
-  ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+  SyncServiceFactory::GetInstance()->SetTestingFactory(
       profile.get(), BrowserContextKeyedServiceFactory::TestingFactory());
   SignedInDevicesManager manager(profile.get());
 
diff --git a/chrome/browser/extensions/extension_service_sync_unittest.cc b/chrome/browser/extensions/extension_service_sync_unittest.cc
index 20b8c80..b59853c 100644
--- a/chrome/browser/extensions/extension_service_sync_unittest.cc
+++ b/chrome/browser/extensions/extension_service_sync_unittest.cc
@@ -24,7 +24,7 @@
 #include "chrome/browser/extensions/test_blocklist.h"
 #include "chrome/browser/extensions/updater/extension_updater.h"
 #include "chrome/browser/profiles/profile_key.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/themes/test/theme_service_changed_waiter.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
@@ -329,7 +329,7 @@
 
   // The user has enabled sync.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile());
+      SyncServiceFactory::GetForProfile(profile());
   sync_service->GetUserSettings()->SetFirstSetupComplete(kSetSourceFromTest);
 
   service()->Init();
@@ -365,7 +365,7 @@
 
   // Enable sync.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile());
+      SyncServiceFactory::GetForProfile(profile());
   sync_service->GetUserSettings()->SetFirstSetupComplete(kSetSourceFromTest);
 
   service()->Init();
@@ -447,7 +447,7 @@
 
   // Enable sync.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile());
+      SyncServiceFactory::GetForProfile(profile());
   sync_service->GetUserSettings()->SetFirstSetupComplete(kSetSourceFromTest);
 
   service()->Init();
@@ -513,7 +513,7 @@
 
   // The user has enabled sync.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile());
+      SyncServiceFactory::GetForProfile(profile());
   sync_service->GetUserSettings()->SetFirstSetupComplete(kSetSourceFromTest);
   // Make sure ExtensionSyncService is created, so it'll be notified of changes.
   extension_sync_service();
@@ -574,7 +574,7 @@
   InitializeInstalledExtensionService(pref_path, source_install_dir);
 
   // The user has enabled sync.
-  ProfileSyncServiceFactory::GetForProfile(profile())
+  SyncServiceFactory::GetForProfile(profile())
       ->GetUserSettings()
       ->SetFirstSetupComplete(kSetSourceFromTest);
   // Make sure ExtensionSyncService is created, so it'll be notified of changes.
@@ -1703,7 +1703,7 @@
   InitializeEmptyExtensionService();
 
   // The user has enabled sync.
-  ProfileSyncServiceFactory::GetForProfile(profile())
+  SyncServiceFactory::GetForProfile(profile())
       ->GetUserSettings()
       ->SetFirstSetupComplete(kSetSourceFromTest);
   // Make sure ExtensionSyncService is created, so it'll be notified of changes.
@@ -1839,7 +1839,7 @@
 
     // Enable sync.
     syncer::SyncService* sync_service =
-        ProfileSyncServiceFactory::GetForProfile(profile());
+        SyncServiceFactory::GetForProfile(profile());
     sync_service->GetUserSettings()->SetFirstSetupComplete(kSetSourceFromTest);
 
     test_blocklist_.Attach(service()->blocklist_);
diff --git a/chrome/browser/extensions/external_pref_loader.cc b/chrome/browser/extensions/external_pref_loader.cc
index 6e52c06c6..f8527825 100644
--- a/chrome/browser/extensions/external_pref_loader.cc
+++ b/chrome/browser/extensions/external_pref_loader.cc
@@ -33,7 +33,7 @@
 #include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
 #include "chrome/browser/prefs/pref_service_syncable_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_service_observer.h"
@@ -157,8 +157,7 @@
     DCHECK(
         profile_->GetPrefs()->GetBoolean(chromeos::prefs::kSyncOobeCompleted));
     pref_change_registrar_.reset();
-    syncer::SyncService* service =
-        ProfileSyncServiceFactory::GetForProfile(profile_);
+    syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
     if (!service->GetUserSettings()->IsOsSyncFeatureEnabled()) {
       // User opted-out of OS sync, OS sync will never start, we're done here.
       Finish();
@@ -169,8 +168,7 @@
   }
 
   void MaybeObserveSyncStart() {
-    syncer::SyncService* service =
-        ProfileSyncServiceFactory::GetForProfile(profile_);
+    syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
     DCHECK(service);
     if (!service->CanSyncFeatureStart()) {
       Finish();
@@ -218,8 +216,7 @@
     DCHECK(prefs);
     syncable_pref_observation_.Observe(prefs);
 
-    syncer::SyncService* service =
-        ProfileSyncServiceFactory::GetForProfile(profile_);
+    syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
     sync_service_observation_.Observe(service);
   }
 
@@ -267,7 +264,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   if ((options_ & DELAY_LOAD_UNTIL_PRIORITY_SYNC) &&
-      (profile_ && ProfileSyncServiceFactory::IsSyncAllowed(profile_))) {
+      (profile_ && SyncServiceFactory::IsSyncAllowed(profile_))) {
     pending_waiter_list_.push_back(
         std::make_unique<PrioritySyncReadyWaiter>(profile_));
     PrioritySyncReadyWaiter* waiter_ptr = pending_waiter_list_.back().get();
diff --git a/chrome/browser/extensions/external_pref_loader_unittest.cc b/chrome/browser/extensions/external_pref_loader_unittest.cc
index 821a3486..5d313ba 100644
--- a/chrome/browser/extensions/external_pref_loader_unittest.cc
+++ b/chrome/browser/extensions/external_pref_loader_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/extensions/external_provider_impl.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
 #include "components/sync/driver/test_sync_service.h"
@@ -99,7 +99,7 @@
   void SetUp() override {
     profile_ = std::make_unique<TestingProfile>();
     sync_service_ = static_cast<TestSyncService*>(
-        ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+        SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
             profile(), base::BindRepeating(&TestingSyncFactoryFunction)));
     sync_service_->SetFirstSetupComplete(true);
   }
diff --git a/chrome/browser/favicon/history_ui_favicon_request_handler_factory.cc b/chrome/browser/favicon/history_ui_favicon_request_handler_factory.cc
index 5b46af7..de625df0 100644
--- a/chrome/browser/favicon/history_ui_favicon_request_handler_factory.cc
+++ b/chrome/browser/favicon/history_ui_favicon_request_handler_factory.cc
@@ -10,7 +10,7 @@
 #include "chrome/browser/favicon/large_icon_service_factory.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/favicon/core/history_ui_favicon_request_handler_impl.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/sync/driver/sync_service.h"
@@ -47,7 +47,7 @@
           BrowserContextDependencyManager::GetInstance()) {
   DependsOn(FaviconServiceFactory::GetInstance());
   DependsOn(LargeIconServiceFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 HistoryUiFaviconRequestHandlerFactory::
@@ -64,7 +64,7 @@
   Profile* profile = Profile::FromBrowserContext(context);
   return new favicon::HistoryUiFaviconRequestHandlerImpl(
       base::BindRepeating(&CanSendHistoryData,
-                          ProfileSyncServiceFactory::GetForProfile(profile)),
+                          SyncServiceFactory::GetForProfile(profile)),
       FaviconServiceFactory::GetForProfile(profile,
                                            ServiceAccessType::EXPLICIT_ACCESS),
       LargeIconServiceFactory::GetForBrowserContext(context));
diff --git a/chrome/browser/federated_learning/floc_id_provider_browsertest.cc b/chrome/browser/federated_learning/floc_id_provider_browsertest.cc
index 12bac328..f1ffc563 100644
--- a/chrome/browser/federated_learning/floc_id_provider_browsertest.cc
+++ b/chrome/browser/federated_learning/floc_id_provider_browsertest.cc
@@ -21,7 +21,7 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -376,7 +376,7 @@
 
   syncer::TestSyncService* sync_service() {
     return static_cast<syncer::TestSyncService*>(
-        ProfileSyncServiceFactory::GetForProfile(browser()->profile()));
+        SyncServiceFactory::GetForProfile(browser()->profile()));
   }
 
   syncer::FakeUserEventService* user_event_service() {
@@ -391,7 +391,7 @@
 
  protected:
   void OnWillCreateBrowserContextServices(content::BrowserContext* context) {
-    ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+    SyncServiceFactory::GetInstance()->SetTestingFactory(
         context,
         base::BindRepeating(&FlocIdProviderSortingLshUninitializedBrowserTest::
                                 CreateSyncService,
@@ -442,7 +442,7 @@
     Profile* profile = Profile::FromBrowserContext(context);
 
     syncer::SyncService* sync_service =
-        ProfileSyncServiceFactory::GetForProfile(profile);
+        SyncServiceFactory::GetForProfile(profile);
 
     PrivacySandboxSettings* privacy_sandbox_settings =
         PrivacySandboxSettingsFactory::GetForProfile(profile);
diff --git a/chrome/browser/federated_learning/floc_id_provider_factory.cc b/chrome/browser/federated_learning/floc_id_provider_factory.cc
index 452260d..40c8dba0 100644
--- a/chrome/browser/federated_learning/floc_id_provider_factory.cc
+++ b/chrome/browser/federated_learning/floc_id_provider_factory.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -37,7 +37,7 @@
     : BrowserContextKeyedServiceFactory(
           "FlocIdProvider",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(PrivacySandboxSettingsFactory::GetInstance());
   DependsOn(FlocRemotePermissionServiceFactory::GetInstance());
   DependsOn(HistoryServiceFactory::GetInstance());
@@ -51,7 +51,7 @@
   Profile* profile = Profile::FromBrowserContext(context);
 
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   if (!sync_service)
     return nullptr;
 
diff --git a/chrome/browser/federated_learning/floc_remote_permission_service_factory.cc b/chrome/browser/federated_learning/floc_remote_permission_service_factory.cc
index 5a7e68c..059217eb 100644
--- a/chrome/browser/federated_learning/floc_remote_permission_service_factory.cc
+++ b/chrome/browser/federated_learning/floc_remote_permission_service_factory.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/federated_learning/floc_remote_permission_service_factory.h"
 
 #include "chrome/browser/federated_learning/floc_remote_permission_service.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/sync/driver/sync_service.h"
 #include "content/public/browser/browser_context.h"
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
index 70cf099..797352d 100644
--- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
+++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -27,7 +27,7 @@
 #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings_factory.h"
 #include "chrome/browser/google/google_brand.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/channel_info.h"
 #include "components/prefs/pref_service.h"
 #include "components/sync/driver/sync_internals_util.h"
@@ -390,14 +390,14 @@
 void ChromeInternalLogSource::PopulateSyncLogs(SystemLogsResponse* response) {
   // We are only interested in sync logs for the primary user profile.
   Profile* profile = ProfileManager::GetPrimaryUserProfile();
-  if (!profile || !ProfileSyncServiceFactory::HasSyncService(profile))
+  if (!profile || !SyncServiceFactory::HasSyncService(profile))
     return;
 
   // Add sync logs to |response|.
   std::unique_ptr<base::DictionaryValue> sync_logs =
       syncer::sync_ui_util::ConstructAboutInformation(
           syncer::sync_ui_util::IncludeSensitiveData(false),
-          ProfileSyncServiceFactory::GetForProfile(profile),
+          SyncServiceFactory::GetForProfile(profile),
           chrome::GetChannelName(chrome::WithExtendedStable(true)));
   std::string serialized_sync_logs;
   JSONStringValueSerializer(&serialized_sync_logs).Serialize(*sync_logs);
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 2f18f7e..da720e37 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1682,8 +1682,8 @@
   },
   {
     "name": "enable-experimental-accessibility-dictation-extension",
-    "owners": [ "akihiroota" ],
-    "expiry_milestone": 92
+    "owners": [ "akihiroota", "katie" ],
+    "expiry_milestone": 96
   },
   {
     "name": "enable-experimental-accessibility-dictation-listening",
@@ -1693,7 +1693,7 @@
   {
     "name": "enable-experimental-accessibility-dictation-offline",
     "owners": [ "akihiroota", "katie" ],
-    "expiry_milestone": 92
+    "expiry_milestone": 96
   },
   {
     "name": "enable-experimental-accessibility-labels",
@@ -2226,6 +2226,11 @@
     "expiry_milestone": -1
   },
   {
+    "name": "enable-quick-action-search-widget-android",
+    "owners": [ "maxtauro@google.com", "ender@google.com" ],
+    "expiry_milestone": 98
+  },
+  {
     "name": "enable-quick-answers",
     "owners": [ "croissant-eng" ],
     "expiry_milestone": 95
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 58c636d..3c06517 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2043,6 +2043,11 @@
 const char kQuicName[] = "Experimental QUIC protocol";
 const char kQuicDescription[] = "Enable experimental QUIC protocol support.";
 
+const char kQuickActionSearchWidgetAndroidName[] = "Quick Action Search Widget";
+const char kQuickActionSearchWidgetAndroidDescription[] =
+    "When enabled, the quick action search widget will be available to add to "
+    "the homescreen.";
+
 const char kQuietNotificationPromptsName[] =
     "Quieter notification permission prompts";
 const char kQuietNotificationPromptsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 6048eec0..38d59e9f 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1176,6 +1176,9 @@
 extern const char kQuicName[];
 extern const char kQuicDescription[];
 
+extern const char kQuickActionSearchWidgetAndroidName[];
+extern const char kQuickActionSearchWidgetAndroidDescription[];
+
 extern const char kQuietNotificationPromptsName[];
 extern const char kQuietNotificationPromptsDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 9241fe3b..762e84b 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -213,6 +213,7 @@
     &kPageAnnotationsService,
     &kProbabilisticCryptidRenderer,
     &kPwaUpdateDialogForNameAndIcon,
+    &kQuickActionSearchWidgetAndroid,
     &kReachedCodeProfiler,
     &kReaderModeInCCT,
     &kReengagementNotification,
@@ -603,6 +604,9 @@
 const base::Feature kPwaUpdateDialogForNameAndIcon{
     "PwaUpdateDialogForNameAndIcon", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kQuickActionSearchWidgetAndroid{
+    "QuickActionSearchWidgetAndroid", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kReachedCodeProfiler{"ReachedCodeProfiler",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index 85d8c21b..ee773d0 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -104,6 +104,7 @@
 extern const base::Feature kPageAnnotationsService;
 extern const base::Feature kPwaUpdateDialogForNameAndIcon;
 extern const base::Feature kProbabilisticCryptidRenderer;
+extern const base::Feature kQuickActionSearchWidgetAndroid;
 extern const base::Feature kReachedCodeProfiler;
 extern const base::Feature kReengagementNotification;
 extern const base::Feature kReaderModeInCCT;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 5014927b..ee127d2 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -426,6 +426,7 @@
     public static final String QUERY_TILES_ENABLE_QUERY_EDITING = "QueryTilesEnableQueryEditing";
     public static final String QUERY_TILES_LOCAL_ORDERING = "QueryTilesLocalOrdering";
     public static final String QUERY_TILES_SEGMENTATION = "QueryTilesSegmentation";
+    public static final String QUICK_ACTION_SEARCH_WIDGET = "QuickActionSearchWidgetAndroid";
     public static final String QUIET_NOTIFICATION_PROMPTS = "QuietNotificationPrompts";
     public static final String REACHED_CODE_PROFILER = "ReachedCodeProfiler";
     public static final String READ_LATER = "ReadLater";
diff --git a/chrome/browser/history/web_history_service_factory.cc b/chrome/browser/history/web_history_service_factory.cc
index 7be06f2..d8c3172d8 100644
--- a/chrome/browser/history/web_history_service_factory.cc
+++ b/chrome/browser/history/web_history_service_factory.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/history/web_history_service_factory.h"
 
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/history/core/browser/web_history_service.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/sync/driver/sync_service.h"
@@ -16,7 +16,7 @@
 // Returns true if the user is signed in and full history sync is enabled,
 // and false otherwise.
 bool IsHistorySyncEnabled(Profile* profile) {
-  syncer::SyncService* sync = ProfileSyncServiceFactory::GetForProfile(profile);
+  syncer::SyncService* sync = SyncServiceFactory::GetForProfile(profile);
   return sync && sync->IsSyncFeatureActive() && !sync->IsLocalSyncEnabled() &&
          sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES);
 }
diff --git a/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
index 335366a..e8ec46f 100644
--- a/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
+++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
@@ -797,7 +797,7 @@
   {
     ListPrefUpdate update(profile()->GetPrefs(),
                           prefs::kMediaRouterTabMirroringSources);
-    update->Remove(base::Value(origin), nullptr);
+    update->EraseListValue(base::Value(origin));
   }
 
   // Auto-join requests should now go through.
@@ -855,7 +855,7 @@
     ListPrefUpdate update(
         profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true)->GetPrefs(),
         prefs::kMediaRouterTabMirroringSources);
-    update->Remove(base::Value(origin), nullptr);
+    update->EraseListValue(base::Value(origin));
   }
 
   // Auto-join requests should now go through.
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics.h b/chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics.h
index 9f7fbb78..eb1829da 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics.h
+++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_metrics.h
@@ -31,7 +31,7 @@
 // contains all possible combinations of ReceiverAppType.
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused. Please keep it in sync with
-// MediaRouterRequestReceiverAppType in tools/metrics/histograms/enums.xml.
+// ReceiverAppTypeSet in tools/metrics/histograms/enums.xml.
 enum class ReceiverAppTypeSet {
   // Web-based Cast receiver apps. This is supported by all Cast media source
   // by default.
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc
index a7d28407..a24be48 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -57,7 +57,7 @@
 #include "chrome/browser/safe_browsing/certificate_reporting_metrics_provider.h"
 #include "chrome/browser/safe_browsing/metrics/safe_browsing_metrics_provider.h"
 #include "chrome/browser/sync/device_info_sync_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/tracing/background_tracing_metrics_provider.h"
 #include "chrome/browser/translate/translate_ranker_metrics_provider.h"
 #include "chrome/common/buildflags.h"
@@ -409,7 +409,7 @@
     if (!profile)
       return nullptr;
 
-    return ProfileSyncServiceFactory::GetForProfile(profile);
+    return SyncServiceFactory::GetForProfile(profile);
   }
 
   base::Time GetNetworkTime() const override {
@@ -805,7 +805,7 @@
 
   metrics_service_->RegisterMetricsProvider(
       std::make_unique<syncer::PassphraseTypeMetricsProvider>(
-          base::BindRepeating(&ProfileSyncServiceFactory::GetAllSyncServices)));
+          base::BindRepeating(&SyncServiceFactory::GetAllSyncServices)));
 
   metrics_service_->RegisterMetricsProvider(
       std::make_unique<HttpsEngagementMetricsProvider>());
@@ -1028,7 +1028,7 @@
 
   ObserveServiceForDeletions(history_service);
 
-  syncer::SyncService* sync = ProfileSyncServiceFactory::GetForProfile(profile);
+  syncer::SyncService* sync = SyncServiceFactory::GetForProfile(profile);
   if (!sync) {
     return false;
   }
diff --git a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.cc b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.cc
index 3d800bc..a548a62a 100644
--- a/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.cc
+++ b/chrome/browser/metrics/desktop_session_duration/desktop_profile_session_durations_service_factory.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_context.h"
 
@@ -33,7 +33,7 @@
     : BrowserContextKeyedServiceFactory(
           "DesktopProfileSessionDurationsService",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
 }
 
@@ -45,7 +45,7 @@
     content::BrowserContext* context) const {
   Profile* profile = Profile::FromBrowserContext(context);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   DesktopSessionDurationTracker* tracker = DesktopSessionDurationTracker::Get();
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForProfile(profile);
diff --git a/chrome/browser/metrics/perf/metric_provider.cc b/chrome/browser/metrics/perf/metric_provider.cc
index 20a49010..07405741 100644
--- a/chrome/browser/metrics/perf/metric_provider.cc
+++ b/chrome/browser/metrics/perf/metric_provider.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/sync/base/user_selectable_type.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/driver/sync_user_settings.h"
@@ -189,7 +189,7 @@
 MetricProvider::RecordAttemptStatus MetricProvider::AppSyncStateForUserProfile(
     Profile* profile) {
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   if (!sync_service)
     return RecordAttemptStatus::kSyncServiceUnavailable;
   syncer::SyncUserSettings* sync_settings = sync_service->GetUserSettings();
diff --git a/chrome/browser/metrics/perf/metric_provider_unittest.cc b/chrome/browser/metrics/perf/metric_provider_unittest.cc
index 70ba89b..c81463d 100644
--- a/chrome/browser/metrics/perf/metric_provider_unittest.cc
+++ b/chrome/browser/metrics/perf/metric_provider_unittest.cc
@@ -17,7 +17,7 @@
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
@@ -339,7 +339,7 @@
  protected:
   TestSyncService* GetSyncService(TestingProfile* profile) {
     TestSyncService* sync_service = static_cast<TestSyncService*>(
-        ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+        SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
             profile, base::BindRepeating(&TestingSyncFactoryFunction)));
     sync_service->SetFirstSetupComplete(true);
     return sync_service;
diff --git a/chrome/browser/metrics/testing/sync_metrics_test_utils.cc b/chrome/browser/metrics/testing/sync_metrics_test_utils.cc
index 047712a..bcc9661 100644
--- a/chrome/browser/metrics/testing/sync_metrics_test_utils.cc
+++ b/chrome/browser/metrics/testing/sync_metrics_test_utils.cc
@@ -6,7 +6,7 @@
 
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
@@ -20,7 +20,7 @@
     base::WeakPtr<fake_server::FakeServer> fake_server) {
   DCHECK(profile);
 
-  ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(profile)
+  SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile)
       ->OverrideNetworkForTest(
           fake_server::CreateFakeServerHttpPostProviderFactory(
               fake_server->AsWeakPtr()));
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc
index 907d17d..f018b83 100644
--- a/chrome/browser/metrics/ukm_browsertest.cc
+++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -25,7 +25,7 @@
 #include "chrome/browser/metrics/testing/sync_metrics_test_utils.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/secondary_account_helper.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
@@ -1151,7 +1151,7 @@
   std::unique_ptr<ProfileSyncServiceHarness> harness =
       test::InitializeProfileForSync(profile, GetFakeServer()->AsWeakPtr());
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
 
   secondary_account_helper::SignInSecondaryAccount(
       profile, &test_url_loader_factory_, "secondary_user@email.com");
diff --git a/chrome/browser/nearby_sharing/instantmessaging/receive_messages_express_unittest.cc b/chrome/browser/nearby_sharing/instantmessaging/receive_messages_express_unittest.cc
index 824e96a8..bf0aa5c2 100644
--- a/chrome/browser/nearby_sharing/instantmessaging/receive_messages_express_unittest.cc
+++ b/chrome/browser/nearby_sharing/instantmessaging/receive_messages_express_unittest.cc
@@ -121,7 +121,7 @@
   }
 
   std::string GetFastPathOnlyResponse() {
-    return BuildResponseProto({"message"}, /*include_fast_path_ready=*/true)
+    return BuildResponseProto({}, /*include_fast_path_ready=*/true)
         .SerializeAsString();
   }
 
@@ -249,6 +249,7 @@
 
 TEST_F(ReceiveMessagesExpressTest, StopPreventsPendingTransfer) {
   base::RunLoop run_loop;
+
   StartReceivingMessages(&run_loop, /*token_success=*/true);
 
   // Calls OnDataReceived() in ReceiveMessagesExpress.
diff --git a/chrome/browser/nearby_sharing/instantmessaging/stream_parser.cc b/chrome/browser/nearby_sharing/instantmessaging/stream_parser.cc
index 8349ffc..6e490300 100644
--- a/chrome/browser/nearby_sharing/instantmessaging/stream_parser.cc
+++ b/chrome/browser/nearby_sharing/instantmessaging/stream_parser.cc
@@ -4,24 +4,18 @@
 
 #include "chrome/browser/nearby_sharing/instantmessaging/stream_parser.h"
 
+#include "base/metrics/histogram_functions.h"
 #include "base/strings/string_piece.h"
 #include "chrome/browser/nearby_sharing/instantmessaging/proto/instantmessaging.pb.h"
 #include "chrome/browser/nearby_sharing/logging/logging.h"
-#include "net/base/io_buffer.h"
-#include "third_party/protobuf/src/google/protobuf/io/coded_stream.h"
-#include "third_party/protobuf/src/google/protobuf/wire_format_lite.h"
 
 namespace {
 
-using ::google::protobuf::internal::WireFormatLite;
-
-// A buffer spare capacity limits the amount of times we need to resize the
-// buffer when copying over data, which involves reallocating memory.
-// We chose 512 is because it is one of the larger standard sizes for
-// a buffer, and we expect a lot of data to be received in the WebRTC
-// signaling process.
-constexpr int kReadBufferSpareCapacity = 512;
-constexpr int kMinimumBytesToParseNextMessagesField = 6;
+void RecordNumParsingAttemptsMetrics(int num_attempts) {
+  base::UmaHistogramCounts1000(
+      "Nearby.Connections.InstantMessaging.ReceiveExpress.NumParsingAttempts",
+      num_attempts);
+}
 
 }  // namespace
 
@@ -33,157 +27,87 @@
 StreamParser::~StreamParser() = default;
 
 void StreamParser::Append(base::StringPiece data) {
-  if (!unparsed_data_buffer_) {
-    unparsed_data_buffer_ = base::MakeRefCounted<net::GrowableIOBuffer>();
-    unparsed_data_buffer_->SetCapacity(data.size() + kReadBufferSpareCapacity);
-  } else if (unparsed_data_buffer_->RemainingCapacity() < data.size()) {
-    unparsed_data_buffer_->SetCapacity(unparsed_data_buffer_->offset() +
-                                       data.size() + kReadBufferSpareCapacity);
-  }
+  data_.append(data.data(), data.size());
 
-  DCHECK_GE(unparsed_data_buffer_->RemainingCapacity(),
-            static_cast<int>(data.size()));
-  memcpy(unparsed_data_buffer_->data(), data.data(), data.size());
-  unparsed_data_buffer_->set_offset(unparsed_data_buffer_->offset() +
-                                    data.size());
-  ParseStreamIfAvailable();
+  absl::optional<chrome_browser_nearby_sharing_instantmessaging::StreamBody>
+      stream_body = GetNextMessage();
+  while (stream_body) {
+    DelegateMessage(stream_body.value());
+    stream_body = GetNextMessage();
+  }
 }
 
-void StreamParser::ParseStreamIfAvailable() {
-  DCHECK(unparsed_data_buffer_);
-  int unparsed_bytes_available = unparsed_data_buffer_->offset();
+absl::optional<chrome_browser_nearby_sharing_instantmessaging::StreamBody>
+StreamParser::GetNextMessage() {
+  // The incoming stream may not be a valid StreamBody proto as it might be
+  // split into various OnDataReceived calls. The easy way is to append all
+  // incoming data and parse byte by byte to check if it forms a valid
+  // StreamBody proto.
+  // Security Note - The StreamBody proto is coming from a trusted Google server
+  // and hence can be parsed on the browser process.
 
-  // If we don't at least 8 bytes, don't bother trying to parse yet and wait
-  // for more data.
-  if (unparsed_bytes_available < kMinimumBytesToParseNextMessagesField)
-    return;
+  // TODO(crbug.com/1123172) - Add metrics to figure out which code paths are
+  // more used and the time taken to parse the incoming messages.
+  if (data_.empty())
+    return absl::nullopt;
 
-  google::protobuf::io::CodedInputStream input_stream(
-      reinterpret_cast<const uint8_t*>(unparsed_data_buffer_->StartOfBuffer()),
-      unparsed_bytes_available);
-  int bytes_consumed = 0;
+  // There's a good chance that the entire message is a valid proto since the
+  // individual messages sent by WebRTC are small, so check that first to
+  // speed up parsing.
+  chrome_browser_nearby_sharing_instantmessaging::StreamBody stream_body;
+  ++parsing_counter_for_metrics_;
+  if (stream_body.ParseFromString(data_)) {
+    data_.clear();
+    RecordNumParsingAttemptsMetrics(parsing_counter_for_metrics_);
+    parsing_counter_for_metrics_ = 0;
+    return stream_body;
+  }
 
-  // We can't use StreamBody::ParseFromString() here, as it can't do partial
-  // parsing, nor can it tell how many bytes are consumed.
-  while (bytes_consumed < unparsed_bytes_available) {
-    bool is_successful = ParseNextMessagesFieldFromStream(&input_stream);
-    if (is_successful) {
-      // Only update |bytes_consumed| if the whole field is decoded.
-      bytes_consumed = input_stream.CurrentPosition();
-    } else {
-      // The stream data can't be fully decoded yet.
-      break;
+  int end_pos = 1;
+  int size = data_.size();
+  while (end_pos < size) {
+    ++parsing_counter_for_metrics_;
+    // TODO(crbug.com/1123169) - Optimize this function to use header
+    // information to figure out the start and end of proto instead of checking
+    // for every length.
+    if (stream_body.ParseFromArray(data_.data(), end_pos)) {
+      data_.erase(data_.begin(), data_.begin() + end_pos);
+      RecordNumParsingAttemptsMetrics(parsing_counter_for_metrics_);
+      parsing_counter_for_metrics_ = 0;
+      return stream_body;
     }
+    end_pos++;
   }
 
-  if (bytes_consumed == 0) {
-    return;
-  }
-
-  CHECK_LE(bytes_consumed, unparsed_bytes_available);
-  int bytes_not_consumed = unparsed_bytes_available - bytes_consumed;
-
-  // Shift the unread data back to the beginning of the buffer for the next
-  // iteration of reading data.
-  memmove(unparsed_data_buffer_->StartOfBuffer(),
-          unparsed_data_buffer_->StartOfBuffer() + bytes_consumed,
-          bytes_not_consumed);
-  unparsed_data_buffer_->set_offset(bytes_not_consumed);
+  return absl::nullopt;
 }
 
-void StreamParser::DelegateMessage(const std::string& messages) {
+void StreamParser::DelegateMessage(
+    const chrome_browser_nearby_sharing_instantmessaging::StreamBody&
+        stream_body) {
   // Security Note - The ReceiveMessagesResponse proto is coming from a trusted
   // Google server and hence can be parsed on the browser process. The message
   // contained within the proto is untrusted and should be parsed within a
   // sandbox process.
-  chrome_browser_nearby_sharing_instantmessaging::ReceiveMessagesResponse
-      response;
-  if (!response.ParseFromString(messages)) {
-    NS_LOG(ERROR) << "Cannot read ReceiveMessagesResponse from string.";
-    return;
+  for (int i = 0; i < stream_body.messages_size(); i++) {
+    chrome_browser_nearby_sharing_instantmessaging::ReceiveMessagesResponse
+        response;
+    response.ParseFromString(stream_body.messages(i));
+    switch (response.body_case()) {
+      case chrome_browser_nearby_sharing_instantmessaging::
+          ReceiveMessagesResponse::kFastPathReady:
+        if (fastpath_ready_callback_) {
+          std::move(fastpath_ready_callback_).Run();
+        }
+        break;
+      case chrome_browser_nearby_sharing_instantmessaging::
+          ReceiveMessagesResponse::kInboxMessage:
+        listener_.Run(response.inbox_message().message());
+        break;
+      default:
+        NS_LOG(ERROR) << __func__ << ": message body case was unexpected: "
+                      << response.body_case();
+        NOTREACHED();
+    }
   }
-
-  switch (response.body_case()) {
-    case chrome_browser_nearby_sharing_instantmessaging::
-        ReceiveMessagesResponse::kFastPathReady:
-      if (fastpath_ready_callback_) {
-        std::move(fastpath_ready_callback_).Run();
-      }
-      break;
-    case chrome_browser_nearby_sharing_instantmessaging::
-        ReceiveMessagesResponse::kInboxMessage:
-      listener_.Run(response.inbox_message().message());
-      break;
-    default:
-      NS_LOG(ERROR) << __func__ << ": message body case was unexpected: "
-                    << response.body_case();
-      NOTREACHED();
-  }
-}
-
-bool StreamParser::ParseNextMessagesFieldFromStream(
-    google::protobuf::io::CodedInputStream* input_stream) {
-  // The WireFormat nature of protos allows for key:value pairs, each which
-  // contains the value of one proto field. The key (also called tag) for each
-  // pair is actually two values: the field number and the wire type.
-  //
-  // A typical stream looks like:
-  //      [message tag][field data][message tag][field data]...
-  // where the message tag consists of the field id and the WireType, like so:
-  //      [field id + WireType][field data][field id + WireType][field data]...
-  //
-  // In this case, we only considering the specific field (1 -- "messages") of
-  // the StreamBody, and because we are expecting the 'bytes' data type, the
-  // wire type says it is a length delimited value. From this, we know that the
-  // next bytes on should be a length followed by the actual data bytes (which
-  // will be read by WireFormatLite::ReadBytes). Note: this is only true when
-  // the wire type is set to  WIRETYPE_LENGTH_DELIMITED and we know the field
-  // type is bytes.
-  //
-  // Therefore, for this specific instance, we expect our stream to look like
-  // this:
-  //     [field id="messages"|WIRETYPE_LENGTH_DELIMITED][bytes size][byte data]
-  // See https://developers.google.com/protocol-buffers/docs/encoding for
-  // further explanation.
-
-  // A message tag of zero means we don't have a valid tag or we don't have
-  // enough bytes to read a tag. If we cannot read the tag, we likely need to
-  // wait for more bytes to be appended to the input stream.
-  uint32_t messages_tag = input_stream->ReadTag();
-  if (messages_tag == 0)
-    return false;
-
-  // If we were able to read the full tag above, and the field id does not
-  // match the StreamBody messages field body we were expecting, then we need
-  // more data to continue.
-  if (WireFormatLite::GetTagFieldNumber(messages_tag) !=
-      chrome_browser_nearby_sharing_instantmessaging::StreamBody::
-          kMessagesFieldNumber) {
-    return false;
-  }
-
-  // WireType specifies the format of the data to follow. Here, we are verifying
-  // the data we are receiving matching the data we are expecting, which is in
-  // the form of WIRETYPE_LENGTH_DELIMITED. We expect this to be
-  // WIRETYPE_LENGTH_DELIMITED because the proto defines "messages" field as
-  // the "bytes" type.
-  CHECK_EQ(WireFormatLite::WireType::WIRETYPE_LENGTH_DELIMITED,
-           WireFormatLite::GetTagWireType(messages_tag));
-
-  // Read the byte messages field, not including tags. If it is not successful,
-  // we likely need to wait for more bytes to be appended to the input stream to
-  // form a complete message. This function makes the assumption that we
-  // already know the field and read the tag to determine what field to read,
-  // which is why we need the checks above.
-  std::string messages_field_bytes;
-  if (!WireFormatLite::ReadBytes(input_stream, &messages_field_bytes))
-    return false;
-
-  // Now that we have a complete "StreamBody.messages" bytes field, we want to
-  // properly handle it. DelegateMessage allows us to transform the bytes
-  // message we received to a ReceiveMessagesResponse, and run the appropriate
-  // callback depending on the response body. Then we can move along and read
-  // the next data from the buffer, if applicable.
-  DelegateMessage(messages_field_bytes);
-  return true;
 }
diff --git a/chrome/browser/nearby_sharing/instantmessaging/stream_parser.h b/chrome/browser/nearby_sharing/instantmessaging/stream_parser.h
index 3ce8eafe..f937489a 100644
--- a/chrome/browser/nearby_sharing/instantmessaging/stream_parser.h
+++ b/chrome/browser/nearby_sharing/instantmessaging/stream_parser.h
@@ -11,18 +11,6 @@
 #include "base/strings/string_piece.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace google {
-namespace protobuf {
-namespace io {
-class CodedInputStream;
-}  // namespace io
-}  // namespace protobuf
-}  // namespace google
-
-namespace net {
-class GrowableIOBuffer;
-}  // namespace net
-
 namespace chrome_browser_nearby_sharing_instantmessaging {
 class StreamBody;
 }  // namespace chrome_browser_nearby_sharing_instantmessaging
@@ -36,22 +24,19 @@
       base::OnceClosure fastpath_ready);
   ~StreamParser();
 
-  // Appends the stream data (which should be the partial or full serialized
-  // StreamBody).
   void Append(base::StringPiece data);
 
  private:
-  void DelegateMessage(const std::string& message);
-  void ParseStreamIfAvailable();
-
-  // Only supports reading single field type and assumes the StreamBody messages
-  // field is the only one we will ever see.
-  bool ParseNextMessagesFieldFromStream(
-      google::protobuf::io::CodedInputStream* input_stream);
+  absl::optional<chrome_browser_nearby_sharing_instantmessaging::StreamBody>
+  GetNextMessage();
+  void DelegateMessage(
+      const chrome_browser_nearby_sharing_instantmessaging::StreamBody&
+          stream_body);
 
   base::RepeatingCallback<void(const std::string& message)> listener_;
   base::OnceClosure fastpath_ready_callback_;
-  scoped_refptr<net::GrowableIOBuffer> unparsed_data_buffer_;
+  std::string data_;
+  int parsing_counter_for_metrics_ = 0;
 };
 
 #endif  // CHROME_BROWSER_NEARBY_SHARING_INSTANTMESSAGING_STREAM_PARSER_H_
diff --git a/chrome/browser/nearby_sharing/instantmessaging/stream_parser_unittest.cc b/chrome/browser/nearby_sharing/instantmessaging/stream_parser_unittest.cc
index dc5a7c5..2ecdba9 100644
--- a/chrome/browser/nearby_sharing/instantmessaging/stream_parser_unittest.cc
+++ b/chrome/browser/nearby_sharing/instantmessaging/stream_parser_unittest.cc
@@ -151,41 +151,3 @@
   EXPECT_EQ(1, MessagesReceived());
   EXPECT_EQ(messages, GetMessages());
 }
-
-// Check that the buffer resizes properly when a long message is sent at once.
-TEST_F(StreamParserTest, LongMessageAtOnce) {
-  std::vector<std::string> messages = {
-      "This is a long test message to see if the buffer breaks if we send a "
-      "big message: "
-      "111111111111111111111111111111111111111111111111111111111111111111111111"
-      "111111111111111111111111111111111111111111111111111111111111111111111111"
-      "111111111111111111111111111111111111111111111111111111111111111111111111"
-      "111111111111111111111111111111111111111111111111111111111111111111111111"
-      "111111111111111111111111111111111111111111111111111111111111111111111111"
-      "111111111111111111111111111111111111111111111111111111111111111111111111"
-      "111111"};
-  chrome_browser_nearby_sharing_instantmessaging::StreamBody stream_body =
-      BuildProto(messages);
-  GetStreamParser().Append(stream_body.SerializeAsString());
-
-  EXPECT_EQ(1, MessagesReceived());
-  EXPECT_EQ(messages, GetMessages());
-}
-
-// Check that when we have a tag failure, no message is received.
-TEST_F(StreamParserTest, TagFailure) {
-  std::string message = "";
-  GetStreamParser().Append(message);
-  EXPECT_EQ(0, MessagesReceived());
-
-  char bytes[3] = {0x00, 0xf0, 0xab};
-  GetStreamParser().Append(bytes);
-  EXPECT_EQ(0, MessagesReceived());
-}
-
-// Check that when we have a ReadBytes failure, no message is received.
-TEST_F(StreamParserTest, ReadBytesFailure) {
-  char bytes[6] = {0x00, 0xf0, 0xab, 0xf0, 0xab, 0xf0};
-  GetStreamParser().Append(bytes);
-  EXPECT_EQ(0, MessagesReceived());
-}
diff --git a/chrome/browser/notifications/notifier_state_tracker.cc b/chrome/browser/notifications/notifier_state_tracker.cc
index 5529e0d1e..5044c68 100644
--- a/chrome/browser/notifications/notifier_state_tracker.cc
+++ b/chrome/browser/notifications/notifier_state_tracker.cc
@@ -134,7 +134,7 @@
     if (!base::Contains(update->GetList(), id))
       update->Append(std::move(id));
   } else {
-    update->Remove(id, nullptr);
+    update->EraseListValue(id);
   }
 }
 
diff --git a/chrome/browser/password_check/android/password_check_manager.cc b/chrome/browser/password_check/android/password_check_manager.cc
index 71f2594..7f88199 100644
--- a/chrome/browser/password_check/android/password_check_manager.cc
+++ b/chrome/browser/password_check/android/password_check_manager.cc
@@ -8,7 +8,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/password_check/android/password_check_bridge.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
 #include "components/password_manager/core/browser/password_form.h"
@@ -336,7 +336,7 @@
 
 bool PasswordCheckManager::CanUseAccountCheck() const {
   SyncState sync_state = password_manager_util::GetPasswordSyncState(
-      ProfileSyncServiceFactory::GetForProfile(profile_));
+      SyncServiceFactory::GetForProfile(profile_));
   switch (sync_state) {
     case SyncState::kNotSyncing:
       ABSL_FALLTHROUGH_INTENDED;
@@ -379,7 +379,7 @@
 
 bool PasswordCheckManager::ShouldFetchPasswordScripts() const {
   SyncState sync_state = password_manager_util::GetPasswordSyncState(
-      ProfileSyncServiceFactory::GetForProfile(profile_));
+      SyncServiceFactory::GetForProfile(profile_));
 
   // Password change scripts are using password generation, so automatic
   // password change should not be offered to non sync users.
diff --git a/chrome/browser/password_check/android/password_check_manager_unittest.cc b/chrome/browser/password_check/android/password_check_manager_unittest.cc
index 42b7c35..4f876e5 100644
--- a/chrome/browser/password_check/android/password_check_manager_unittest.cc
+++ b/chrome/browser/password_check/android/password_check_manager_unittest.cc
@@ -18,7 +18,7 @@
 #include "chrome/browser/password_manager/bulk_leak_check_service_factory.h"
 #include "chrome/browser/password_manager/password_manager_test_util.h"
 #include "chrome/browser/password_manager/password_scripts_fetcher_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/password_manager/core/browser/bulk_leak_check_service.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
@@ -127,11 +127,10 @@
 }
 
 syncer::TestSyncService* CreateAndUseSyncService(Profile* profile) {
-  return ProfileSyncServiceFactory::GetInstance()
-      ->SetTestingSubclassFactoryAndUse(
-          profile, base::BindLambdaForTesting([](content::BrowserContext*) {
-            return std::make_unique<syncer::TestSyncService>();
-          }));
+  return SyncServiceFactory::GetInstance()->SetTestingSubclassFactoryAndUse(
+      profile, base::BindLambdaForTesting([](content::BrowserContext*) {
+        return std::make_unique<syncer::TestSyncService>();
+      }));
 }
 
 PasswordForm MakeSavedPassword(base::StringPiece signon_realm,
diff --git a/chrome/browser/password_manager/affiliation_service_factory.cc b/chrome/browser/password_manager/affiliation_service_factory.cc
index 7e50ef00..3ef34c51 100644
--- a/chrome/browser/password_manager/affiliation_service_factory.cc
+++ b/chrome/browser/password_manager/affiliation_service_factory.cc
@@ -6,7 +6,7 @@
 
 #include "base/no_destructor.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/password_manager/core/browser/site_affiliation/affiliation_service_impl.h"
 #include "content/public/browser/browser_context.h"
@@ -35,7 +35,7 @@
     content::BrowserContext* context) const {
   Profile* profile = Profile::FromBrowserContext(context);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   network::SharedURLLoaderFactory* url_loader_factory =
       context->GetDefaultStoragePartition()
           ->GetURLLoaderFactoryForBrowserProcess()
diff --git a/chrome/browser/password_manager/android/auto_signin_first_run_dialog_android.cc b/chrome/browser/password_manager/android/auto_signin_first_run_dialog_android.cc
index b1b17f0..8c981ecc 100644
--- a/chrome/browser/password_manager/android/auto_signin_first_run_dialog_android.cc
+++ b/chrome/browser/password_manager/android/auto_signin_first_run_dialog_android.cc
@@ -9,7 +9,6 @@
 #include "chrome/android/chrome_jni_headers/AutoSigninFirstRunDialog_jni.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/password_manager/android/password_infobar_utils.cc b/chrome/browser/password_manager/android/password_infobar_utils.cc
index 91fa6c87..242dc79 100644
--- a/chrome/browser/password_manager/android/password_infobar_utils.cc
+++ b/chrome/browser/password_manager/android/password_infobar_utils.cc
@@ -6,7 +6,6 @@
 
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
diff --git a/chrome/browser/password_manager/android/save_password_infobar_delegate_android.cc b/chrome/browser/password_manager/android/save_password_infobar_delegate_android.cc
index f7a0bd53..34c1851 100644
--- a/chrome/browser/password_manager/android/save_password_infobar_delegate_android.cc
+++ b/chrome/browser/password_manager/android/save_password_infobar_delegate_android.cc
@@ -12,7 +12,7 @@
 #include "base/values.h"
 #include "chrome/browser/password_manager/android/password_infobar_utils.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/android/infobars/save_password_infobar.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/grit/chromium_strings.h"
@@ -34,7 +34,7 @@
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   // is_smartlock_branding_enabled indicates whether the user is syncing
   // passwords to their Google Account.
   bool is_smartlock_branding_enabled =
diff --git a/chrome/browser/password_manager/android/save_password_message_delegate.cc b/chrome/browser/password_manager/android/save_password_message_delegate.cc
index 8e020a3..7078768 100644
--- a/chrome/browser/password_manager/android/save_password_message_delegate.cc
+++ b/chrome/browser/password_manager/android/save_password_message_delegate.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/password_manager/android/password_infobar_utils.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/messages/android/message_dispatcher_bridge.h"
@@ -49,7 +49,7 @@
   // passwords to their Google Account.
   const bool is_saving_google_account =
       password_bubble_experiment::IsSmartLockUser(
-          ProfileSyncServiceFactory::GetForProfile(profile));
+          SyncServiceFactory::GetForProfile(profile));
 
   absl::optional<AccountInfo> account_info =
       password_manager::GetAccountInfoForPasswordMessages(
diff --git a/chrome/browser/password_manager/android/update_password_infobar_delegate_android.cc b/chrome/browser/password_manager/android/update_password_infobar_delegate_android.cc
index cec0ec6..29ed0d5 100644
--- a/chrome/browser/password_manager/android/update_password_infobar_delegate_android.cc
+++ b/chrome/browser/password_manager/android/update_password_infobar_delegate_android.cc
@@ -9,7 +9,7 @@
 #include "chrome/browser/password_manager/android/password_infobar_utils.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/android/infobars/update_password_infobar.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/grit/chromium_strings.h"
@@ -34,7 +34,7 @@
   // passwords to their Google Account.
   const bool is_smartlock_branding_enabled =
       password_bubble_experiment::IsSmartLockUser(
-          ProfileSyncServiceFactory::GetForProfile(
+          SyncServiceFactory::GetForProfile(
               Profile::FromBrowserContext(web_contents->GetBrowserContext())));
   infobars::ContentInfoBarManager::FromWebContents(web_contents)
       ->AddInfoBar(std::make_unique<UpdatePasswordInfoBar>(
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index b34bd0d3..92c590b 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -34,7 +34,7 @@
 #include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
 #include "chrome/browser/safe_browsing/user_interaction_observer.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/browser/ui/passwords/password_generation_popup_controller_impl.h"
@@ -177,8 +177,8 @@
 namespace {
 
 const syncer::SyncService* GetSyncService(Profile* profile) {
-  if (ProfileSyncServiceFactory::HasSyncService(profile))
-    return ProfileSyncServiceFactory::GetForProfile(profile);
+  if (SyncServiceFactory::HasSyncService(profile))
+    return SyncServiceFactory::GetForProfile(profile);
   return nullptr;
 }
 
@@ -644,7 +644,7 @@
 password_manager::SyncState ChromePasswordManagerClient::GetPasswordSyncState()
     const {
   const syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   return password_manager_util::GetPasswordSyncState(sync_service);
 }
 
@@ -1169,9 +1169,8 @@
     : content::WebContentsObserver(web_contents),
       profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
       password_manager_(this),
-      password_feature_manager_(
-          profile_->GetPrefs(),
-          ProfileSyncServiceFactory::GetForProfile(profile_)),
+      password_feature_manager_(profile_->GetPrefs(),
+                                SyncServiceFactory::GetForProfile(profile_)),
       httpauth_manager_(this),
       password_reuse_detection_manager_(this),
       driver_factory_(nullptr),
@@ -1417,7 +1416,7 @@
     return false;
 
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   if (!sync_service || !sync_service->IsSyncFeatureActive() ||
       sync_service->GetUserSettings()->IsUsingExplicitPassphrase()) {
     return false;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index 2833e14..c67e170 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -24,7 +24,7 @@
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/user_interaction_observer.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/autofill/content/common/mojom/autofill_agent.mojom.h"
@@ -216,7 +216,7 @@
   syncer::TestSyncService* SetupBasicTestSync() {
     syncer::TestSyncService* sync_service =
         static_cast<syncer::TestSyncService*>(
-            ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+            SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
                 profile(), base::BindRepeating(&CreateTestSyncService)));
     return sync_service;
   }
diff --git a/chrome/browser/password_manager/generated_password_leak_detection_pref.cc b/chrome/browser/password_manager/generated_password_leak_detection_pref.cc
index 2cd3b2b..4b788d4 100644
--- a/chrome/browser/password_manager/generated_password_leak_detection_pref.cc
+++ b/chrome/browser/password_manager/generated_password_leak_detection_pref.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_ui_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/common/extensions/api/settings_private.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
@@ -77,7 +77,7 @@
   if (auto* identity_manager = IdentityManagerFactory::GetForProfile(profile))
     identity_manager_observer_.Observe(identity_manager);
 
-  if (auto* sync_service = ProfileSyncServiceFactory::GetForProfile(profile))
+  if (auto* sync_service = SyncServiceFactory::GetForProfile(profile))
     sync_service_observer_.Observe(sync_service);
 }
 
diff --git a/chrome/browser/password_manager/generated_password_leak_detection_pref_unittest.cc b/chrome/browser/password_manager/generated_password_leak_detection_pref_unittest.cc
index 79df1ce..f9d355d0 100644
--- a/chrome/browser/password_manager/generated_password_leak_detection_pref_unittest.cc
+++ b/chrome/browser/password_manager/generated_password_leak_detection_pref_unittest.cc
@@ -9,7 +9,7 @@
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_test_util.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
@@ -72,7 +72,7 @@
       BuildTestProfile(test_url_loader_factory_);
   syncer::TestSyncService* sync_service_ =
       static_cast<syncer::TestSyncService*>(
-          ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+          SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
               profile(),
               base::BindRepeating(&BuildTestSyncService)));
   IdentityTestEnvironmentProfileAdaptor identity_test_env_adaptor_{
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index ba89f2d..9bda90d 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -3845,8 +3845,8 @@
   controller = autofill_client->popup_controller_for_testing().get();
   ASSERT_TRUE(controller);
   EXPECT_EQ(2, controller->GetLineCount());
-  EXPECT_EQ(u"user", controller->GetSuggestionValueAt(0));
-  EXPECT_NE(u"admin", controller->GetSuggestionValueAt(1));
+  EXPECT_EQ(u"user", controller->GetSuggestionMainTextAt(0));
+  EXPECT_NE(u"admin", controller->GetSuggestionMainTextAt(1));
 
   // The username_field should get re-filled with "user" instead of "admin".
   WaitForElementValue("username_field", "user");
diff --git a/chrome/browser/password_manager/password_manager_captured_sites_interactive_uitest.cc b/chrome/browser/password_manager/password_manager_captured_sites_interactive_uitest.cc
index 7197c10..e3198d1 100644
--- a/chrome/browser/password_manager/password_manager_captured_sites_interactive_uitest.cc
+++ b/chrome/browser/password_manager/password_manager_captured_sites_interactive_uitest.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/autofill/captured_sites_test_utils.h"
 #include "chrome/browser/password_manager/password_manager_test_base.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/tab_dialogs.h"
 #include "components/autofill/core/common/autofill_features.h"
@@ -173,7 +173,7 @@
                   // Set up a TestSyncService which will happily return
                   // "everything is active" so that password generation is
                   // considered enabled.
-                  ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+                  SyncServiceFactory::GetInstance()->SetTestingFactory(
                       context, base::BindRepeating(&BuildTestSyncService));
 
                   PasswordStoreFactory::GetInstance()->SetTestingFactory(
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc
index f932c1d..a7436edc 100644
--- a/chrome/browser/password_manager/password_manager_test_base.cc
+++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -19,7 +19,7 @@
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
@@ -703,7 +703,7 @@
                 // Set up a TestSyncService which will happily return
                 // "everything is active" so that password generation is
                 // considered enabled.
-                ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+                SyncServiceFactory::GetInstance()->SetTestingFactory(
                     context, base::BindRepeating(&BuildTestSyncService));
 
                 PasswordStoreFactory::GetInstance()->SetTestingFactory(
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc
index 5c2d7620..edd9a87f 100644
--- a/chrome/browser/password_manager/password_store_factory.cc
+++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -16,7 +16,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "chrome/common/chrome_paths_internal.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -93,7 +93,7 @@
   if (!password_store)
     return;
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
 
   password_manager::ToggleAffiliationBasedMatchingBasedOnPasswordSyncedState(
       password_store.get(), sync_service,
diff --git a/chrome/browser/policy/test/url_blacklist_policy_browsertest.cc b/chrome/browser/policy/test/url_blacklist_policy_browsertest.cc
index 26fa2ad..3b09d1d 100644
--- a/chrome/browser/policy/test/url_blacklist_policy_browsertest.cc
+++ b/chrome/browser/policy/test/url_blacklist_policy_browsertest.cc
@@ -336,7 +336,7 @@
   CheckURLIsBlocked(browser(), file_path2);
 
   // Replace the URLblacklist with disabling the file scheme.
-  blacklist.Remove(base::Value("file://*"), nullptr);
+  blacklist.EraseListValue(base::Value("file://*"));
   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
   UpdateProviderPolicy(policies);
diff --git a/chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.cc b/chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.cc
index 9756e160..d1351fe 100644
--- a/chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.cc
+++ b/chrome/browser/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.cc
@@ -10,7 +10,7 @@
 #include "chrome/browser/prefetch/no_state_prefetch/chrome_no_state_prefetch_manager_delegate.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
 #include "extensions/buildflags/buildflags.h"
@@ -46,7 +46,7 @@
   // PrerenderLocalPredictor observers the history visit DB.
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(predictors::PredictorDatabaseFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 NoStatePrefetchManagerFactory::~NoStatePrefetchManagerFactory() {}
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 14b002b5..e69c5fd1 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -578,6 +578,10 @@
 #endif
 const char kSessionExitedCleanly[] = "profile.exited_cleanly";
 
+// Deprecated 05/2021
+const char kSpellCheckBlacklistedDictionaries[] =
+    "spellcheck.blacklisted_dictionaries";
+
 // Register local state used only for migration (clearing or moving to a new
 // key).
 void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) {
@@ -713,6 +717,8 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   registry->RegisterInt64Pref(kFeatureUsageDailySampleFingerprint, 0);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+  registry->RegisterListPref(kSpellCheckBlacklistedDictionaries);
 }
 
 }  // namespace
@@ -1437,6 +1443,9 @@
   profile_prefs->ClearPref(kFeatureUsageDailySampleFingerprint);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+  // Added 05/2021
+  profile_prefs->ClearPref(kSpellCheckBlacklistedDictionaries);
+
   // Please don't delete the following line. It is used by PRESUBMIT.py.
   // END_MIGRATE_OBSOLETE_PROFILE_PREFS
 }
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
index e7e2de2..7560ecc 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -33,7 +33,7 @@
           BrowserContextDependencyManager::GetInstance()) {
   DependsOn(HostContentSettingsMapFactory::GetInstance());
   DependsOn(CookieSettingsFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
 }
 
@@ -45,7 +45,7 @@
       HostContentSettingsMapFactory::GetForProfile(profile),
       CookieSettingsFactory::GetForProfile(profile).get(), profile->GetPrefs(),
       profile->GetProfilePolicyConnector()->policy_service(),
-      ProfileSyncServiceFactory::GetForProfile(profile),
+      SyncServiceFactory::GetForProfile(profile),
       IdentityManagerFactory::GetForProfile(profile));
 }
 
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
index 08d0ceec..877bb11 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_unittest.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/federated_learning/floc_id_provider.h"
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
diff --git a/chrome/browser/profiles/bookmark_model_loaded_observer.cc b/chrome/browser/profiles/bookmark_model_loaded_observer.cc
index e6e6acee..4d87f08 100644
--- a/chrome/browser/profiles/bookmark_model_loaded_observer.cc
+++ b/chrome/browser/profiles/bookmark_model_loaded_observer.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/profiles/bookmark_model_loaded_observer.h"
 
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 
 using bookmarks::BookmarkModel;
@@ -19,7 +19,7 @@
 void BookmarkModelLoadedObserver::BookmarkModelLoaded(BookmarkModel* model,
                                                       bool ids_reassigned) {
   // Causes lazy-load if sync is enabled.
-  ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
+  SyncServiceFactory::GetInstance()->GetForProfile(profile_);
   model->RemoveObserver(this);
   delete this;
 }
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index 7bbdc118..33cc78e2 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -87,7 +87,7 @@
 #include "chrome/browser/signin/signin_profile_attributes_updater_factory.h"
 #include "chrome/browser/ssl/sct_reporting_service_factory.h"
 #include "chrome/browser/sync/model_type_store_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/translate/translate_ranker_factory.h"
@@ -401,7 +401,7 @@
   prerender::NoStatePrefetchManagerFactory::GetInstance();
   PrivacySandboxSettingsFactory::GetInstance();
   ProfileNetworkContextServiceFactory::GetInstance();
-  ProfileSyncServiceFactory::GetInstance();
+  SyncServiceFactory::GetInstance();
 #if !defined(OS_ANDROID)
   ProfileThemeUpdateServiceFactory::GetInstance();
 #endif
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 75e3b52..d45753e 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -70,7 +70,7 @@
 #include "chrome/browser/signin/account_reconcilor_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/sync/sync_promo_ui.h"
 #include "chrome/browser/unified_consent/unified_consent_service_factory.h"
@@ -1894,9 +1894,9 @@
       observer.OnProfileMarkedForPermanentDeletion(profile);
 
     // Disable sync for doomed profile.
-    if (ProfileSyncServiceFactory::HasSyncService(profile)) {
+    if (SyncServiceFactory::HasSyncService(profile)) {
       syncer::SyncService* sync_service =
-          ProfileSyncServiceFactory::GetForProfile(profile);
+          SyncServiceFactory::GetForProfile(profile);
       // Ensure data is cleared even if sync was already off.
       sync_service->StopAndClear();
     }
diff --git a/chrome/browser/resources/download_shelf/download_item.html b/chrome/browser/resources/download_shelf/download_item.html
index c615b9cb..013e9748 100644
--- a/chrome/browser/resources/download_shelf/download_item.html
+++ b/chrome/browser/resources/download_shelf/download_item.html
@@ -3,7 +3,7 @@
   --button-hover-color: rgba(var(--google-grey-900-rgb), .1);
   --button-icon-stroke-color: var(--google-grey-refresh-700);
   --pi: 3.14159265358979;
-  --spinner-color-rgb: var(--google-grey-900-rgb);
+  --spinner-color-rgb: var(--google-blue-600-rgb);
   --text-width: 140px;
   --warn-text-width: 241px;
   --warn-keep-text-width: 318px;
@@ -81,9 +81,22 @@
   stroke-width: var(--stroke-width);
 }
 
+/* Animate opacity from 1 -> 0 -> 1 -> 0 -> 1 -> 0. */
+.download-complete-animation {
+  animation-duration: 1s;
+  animation-iteration-count: 2.5;
+  animation-name: spinner-flash;
+}
+
+@keyframes spinner-flash {
+  0% {opacity: 1;}
+  50% {opacity: 0;}
+  100% {opacity: 1;}
+}
+
 /* Display progress spinner only when state=DownloadState.kInProgress. */
-.download-item:not([data-state='2']) .progress-circle,
-.download-item:not([data-state='2']) .progress-spinner {
+.download-item:not([data-state='2']) .progress-indicator:not(.download-complete-animation) .progress-circle,
+.download-item:not([data-state='2']) .progress-indicator:not(.download-complete-animation) .progress-spinner {
   display: none;
 }
 
@@ -208,9 +221,6 @@
 [data-display-mode^='warn'] #file-icon,
 [data-display-mode^='warn'] #filename,
 [data-display-mode^='warn'] #status-text,
-[data-display-mode^='warn'] .progress-indicator {
-  display: none;
-}
 
 [data-display-mode='warn-keep'] #keep-button {
   display: block;
diff --git a/chrome/browser/resources/download_shelf/download_item.js b/chrome/browser/resources/download_shelf/download_item.js
index 9849787..68db414 100644
--- a/chrome/browser/resources/download_shelf/download_item.js
+++ b/chrome/browser/resources/download_shelf/download_item.js
@@ -39,6 +39,9 @@
     this.item_;
 
     /** @private {boolean} */
+    this.downloadUpdated_ = false;
+
+    /** @private {boolean} */
     this.opening_ = false;
 
     /** @property {boolean} */
@@ -57,6 +60,18 @@
     this.$('#keep-button')
         .addEventListener('click', e => this.onKeepButtonClick_(e));
     this.addEventListener('contextmenu', e => this.onContextMenu_(e));
+
+    this.$('.progress-indicator').addEventListener('animationend', () => {
+      this.$('.progress-indicator')
+          .classList.remove('download-complete-animation');
+    });
+  }
+
+  /** @param {DownloadItem} item */
+  onDownloadUpdated(item) {
+    this.downloadUpdated_ = true;
+    this.item_ = item;
+    this.update_();
   }
 
   /** @param {DownloadItem} value */
@@ -121,18 +136,25 @@
     statusTextElement.innerText = statusText;
 
     downloadElement.dataset.state = item.state;
-    switch (item.state) {
-      case DownloadState.kInProgress:
-        this.progress = item.totalBytes > 0 ?
-            Number(item.receivedBytes) / Number(item.totalBytes) :
-            0;
-        break;
-      case DownloadState.kComplete:
-        this.progress = 1;
-        break;
-      case DownloadState.kInterrupted:
-        this.progress = 0;
-        break;
+    if (item.mode === DownloadMode.kNormal) {
+      switch (item.state) {
+        case DownloadState.kInProgress:
+          this.progress = item.totalBytes > 0 ?
+              Number(item.receivedBytes) / Number(item.totalBytes) :
+              0;
+          break;
+        case DownloadState.kComplete:
+          this.progress = 1;
+          // Only start animation if it's called from OnDownloadUpdated.
+          if (this.downloadUpdated_) {
+            this.$('.progress-indicator')
+                .classList.add('download-complete-animation');
+          }
+          break;
+        case DownloadState.kInterrupted:
+          this.progress = 0;
+          break;
+      }
     }
 
     if (item.isPaused) {
@@ -157,6 +179,8 @@
 
     this.$('#keep-button').innerText = item.warningConfirmButtonText;
     this.$('#warning-text').innerText = this.clampedWarningText_;
+
+    this.downloadUpdated_ = false;
   }
 
   /** @param {number} value */
diff --git a/chrome/browser/resources/download_shelf/download_list.js b/chrome/browser/resources/download_shelf/download_list.js
index b23b58c..5f160ff 100644
--- a/chrome/browser/resources/download_shelf/download_list.js
+++ b/chrome/browser/resources/download_shelf/download_list.js
@@ -76,7 +76,10 @@
               this.items_.findIndex(item => item.id === downloadItem.id);
           if (index >= 0) {
             this.items_[index] = downloadItem;
-            this.updateElements_();
+            const element = this.elements_[index];
+            if (element) {
+              element.onDownloadUpdated(downloadItem);
+            }
           }
         }),
         callbackRouter.onDownloadErased.addListener((downloadId) => {
diff --git a/chrome/browser/resources/read_later/side_panel/app.html b/chrome/browser/resources/read_later/side_panel/app.html
index 9e63db9..266f321 100644
--- a/chrome/browser/resources/read_later/side_panel/app.html
+++ b/chrome/browser/resources/read_later/side_panel/app.html
@@ -1,5 +1,6 @@
 <style>
   :host {
+    color: var(--cr-primary-text-color);
     display: flex;
     flex-direction: column;
     height: 100%;
diff --git a/chrome/browser/resources/read_later/side_panel/app.js b/chrome/browser/resources/read_later/side_panel/app.js
index f9ec208..2daff341 100644
--- a/chrome/browser/resources/read_later/side_panel/app.js
+++ b/chrome/browser/resources/read_later/side_panel/app.js
@@ -7,6 +7,7 @@
 // directory, with read_later being moved into a subdirectory within side_panel.
 
 import 'chrome://resources/cr_elements/cr_tabs/cr_tabs.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/polymer/v3_0/iron-pages/iron-pages.js';
 import './bookmarks_list.js';
 import '../app.js'; /* <read-later-app> */
diff --git a/chrome/browser/resources/read_later/side_panel/side_panel.html b/chrome/browser/resources/read_later/side_panel/side_panel.html
index fd1b04c..a0148bb 100644
--- a/chrome/browser/resources/read_later/side_panel/side_panel.html
+++ b/chrome/browser/resources/read_later/side_panel/side_panel.html
@@ -4,6 +4,7 @@
   <meta charset="utf-8">
   <title>Side panel</title>
   <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
+  <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
   <style>
     html,
     body {
@@ -14,8 +15,15 @@
     }
 
     body {
+      background: white;
       overflow: auto;
     }
+
+    @media (prefers-color-scheme: dark) {
+      body {
+        background: var(--google-grey-900);
+      }
+    }
   </style>
 </head>
 <body>
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 b761aa6..4c222789 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
@@ -52,8 +52,9 @@
         font-weight: 400;
         height: 30px;
         line-height: var(--cr-form-field-label-line-height);
+        padding-top: 8px;
         position: absolute;
-        top: 58px;
+        top: 50px;
         width: 100%;
       }
 
@@ -69,7 +70,7 @@
       #inputCount {
         position: absolute;
         right: 0;
-        top: 0;
+        top: 8px;
       }
 
       :host-context([dir='rtl']) #inputCount {
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 7ce6b313..0d400cf 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.html
@@ -32,10 +32,13 @@
   <template>
     <style include="cr-shared-style os-settings-icons settings-shared iron-flex">
       #networkListDiv {
-        margin-top: var(--cr-section-vertical-margin);
         min-height: var(--settings-row-min-height);
       }
 
+      :host(:not([is-showing-vpn_])) #networkListDiv {
+        margin-top: var(--cr-section-vertical-margin);
+      }
+
       #cellularNetworkList {
         /* No extra margin-top when displaying the cellular network list. */
         margin-top: calc(-1*var(--cr-section-vertical-margin));
@@ -146,7 +149,7 @@
     <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="[[matchesType_('VPN', deviceState)]]">
+        <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_]]">
@@ -219,7 +222,7 @@
                 "[[getNoNetworksInnerHtml_(deviceState, tetherDeviceState)]]">
         </settings-localized-link>
 
-        <template is="dom-if" if="[[matchesType_('VPN', deviceState)]]">
+        <template is="dom-if" if="[[isShowingVpn_]]">
           <!-- Third party VPNs. -->
           <template is="dom-repeat"
               items="[[getVpnProviders_(vpnProviders, thirdPartyVpns_)]]">
@@ -245,7 +248,7 @@
       </div>
 
       <template is="dom-if"
-          if="[[shouldShowVpnPreferences_(isManaged_, deviceState)]]">
+          if="[[shouldShowVpnPreferences_(isManaged_, isShowingVpn_)]]">
         <div class="settings-box first">
           <h2>$i18n{networkVpnPreferences}</h2>
         </div>
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 fe753226..db3d40c 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_subpage.js
@@ -91,6 +91,13 @@
       },
     },
 
+    /** @private */
+    isShowingVpn_: {
+      type: Boolean,
+      computed: 'computeIsShowingVpn_(deviceState)',
+      reflectToAttribute: true,
+    },
+
     /**
      * Whether the browser/ChromeOS is managed by their organization
      * through enterprise policies.
@@ -992,6 +999,18 @@
   },
 
   /**
+   * @return {boolean}
+   * @private
+   */
+  computeIsShowingVpn_() {
+    if (!this.deviceState) {
+      return false;
+    }
+    return this.matchesType_(
+        OncMojo.getNetworkTypeString(mojom.NetworkType.kVPN), this.deviceState);
+  },
+
+  /**
    * Tells when VPN preferences section should be displayed. It is
    * displayed when the preferences are applicable to the current device.
    * @return {boolean}
@@ -1004,7 +1023,7 @@
     // For now the section only contain always-on VPN settings. It should not be
     // displayed on managed devices while the legacy always-on VPN based on ARC
     // is not replaced/extended by the new implementation.
-    return !this.isManaged_ && this.matchesType_('VPN', this.deviceState);
+    return !this.isManaged_ && this.isShowingVpn_;
   },
 
   /**
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_child.html b/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
index 65b226a..0e2e38a 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
@@ -1,6 +1,7 @@
-<style include="cr-shared-style settings-shared iron-flex">
-  :host([row-clickable]) .cr-row {
-    cursor: pointer;
+<style include="cr-shared-style settings-shared iron-flex cr-actionable-row-style">
+  :host {
+    border-top: var(--cr-separator-line);
+    padding: 0 var(--cr-section-padding);
   }
 
   :host([row-clickable]) #managedIcon {
@@ -34,36 +35,33 @@
     }
   }
 </style>
-<div class="cr-row">
-  <iron-icon id="statusIcon"
-      icon="[[getStatusIcon_(iconStatus)]]"
-      src="[[getStatusIconSrc_(iconStatus)]]"
-      class$="[[getStatusIconClass_(iconStatus)]]"
-      role="img"
-      aria-label="[[getStatusIconAriaLabel_(iconStatus)]]">
-  </iron-icon>
-  <div class="flex cr-padded-text">
-    <div id="label">[[label]]</div>
-    <div id="subLabel" class="secondary" no-search
-        inner-h-t-m-l="[[subLabel]]">
-    </div>
+<iron-icon id="statusIcon"
+    icon="[[getStatusIcon_(iconStatus)]]"
+    src="[[getStatusIconSrc_(iconStatus)]]"
+    class$="[[getStatusIconClass_(iconStatus)]]"
+    role="img"
+    aria-label="[[getStatusIconAriaLabel_(iconStatus)]]">
+</iron-icon>
+<div class="flex cr-padded-text">
+  <div id="label">[[label]]</div>
+  <div id="subLabel" class="secondary" no-search inner-h-t-m-l="[[subLabel]]">
   </div>
-  <template is="dom-if" if="[[showButton_(buttonLabel)]]" restamp>
-    <cr-button id="button" class$="[[buttonClass]]" on-click="onButtonClick_"
-        aria-label="[[buttonAriaLabel]]" no-search>
-      [[buttonLabel]]
-    </cr-button>
-  </template>
-  <template is="dom-if" if="[[showManagedIcon_(managedIcon)]]">
-    <iron-icon id="managedIcon" icon="[[managedIcon]]" aria-hidden="true">
-    </iron-icon>
-  </template>
-  <template is="dom-if" if="[[rowClickable]]">
-    <cr-icon-button id="rowClickableIndicator"
-        iron-icon="[[rowClickableIcon_]]"
-        aria-describedby="subLabel"
-        aria-labelledby="label"
-        aria-roledescription$="[[getRoleDescription_(rowClickableIcon_)]]">
-    </cr-icon-button>
-  </template>
 </div>
+<template is="dom-if" if="[[showButton_(buttonLabel)]]" restamp>
+  <cr-button id="button" class$="[[buttonClass]]" on-click="onButtonClick_"
+      aria-label="[[buttonAriaLabel]]" no-search>
+    [[buttonLabel]]
+  </cr-button>
+</template>
+<template is="dom-if" if="[[showManagedIcon_(managedIcon)]]">
+  <iron-icon id="managedIcon" icon="[[managedIcon]]" aria-hidden="true">
+  </iron-icon>
+</template>
+<template is="dom-if" if="[[rowClickable]]">
+  <cr-icon-button id="rowClickableIndicator"
+      iron-icon="[[rowClickableIcon_]]"
+      aria-describedby="subLabel"
+      aria-labelledby="label"
+      aria-roledescription$="[[getRoleDescription_(rowClickableIcon_)]]">
+  </cr-icon-button>
+</template>
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_child.js
index 40e1e4b..5d1ec6a 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_child.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_child.js
@@ -8,6 +8,7 @@
  * have in common. It is used by all safety check elements: parent, updates,
  * passwors, etc.
  */
+import 'chrome://resources/cr_elements/cr_actionable_row_style.m.js';
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
@@ -67,6 +68,7 @@
       type: Boolean,
       value: false,
       reflectToAttribute: true,
+      observer: 'onRowClickableChanged_',
     },
 
     // Is the row directed to external link.
@@ -194,5 +196,11 @@
     return this.rowClickableIcon_ === 'cr:arrow-right' ?
         this.i18n('subpageArrowRoleDescription') :
         '';
+  },
+
+  /** @private */
+  onRowClickableChanged_() {
+    // For cr-actionable-row-style.
+    this.toggleAttribute('effectively-disabled_', !this.rowClickable);
   }
 });
diff --git a/chrome/browser/resources/welcome/BUILD.gn b/chrome/browser/resources/welcome/BUILD.gn
index f0c7e59..7a04bed 100644
--- a/chrome/browser/resources/welcome/BUILD.gn
+++ b/chrome/browser/resources/welcome/BUILD.gn
@@ -73,7 +73,7 @@
     "google_apps/google_app_proxy.ts",
     "google_apps/google_apps_metrics_proxy.ts",
     "landing_view_proxy.ts",
-    "navigation_behavior.ts",
+    "navigation_mixin.ts",
     "ntp_background/ntp_background_metrics_proxy.ts",
     "ntp_background/ntp_background_proxy.ts",
     "set_as_default/nux_set_as_default_proxy.ts",
@@ -152,7 +152,7 @@
     "google_apps/nux_google_apps.ts",
     "landing_view.ts",
     "landing_view_proxy.ts",
-    "navigation_behavior.ts",
+    "navigation_mixin.ts",
     "ntp_background/ntp_background_metrics_proxy.ts",
     "ntp_background/ntp_background_proxy.ts",
     "ntp_background/nux_ntp_background.ts",
diff --git a/chrome/browser/resources/welcome/google_apps/nux_google_apps.ts b/chrome/browser/resources/welcome/google_apps/nux_google_apps.ts
index 7bdd2b5..3496def 100644
--- a/chrome/browser/resources/welcome/google_apps/nux_google_apps.ts
+++ b/chrome/browser/resources/welcome/google_apps/nux_google_apps.ts
@@ -19,7 +19,7 @@
 import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js';
 import {afterNextRender, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {navigateToNextStep, NavigationMixin, NavigationMixinInterface} from '../navigation_behavior.js';
+import {navigateToNextStep, NavigationMixin, NavigationMixinInterface} from '../navigation_mixin.js';
 import {BookmarkBarManager, BookmarkProxy, BookmarkProxyImpl} from '../shared/bookmark_proxy.js';
 import {ModuleMetricsManager} from '../shared/module_metrics_proxy.js';
 import {stepIndicatorModel} from '../shared/nux_types.js';
diff --git a/chrome/browser/resources/welcome/landing_view.ts b/chrome/browser/resources/welcome/landing_view.ts
index b8b7675..1c7c8af 100644
--- a/chrome/browser/resources/welcome/landing_view.ts
+++ b/chrome/browser/resources/welcome/landing_view.ts
@@ -13,7 +13,7 @@
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {LandingViewProxy, LandingViewProxyImpl} from './landing_view_proxy.js';
-import {navigateTo, NavigationMixin, Routes} from './navigation_behavior.js';
+import {navigateTo, NavigationMixin, Routes} from './navigation_mixin.js';
 import {OnboardingBackgroundElement} from './shared/onboarding_background.js';
 import {WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
 
diff --git a/chrome/browser/resources/welcome/navigation_behavior.ts b/chrome/browser/resources/welcome/navigation_mixin.ts
similarity index 100%
rename from chrome/browser/resources/welcome/navigation_behavior.ts
rename to chrome/browser/resources/welcome/navigation_mixin.ts
diff --git a/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.ts b/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.ts
index 686539c9..00654a5 100644
--- a/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.ts
+++ b/chrome/browser/resources/welcome/ntp_background/nux_ntp_background.ts
@@ -17,7 +17,7 @@
 import {isRTL} from 'chrome://resources/js/util.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {navigateToNextStep, NavigationMixin, NavigationMixinInterface} from '../navigation_behavior.js';
+import {navigateToNextStep, NavigationMixin, NavigationMixinInterface} from '../navigation_mixin.js';
 import {ModuleMetricsManager} from '../shared/module_metrics_proxy.js';
 import {stepIndicatorModel} from '../shared/nux_types.js';
 
diff --git a/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.ts b/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.ts
index e49252e..4bb728c 100644
--- a/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.ts
+++ b/chrome/browser/resources/welcome/set_as_default/nux_set_as_default.ts
@@ -16,7 +16,7 @@
 import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {navigateToNextStep, NavigationMixin, NavigationMixinInterface} from '../navigation_behavior.js';
+import {navigateToNextStep, NavigationMixin, NavigationMixinInterface} from '../navigation_mixin.js';
 import {DefaultBrowserInfo, stepIndicatorModel} from '../shared/nux_types.js';
 
 import {NuxSetAsDefaultProxy, NuxSetAsDefaultProxyImpl} from './nux_set_as_default_proxy.js';
diff --git a/chrome/browser/resources/welcome/signin_view.ts b/chrome/browser/resources/welcome/signin_view.ts
index f9688e8..bb73c1d0 100644
--- a/chrome/browser/resources/welcome/signin_view.ts
+++ b/chrome/browser/resources/welcome/signin_view.ts
@@ -12,7 +12,7 @@
 
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {NavigationMixin} from './navigation_behavior.js';
+import {NavigationMixin} from './navigation_mixin.js';
 import {OnboardingBackgroundElement} from './shared/onboarding_background.js';
 import {SigninViewProxy, SigninViewProxyImpl} from './signin_view_proxy.js';
 import {WelcomeBrowserProxy, WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
diff --git a/chrome/browser/resources/welcome/welcome_app.ts b/chrome/browser/resources/welcome/welcome_app.ts
index 97f21ef..c4f9e26 100644
--- a/chrome/browser/resources/welcome/welcome_app.ts
+++ b/chrome/browser/resources/welcome/welcome_app.ts
@@ -17,7 +17,7 @@
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {NavigationMixin, Routes} from './navigation_behavior.js';
+import {NavigationMixin, Routes} from './navigation_mixin.js';
 import {NuxSetAsDefaultProxyImpl} from './set_as_default/nux_set_as_default_proxy.js';
 import {BookmarkBarManager} from './shared/bookmark_proxy.js';
 import {WelcomeBrowserProxyImpl} from './welcome_browser_proxy.js';
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 4355f2b..0aec976 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
@@ -15,7 +15,6 @@
 #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 "chrome/browser/sync/profile_sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/safe_browsing/core/browser/sync/sync_utils.h"
 #include "components/safe_browsing/core/common/utils.h"
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
index e14ef4a..f7b60adb 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -36,7 +36,7 @@
 #include "chrome/browser/safe_browsing/user_population.h"
 #include "chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -1543,8 +1543,7 @@
 }
 
 bool ChromePasswordProtectionService::IsPrimaryAccountSyncing() const {
-  syncer::SyncService* sync =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  syncer::SyncService* sync = SyncServiceFactory::GetForProfile(profile_);
   return sync && sync->IsSyncFeatureActive() && !sync->IsLocalSyncEnabled();
 }
 
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_factory.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_factory.cc
index 0a5b03df..bade8410 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_factory.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_factory.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_context.h"
@@ -40,7 +40,7 @@
   DependsOn(HistoryServiceFactory::GetInstance());
   DependsOn(VerdictCacheManagerFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(PasswordStoreFactory::GetInstance());
   DependsOn(browser_sync::UserEventServiceFactory::GetInstance());
 }
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_sync_browsertest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_sync_browsertest.cc
index fb3ad4f..14808fe 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_sync_browsertest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_sync_browsertest.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/browser/ui/browser.h"
@@ -67,7 +67,7 @@
     ASSERT_TRUE(embedded_test_server()->Start());
 
     syncer::ProfileSyncService* sync_service =
-        ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
+        SyncServiceFactory::GetAsProfileSyncServiceForProfile(
             browser()->profile());
 
     sync_service->OverrideNetworkForTest(
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 08adc8b..2dd72c1 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
@@ -59,7 +59,7 @@
 #include "chrome/browser/safe_browsing/test_extension_event_observer.h"
 #include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/extensions/api/safe_browsing_private.h"
 #include "chrome/common/safe_browsing/binary_feature_extractor.h"
@@ -375,7 +375,7 @@
     identity_test_env_adaptor_ =
         std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile());
 
-    ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+    SyncServiceFactory::GetInstance()->SetTestingFactory(
         profile(), BrowserContextKeyedServiceFactory::TestingFactory());
   }
 
diff --git a/chrome/browser/safe_browsing/url_lookup_service_factory.cc b/chrome/browser/safe_browsing/url_lookup_service_factory.cc
index ed8df45..e86d1d9 100644
--- a/chrome/browser/safe_browsing/url_lookup_service_factory.cc
+++ b/chrome/browser/safe_browsing/url_lookup_service_factory.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/safe_browsing/user_population.h"
 #include "chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#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/core/browser/sync/safe_browsing_primary_account_token_fetcher.h"
@@ -46,7 +46,7 @@
           "RealTimeUrlLookupService",
           BrowserContextDependencyManager::GetInstance()) {
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(VerdictCacheManagerFactory::GetInstance());
 #if BUILDFLAG(FULL_SAFE_BROWSING)
   DependsOn(AdvancedProtectionStatusManagerFactory::GetInstance());
@@ -72,7 +72,7 @@
           IdentityManagerFactory::GetForProfile(profile)),
       base::BindRepeating(&safe_browsing::SyncUtils::
                               AreSigninAndSyncSetUpForSafeBrowsingTokenFetches,
-                          ProfileSyncServiceFactory::GetForProfile(profile),
+                          SyncServiceFactory::GetForProfile(profile),
                           IdentityManagerFactory::GetForProfile(profile)),
       profile->IsOffTheRecord(), g_browser_process->variations_service(),
       g_browser_process->safe_browsing_service()
diff --git a/chrome/browser/safe_browsing/user_population.cc b/chrome/browser/safe_browsing/user_population.cc
index ce60cfd6..5a34347 100644
--- a/chrome/browser/safe_browsing/user_population.cc
+++ b/chrome/browser/safe_browsing/user_population.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/profiles/profile_manager.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/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/buildflags.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
@@ -46,7 +46,7 @@
 
   population.set_is_incognito(profile->IsOffTheRecord());
 
-  syncer::SyncService* sync = ProfileSyncServiceFactory::GetForProfile(profile);
+  syncer::SyncService* sync = SyncServiceFactory::GetForProfile(profile);
   bool is_history_sync_enabled =
       sync && sync->IsSyncFeatureActive() && !sync->IsLocalSyncEnabled() &&
       sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES);
diff --git a/chrome/browser/safe_browsing/user_population_unittest.cc b/chrome/browser/safe_browsing/user_population_unittest.cc
index 17cfd979..235c10a 100644
--- a/chrome/browser/safe_browsing/user_population_unittest.cc
+++ b/chrome/browser/safe_browsing/user_population_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/feature_list.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/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/buildflags.h"
@@ -84,7 +84,7 @@
   content::BrowserTaskEnvironment task_environment;
   TestingProfile profile;
   syncer::TestSyncService* sync_service = static_cast<syncer::TestSyncService*>(
-      ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+      SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
           &profile, base::BindRepeating(&CreateTestSyncService)));
 
   {
diff --git a/chrome/browser/search/suggestions/suggestions_service_factory.cc b/chrome/browser/search/suggestions/suggestions_service_factory.cc
index 18264bbc..caa8de5 100644
--- a/chrome/browser/search/suggestions/suggestions_service_factory.cc
+++ b/chrome/browser/search/suggestions/suggestions_service_factory.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
@@ -45,7 +45,7 @@
           "SuggestionsService",
           BrowserContextDependencyManager::GetInstance()) {
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 SuggestionsServiceFactory::~SuggestionsServiceFactory() {}
@@ -57,7 +57,7 @@
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForProfile(profile);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
 
   std::unique_ptr<SuggestionsStore> suggestions_store(
       new SuggestionsStore(profile->GetPrefs()));
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc
index 2e2b619c..5f0c504 100644
--- a/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc
+++ b/chrome/browser/send_tab_to_self/send_tab_to_self_util.cc
@@ -6,7 +6,6 @@
 
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/device_info_sync_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h"
 #include "components/send_tab_to_self/features.h"
 #include "components/send_tab_to_self/send_tab_to_self_model.h"
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
index c53623e..e93c9e7 100644
--- a/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
+++ b/chrome/browser/send_tab_to_self/send_tab_to_self_util_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc
index 7ca421e..524417b8 100644
--- a/chrome/browser/sessions/session_restore.cc
+++ b/chrome/browser/sessions/session_restore.cc
@@ -59,6 +59,8 @@
 #include "chrome/browser/ui/tabs/tab_group_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_provider_factory.h"
 #include "chrome/common/extensions/extension_metrics.h"
 #include "chrome/common/url_constants.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
@@ -159,8 +161,8 @@
 
   Browser* Restore() {
     SessionServiceBase* service =
-        SessionServiceFactory::GetForProfile(profile_);
-    DCHECK(service);
+        SessionServiceFactory::GetForProfileForSessionRestore(profile_);
+    CHECK(service);
     service->GetLastSession(base::BindOnce(&SessionRestoreImpl::OnGotSession,
                                            weak_factory_.GetWeakPtr(),
                                            /* for_apps */ false));
@@ -168,11 +170,22 @@
 #if BUILDFLAG(ENABLE_APP_SESSION_SERVICE)
     if (restore_apps_) {
       SessionServiceBase* app_service =
-          AppSessionServiceFactory::GetForProfile(profile_);
-      DCHECK(app_service);
+          AppSessionServiceFactory::GetForProfileForSessionRestore(profile_);
+      CHECK(app_service);
       app_service->GetLastSession(base::BindOnce(
           &SessionRestoreImpl::OnGotSession, weak_factory_.GetWeakPtr(),
           /* for_apps */ true));
+
+      // Ensure the registry is ready so that when we reopen apps they work
+      // properly. If we don't wait, it's possible that apps are restored in
+      // an incoherent state.
+      web_app::WebAppProvider* provider =
+          web_app::WebAppProviderFactory::GetForProfile(profile_);
+      DCHECK(provider);
+
+      provider->on_registry_ready().Post(
+          FROM_HERE, base::BindOnce(&SessionRestoreImpl::WebAppRegistryReady,
+                                    weak_factory_.GetWeakPtr()));
     }
 #endif
 
@@ -393,39 +406,56 @@
       got_browser_windows_ = true;
     }
 
-    // Keep track of whether we're ready to start processing windows.
-    // There's two ways we are ready to process:
-    // 1. we aren't restoring apps, and have browser_windows.
-    // 2. we are restoring apps, and we have both browser and app windows.
-    bool got_all_sessions =
-        !restore_apps_ || (got_app_windows_ && got_browser_windows_);
+    // Don't let app restores set the active_window_id, or else it will
+    // always bring the app to the forefront.
+    if (!for_apps)
+      active_window_id_ = active_window_id;
 
-    if (got_all_sessions)
-      SortWindowsByWindowId();
+    ProcessSessionWindowsIfReady();
+  }
 
-    if (synchronous_) {
-      // Don't let app restores set the active_window_id, or else it will
-      // always bring the app to the forefront.
-      if (!for_apps)
-        active_window_id_ = active_window_id;
+  void WebAppRegistryReady() {
+    DCHECK_EQ(web_app_registry_ready_, false);
+    DCHECK(restore_apps_);
+    web_app_registry_ready_ = true;
 
-      CHECK(!quit_closure_for_sync_restore_.is_null());
+    ProcessSessionWindowsIfReady();
+  }
 
-      if (got_all_sessions) {
-        // now we know we have all the windows we need merge them into windows_
-        // for processing.
-        std::move(quit_closure_for_sync_restore_).Run();
-      }
-
-      return;
-    }
+  // This is called by callback handlers and may trigger session restore if
+  // all the required conditions have been met. It also handles the differences
+  // between async/sync restores.
+  void ProcessSessionWindowsIfReady() {
+    bool got_all_sessions = IsReadyToProcessSessionWindows();
 
     // For async restores, we need to early exit here if we aren't ready to
     // start restoring windows.
     if (!got_all_sessions)
       return;
 
-    ProcessSessionWindowsAndNotify(&windows_, active_window_id);
+    SortWindowsByWindowId();
+
+    if (synchronous_) {
+      CHECK(!quit_closure_for_sync_restore_.is_null());
+      // now we know we have all the windows we need merge them into windows_
+      // for processing.
+      std::move(quit_closure_for_sync_restore_).Run();
+      return;
+    }
+
+    ProcessSessionWindowsAndNotify(&windows_, active_window_id_);
+  }
+
+  // This helper, based on the restore_apps_ state tells us if we're ready to
+  // begin restoring windows. There's two ways we are ready to process:
+  // 1. we aren't restoring apps, and have browser_windows.
+  // 2. we are restoring apps, we have both browser and app windows and
+  //   WebAppRegistryReady() has been called.
+  bool IsReadyToProcessSessionWindows() const {
+    if (!restore_apps_)
+      return got_browser_windows_;
+    return (got_app_windows_ && got_browser_windows_ &&
+            web_app_registry_ready_);
   }
 
   Browser* ProcessSessionWindowsAndNotify(
@@ -840,6 +870,11 @@
   // If true, restores apps.
   const bool restore_apps_;
 
+  // App restores depend on web_app::WebAppProvider on_registry_ready(). This
+  // bool will track that and hold up restores until that's ready too if apps
+  // are being restored.
+  bool web_app_registry_ready_ = false;
+
   // During app restores, we make two GetLastSession calls to
   // [App]SessionService, we need to wait till they both return before
   // processing the windows together in one pass.
@@ -929,10 +964,8 @@
 
 // TODO(stahon@microsoft.com) http://crbug.com/1194201 covers this
 // being disabled on mac. MacOS will not restore apps on crash restore.
-// On linux, apps can be restored without the proper app frame,
-// disabling restorations on linux for now. http://crbug.com/1199109
 #if BUILDFLAG(ENABLE_APP_SESSION_SERVICE)
-#if !defined(OS_MAC) && !defined(OS_LINUX)
+#if !defined(OS_MAC)
   // Apps should always be restored on crash restore.
   behavior |= SessionRestore::RESTORE_APPS;
 #endif
diff --git a/chrome/browser/sessions/tab_restore_browsertest.cc b/chrome/browser/sessions/tab_restore_browsertest.cc
index 79612b4c..afb4fa5a 100644
--- a/chrome/browser/sessions/tab_restore_browsertest.cc
+++ b/chrome/browser/sessions/tab_restore_browsertest.cc
@@ -1418,23 +1418,20 @@
   TabGroupModel* restored_group_model =
       restored_window->tab_strip_model()->group_model();
   ASSERT_EQ(tab_count, restored_window->tab_strip_model()->count());
-  auto restored_group1 =
-      restored_window->tab_strip_model()->GetTabGroupForTab(tab_count - 3);
-  ASSERT_TRUE(restored_group1);
   EXPECT_EQ(
-      restored_window->tab_strip_model()->GetTabGroupForTab(tab_count - 3),
+      absl::make_optional(group1),
+      restored_window->tab_strip_model()->GetTabGroupForTab(tab_count - 3));
+  EXPECT_EQ(
+      absl::make_optional(group1),
       restored_window->tab_strip_model()->GetTabGroupForTab(tab_count - 2));
-  auto restored_group2 =
-      restored_window->tab_strip_model()->GetTabGroupForTab(tab_count - 1);
-  ASSERT_TRUE(restored_group2);
-  EXPECT_NE(restored_group2, restored_group1);
+  EXPECT_EQ(
+      absl::make_optional(group2),
+      restored_window->tab_strip_model()->GetTabGroupForTab(tab_count - 1));
 
-  EXPECT_EQ(
-      group1_data,
-      *restored_group_model->GetTabGroup(*restored_group1)->visual_data());
-  EXPECT_EQ(
-      group2_data,
-      *restored_group_model->GetTabGroup(*restored_group2)->visual_data());
+  EXPECT_EQ(group1_data,
+            *restored_group_model->GetTabGroup(group1)->visual_data());
+  EXPECT_EQ(group2_data,
+            *restored_group_model->GetTabGroup(group2)->visual_data());
 }
 
 // Ensure a tab is not restored between tabs of another group.
@@ -1784,47 +1781,3 @@
   EXPECT_EQ(initial_origin,
             new_popup->GetMainFrame()->GetLastCommittedOrigin());
 }
-
-// Ensures group IDs are regenerated for restored windows so that we don't split
-// the same group between multiple windows. See https://crbug.com/1202102. This
-// test is temporary until a more comprehensive fix is implemented.
-IN_PROC_BROWSER_TEST_F(TabRestoreTest, RestoredWindowHasNewGroupIds) {
-  sessions::TabRestoreService* service =
-      TabRestoreServiceFactory::GetForProfile(browser()->profile());
-
-  AddSomeTabs(browser(), 2);
-  ASSERT_EQ(3, browser()->tab_strip_model()->count());
-
-  // Create a new browser from which to restore the first.
-  ui_test_utils::NavigateToURLWithDisposition(
-      browser(), GURL(chrome::kChromeUINewTabURL),
-      WindowOpenDisposition::NEW_WINDOW,
-      ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
-  ASSERT_EQ(2u, active_browser_list_->size());
-  Browser* second_browser = GetBrowser(1);
-  ASSERT_NE(browser(), second_browser);
-
-  auto original_group = browser()->tab_strip_model()->AddToNewGroup({1, 2});
-  CloseBrowserSynchronously(browser());
-  ASSERT_EQ(1u, active_browser_list_->size());
-
-  // We should have a restore entry for the window.
-  const sessions::TabRestoreService::Entries& entries = service->entries();
-  ASSERT_GE(entries.size(), 1u);
-  ASSERT_EQ(entries.front()->type, sessions::TabRestoreService::WINDOW);
-
-  // Restore the window.
-  std::vector<sessions::LiveTab*> restored_window_tabs =
-      service->RestoreEntryById(second_browser->live_tab_context(),
-                                entries.front()->id,
-                                WindowOpenDisposition::NEW_FOREGROUND_TAB);
-  ASSERT_EQ(2u, active_browser_list_->size());
-  ASSERT_EQ(3u, restored_window_tabs.size());
-  Browser* third_browser = GetBrowser(1);
-  ASSERT_NE(second_browser, third_browser);
-  ASSERT_EQ(3, third_browser->tab_strip_model()->count());
-
-  // The group ID should be new.
-  EXPECT_NE(original_group,
-            third_browser->tab_strip_model()->GetTabGroupForTab(1));
-}
diff --git a/chrome/browser/sharing/sharing_message_bridge_factory.h b/chrome/browser/sharing/sharing_message_bridge_factory.h
index c88f6ff..860a297 100644
--- a/chrome/browser/sharing/sharing_message_bridge_factory.h
+++ b/chrome/browser/sharing/sharing_message_bridge_factory.h
@@ -15,7 +15,7 @@
 class SharingMessageBridge;
 
 // Factory for sharing message bridge. We need this factory to prevent cyclic
-// dependency between SharingServiceFactory and ProfileSyncServiceFactory.
+// dependency between SharingServiceFactory and SyncServiceFactory.
 class SharingMessageBridgeFactory : public BrowserContextKeyedServiceFactory {
  public:
   // Returns singleton instance of SharingMessageBridgeFactory.
diff --git a/chrome/browser/sharing/sharing_service_factory.cc b/chrome/browser/sharing/sharing_service_factory.cc
index 2de124b..205e441 100644
--- a/chrome/browser/sharing/sharing_service_factory.cc
+++ b/chrome/browser/sharing/sharing_service_factory.cc
@@ -26,7 +26,7 @@
 #include "chrome/browser/sharing/vapid_key_manager.h"
 #include "chrome/browser/sharing/web_push/web_push_sender.h"
 #include "chrome/browser/sync/device_info_sync_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/buildflags.h"
 #include "components/gcm_driver/crypto/gcm_encryption_provider.h"
 #include "components/gcm_driver/gcm_driver.h"
@@ -77,7 +77,7 @@
   DependsOn(gcm::GCMProfileServiceFactory::GetInstance());
   DependsOn(instance_id::InstanceIDProfileServiceFactory::GetInstance());
   DependsOn(DeviceInfoSyncServiceFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(SharingMessageBridgeFactory::GetInstance());
 }
 
@@ -87,7 +87,7 @@
     content::BrowserContext* context) const {
   Profile* profile = Profile::FromBrowserContext(context);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
 
   if (!sync_service)
     return nullptr;
diff --git a/chrome/browser/signin/e2e_tests/live_sign_in_test.cc b/chrome/browser/signin/e2e_tests/live_sign_in_test.cc
index a6386d6..9bb9608 100644
--- a/chrome/browser/signin/e2e_tests/live_sign_in_test.cc
+++ b/chrome/browser/signin/e2e_tests/live_sign_in_test.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/signin/e2e_tests/live_test.h"
 #include "chrome/browser/signin/e2e_tests/test_accounts_util.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
@@ -266,7 +266,7 @@
   syncer::SyncService* sync_service() { return sync_service(browser()); }
 
   syncer::SyncService* sync_service(Browser* browser) {
-    return ProfileSyncServiceFactory::GetForProfile(browser->profile());
+    return SyncServiceFactory::GetForProfile(browser->profile());
   }
 
   AccountReconcilor* account_reconcilor() {
diff --git a/chrome/browser/signin/header_modification_delegate_impl.cc b/chrome/browser/signin/header_modification_delegate_impl.cc
index 9cd8c0c..da66dc94 100644
--- a/chrome/browser/signin/header_modification_delegate_impl.cc
+++ b/chrome/browser/signin/header_modification_delegate_impl.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
 #include "chrome/browser/signin/chrome_signin_helper.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/signin_pref_names.h"
@@ -59,7 +59,7 @@
   const PrefService* prefs = profile_->GetPrefs();
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/spellchecker/spellcheck_factory.cc b/chrome/browser/spellchecker/spellcheck_factory.cc
index 89edb0f..1d426c3 100644
--- a/chrome/browser/spellchecker/spellcheck_factory.cc
+++ b/chrome/browser/spellchecker/spellcheck_factory.cc
@@ -51,11 +51,6 @@
   user_prefs->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries);
   user_prefs->RegisterListPref(
       spellcheck::prefs::kSpellCheckForcedDictionaries);
-  // Continue registering kSpellCheckBlacklistedDictionaries for
-  // preference migration.
-  // TODO(crbug/1161062): Remove after M91.
-  user_prefs->RegisterListPref(
-      spellcheck::prefs::kSpellCheckBlacklistedDictionaries);
   user_prefs->RegisterListPref(
       spellcheck::prefs::kSpellCheckBlocklistedDictionaries);
   // Continue registering kSpellCheckDictionary for preference migration.
diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc
index 14e9f03d..340667d 100644
--- a/chrome/browser/spellchecker/spellcheck_service.cc
+++ b/chrome/browser/spellchecker/spellcheck_service.cc
@@ -127,22 +127,6 @@
   }
 #endif  // defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
 
-  // Migrating kSpellCheckBlacklistedDictionaries preference to
-  // kSpellCheckBlocklistedDictionaries.
-  // TODO(crbug/1161062): Remove after M91.
-  StringListPrefMember old_blocked_dict_pref;
-  old_blocked_dict_pref.Init(
-      spellcheck::prefs::kSpellCheckBlacklistedDictionaries, prefs);
-  StringListPrefMember blocked_dict_pref;
-  blocked_dict_pref.Init(spellcheck::prefs::kSpellCheckBlocklistedDictionaries,
-                         prefs);
-
-  if (blocked_dict_pref.GetValue().empty() &&
-      !old_blocked_dict_pref.GetValue().empty()) {
-    blocked_dict_pref.SetValue(old_blocked_dict_pref.GetValue());
-    old_blocked_dict_pref.SetValue(std::vector<std::string>());
-  }
-
   pref_change_registrar_.Add(
       spellcheck::prefs::kSpellCheckDictionaries,
       base::BindRepeating(&SpellcheckService::OnSpellCheckDictionariesChanged,
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
index 12dc77c..f94b9e0d 100644
--- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc
+++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -22,7 +22,7 @@
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
@@ -218,7 +218,7 @@
   // TODO(crbug.com/946473): Get rid of this hack and instead call
   // DataTypePreconditionChanged from the controller.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   if (sync_service->GetUserSettings()->IsFirstSetupComplete()) {
     // Trigger a reconfig by grabbing a SyncSetupInProgressHandle and
     // immediately releasing it again (via the temporary unique_ptr going away).
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service_factory.cc b/chrome/browser/supervised_user/child_accounts/child_account_service_factory.cc
index 421a707..97748b0 100644
--- a/chrome/browser/supervised_user/child_accounts/child_account_service_factory.cc
+++ b/chrome/browser/supervised_user/child_accounts/child_account_service_factory.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/supervised_user/child_accounts/child_account_service.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 // static
@@ -28,7 +28,7 @@
         "ChildAccountService",
         BrowserContextDependencyManager::GetInstance()) {
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(SupervisedUserServiceFactory::GetInstance());
 }
 
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index 9a87da5..9ffd2ab 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -34,7 +34,6 @@
 #include "chrome/browser/sync/bookmark_sync_service_factory.h"
 #include "chrome/browser/sync/device_info_sync_service_factory.h"
 #include "chrome/browser/sync/model_type_store_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h"
 #include "chrome/browser/sync/session_sync_service_factory.h"
 #include "chrome/browser/sync/sync_invalidations_service_factory.h"
diff --git a/chrome/browser/sync/glue/sync_start_util.cc b/chrome/browser/sync/glue/sync_start_util.cc
index 1bcaa669..015a80b1 100644
--- a/chrome/browser/sync/glue/sync_start_util.cc
+++ b/chrome/browser/sync/glue/sync_start_util.cc
@@ -9,7 +9,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/sync/driver/sync_service.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -31,7 +31,7 @@
     return;
   }
 
-  syncer::SyncService* service = ProfileSyncServiceFactory::GetForProfile(p);
+  syncer::SyncService* service = SyncServiceFactory::GetForProfile(p);
   if (!service) {
     DVLOG(2) << "No ProfileSyncService for profile, can't start sync.";
     return;
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc
index 9bad961..8b7885df 100644
--- a/chrome/browser/sync/profile_sync_service_android.cc
+++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -20,8 +20,8 @@
 #include "chrome/android/chrome_jni_headers/ProfileSyncService_jni.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/session_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/identity_manager/account_info.h"
@@ -93,7 +93,7 @@
   }
 
   sync_service_ =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(profile_);
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile_);
 }
 
 bool ProfileSyncServiceAndroid::Init() {
diff --git a/chrome/browser/sync/sync_encryption_keys_tab_helper.cc b/chrome/browser/sync/sync_encryption_keys_tab_helper.cc
index eedd50d..9205426 100644
--- a/chrome/browser/sync/sync_encryption_keys_tab_helper.cc
+++ b/chrome/browser/sync/sync_encryption_keys_tab_helper.cc
@@ -12,7 +12,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/no_destructor.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/sync_encryption_keys_extension.mojom.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/driver/sync_service.h"
@@ -118,7 +118,7 @@
     return;
   }
 
-  syncer::SyncService* sync_service = ProfileSyncServiceFactory::GetForProfile(
+  syncer::SyncService* sync_service = SyncServiceFactory::GetForProfile(
       Profile::FromBrowserContext(web_contents->GetBrowserContext()));
   if (!sync_service) {
     return;
diff --git a/chrome/browser/sync/sync_error_notifier_factory_ash.cc b/chrome/browser/sync/sync_error_notifier_factory_ash.cc
index 1c5f975..1792a53 100644
--- a/chrome/browser/sync/sync_error_notifier_factory_ash.cc
+++ b/chrome/browser/sync/sync_error_notifier_factory_ash.cc
@@ -6,15 +6,15 @@
 
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_error_notifier_ash.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 SyncErrorNotifierFactory::SyncErrorNotifierFactory()
     : BrowserContextKeyedServiceFactory(
         "SyncErrorNotifier",
         BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 SyncErrorNotifierFactory::~SyncErrorNotifierFactory() {}
@@ -35,7 +35,7 @@
     content::BrowserContext* context) const {
   Profile* profile = static_cast<Profile*>(context);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
 
   if (!sync_service)
     return nullptr;
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/sync_service_factory.cc
similarity index 92%
rename from chrome/browser/sync/profile_sync_service_factory.cc
rename to chrome/browser/sync/sync_service_factory.cc
index 1bcadf4d..5d662dad 100644
--- a/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/chrome/browser/sync/sync_service_factory.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/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 
 #include <string>
 #include <utility>
@@ -103,13 +103,12 @@
 }  // anonymous namespace
 
 // static
-ProfileSyncServiceFactory* ProfileSyncServiceFactory::GetInstance() {
-  return base::Singleton<ProfileSyncServiceFactory>::get();
+SyncServiceFactory* SyncServiceFactory::GetInstance() {
+  return base::Singleton<SyncServiceFactory>::get();
 }
 
 // static
-syncer::SyncService* ProfileSyncServiceFactory::GetForProfile(
-    Profile* profile) {
+syncer::SyncService* SyncServiceFactory::GetForProfile(Profile* profile) {
   if (!switches::IsSyncAllowedByFlag()) {
     return nullptr;
   }
@@ -120,11 +119,11 @@
 
 // static
 syncer::ProfileSyncService*
-ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(Profile* profile) {
+SyncServiceFactory::GetAsProfileSyncServiceForProfile(Profile* profile) {
   return static_cast<syncer::ProfileSyncService*>(GetForProfile(profile));
 }
 
-content::BrowserContext* ProfileSyncServiceFactory::GetBrowserContextToUse(
+content::BrowserContext* SyncServiceFactory::GetBrowserContextToUse(
     content::BrowserContext* context) const {
   if (context->IsOffTheRecord())
     return nullptr;
@@ -133,10 +132,10 @@
   return context;
 }
 
-ProfileSyncServiceFactory::ProfileSyncServiceFactory()
+SyncServiceFactory::SyncServiceFactory()
     : BrowserContextKeyedServiceFactory(
-        "ProfileSyncService",
-        BrowserContextDependencyManager::GetInstance()) {
+          "SyncService",
+          BrowserContextDependencyManager::GetInstance()) {
   // The ProfileSyncService depends on various SyncableServices being around
   // when it is shut down.  Specify those dependencies here to build the proper
   // destruction order. Note that some of the dependencies are listed here but
@@ -183,9 +182,9 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
-ProfileSyncServiceFactory::~ProfileSyncServiceFactory() = default;
+SyncServiceFactory::~SyncServiceFactory() = default;
 
-KeyedService* ProfileSyncServiceFactory::BuildServiceInstanceFor(
+KeyedService* SyncServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
   syncer::ProfileSyncService::InitParams init_params;
 
@@ -290,18 +289,18 @@
 }
 
 // static
-bool ProfileSyncServiceFactory::HasSyncService(Profile* profile) {
+bool SyncServiceFactory::HasSyncService(Profile* profile) {
   return GetInstance()->GetServiceForBrowserContext(profile, false) != nullptr;
 }
 
 // static
-bool ProfileSyncServiceFactory::IsSyncAllowed(Profile* profile) {
+bool SyncServiceFactory::IsSyncAllowed(Profile* profile) {
   DCHECK(profile);
 
   if (HasSyncService(profile)) {
     syncer::SyncService* sync_service = GetForProfile(profile);
     return !sync_service->HasDisableReason(
-               syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
+        syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
   }
 
   // No ProfileSyncService created yet - we don't want to create one, so just
@@ -313,7 +312,7 @@
 
 // static
 std::vector<const syncer::SyncService*>
-ProfileSyncServiceFactory::GetAllSyncServices() {
+SyncServiceFactory::GetAllSyncServices() {
   std::vector<Profile*> profiles =
       g_browser_process->profile_manager()->GetLoadedProfiles();
   std::vector<const syncer::SyncService*> sync_services;
@@ -326,11 +325,11 @@
 }
 
 // static
-void ProfileSyncServiceFactory::SetSyncClientFactoryForTest(
+void SyncServiceFactory::SetSyncClientFactoryForTest(
     SyncClientFactory* client_factory) {
   client_factory_ = client_factory;
 }
 
 // static
-ProfileSyncServiceFactory::SyncClientFactory*
-    ProfileSyncServiceFactory::client_factory_ = nullptr;
+SyncServiceFactory::SyncClientFactory* SyncServiceFactory::client_factory_ =
+    nullptr;
diff --git a/chrome/browser/sync/profile_sync_service_factory.h b/chrome/browser/sync/sync_service_factory.h
similarity index 82%
rename from chrome/browser/sync/profile_sync_service_factory.h
rename to chrome/browser/sync/sync_service_factory.h
index 5f05d52..024e875 100644
--- a/chrome/browser/sync/profile_sync_service_factory.h
+++ b/chrome/browser/sync/sync_service_factory.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_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
-#define CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
+#ifndef CHROME_BROWSER_SYNC_SYNC_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_SYNC_SYNC_SERVICE_FACTORY_H_
 
 #include <memory>
 #include <vector>
@@ -27,7 +27,7 @@
 class SyncService;
 }  // namespace syncer
 
-class ProfileSyncServiceFactory : public BrowserContextKeyedServiceFactory {
+class SyncServiceFactory : public BrowserContextKeyedServiceFactory {
  public:
   using SyncClientFactory =
       base::RepeatingCallback<std::unique_ptr<browser_sync::ChromeSyncClient>(
@@ -49,7 +49,7 @@
   // |profile| must not be nullptr.
   static bool IsSyncAllowed(Profile* profile);
 
-  static ProfileSyncServiceFactory* GetInstance();
+  static SyncServiceFactory* GetInstance();
 
   // Overrides how the SyncClient is created for testing purposes.
   static void SetSyncClientFactoryForTest(SyncClientFactory* client_factory);
@@ -59,10 +59,10 @@
   static std::vector<const syncer::SyncService*> GetAllSyncServices();
 
  private:
-  friend struct base::DefaultSingletonTraits<ProfileSyncServiceFactory>;
+  friend struct base::DefaultSingletonTraits<SyncServiceFactory>;
 
-  ProfileSyncServiceFactory();
-  ~ProfileSyncServiceFactory() override;
+  SyncServiceFactory();
+  ~SyncServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
   KeyedService* BuildServiceInstanceFor(
@@ -74,7 +74,7 @@
   // This is a raw pointer so it can be statically initialized.
   static SyncClientFactory* client_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceFactory);
+  DISALLOW_COPY_AND_ASSIGN(SyncServiceFactory);
 };
 
-#endif  // CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
+#endif  // CHROME_BROWSER_SYNC_SYNC_SERVICE_FACTORY_H_
diff --git a/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/chrome/browser/sync/sync_service_factory_unittest.cc
similarity index 90%
rename from chrome/browser/sync/profile_sync_service_factory_unittest.cc
rename to chrome/browser/sync/sync_service_factory_unittest.cc
index 5667cb6..3d40adc 100644
--- a/chrome/browser/sync/profile_sync_service_factory_unittest.cc
+++ b/chrome/browser/sync/sync_service_factory_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 
 #include <stddef.h>
 
@@ -39,7 +39,7 @@
 #include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h"
 #endif
 
-class ProfileSyncServiceFactoryTest : public testing::Test {
+class SyncServiceFactoryTest : public testing::Test {
  public:
   void SetUp() override {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -64,16 +64,14 @@
 
  protected:
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  ProfileSyncServiceFactoryTest() {
+  SyncServiceFactoryTest() {
     // Fake network stack is required for WIFI_CONFIGURATIONS datatype.
     chromeos::NetworkHandler::Initialize();
   }
-  ~ProfileSyncServiceFactoryTest() override {
-    chromeos::NetworkHandler::Shutdown();
-  }
+  ~SyncServiceFactoryTest() override { chromeos::NetworkHandler::Shutdown(); }
 #else
-  ProfileSyncServiceFactoryTest() = default;
-  ~ProfileSyncServiceFactoryTest() override = default;
+  SyncServiceFactoryTest() = default;
+  ~SyncServiceFactoryTest() override = default;
 #endif
 
   // Returns the collection of default datatypes.
@@ -188,16 +186,16 @@
 };
 
 // Verify that the disable sync flag disables creation of the sync service.
-TEST_F(ProfileSyncServiceFactoryTest, DisableSyncFlag) {
+TEST_F(SyncServiceFactoryTest, DisableSyncFlag) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync);
-  EXPECT_EQ(nullptr, ProfileSyncServiceFactory::GetForProfile(profile()));
+  EXPECT_EQ(nullptr, SyncServiceFactory::GetForProfile(profile()));
 }
 
 // Verify that a normal (no command line flags) PSS can be created and
 // properly initialized.
-TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDefault) {
+TEST_F(SyncServiceFactoryTest, CreatePSSDefault) {
   syncer::ProfileSyncService* pss =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(profile());
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile());
   syncer::ModelTypeSet types = pss->GetRegisteredDataTypesForTest();
   EXPECT_EQ(DefaultDatatypesCount(), types.Size());
   CheckDefaultDatatypesInSetExcept(types, syncer::ModelTypeSet());
@@ -208,11 +206,11 @@
 
 // Verify that a PSS with a disabled datatype can be created and properly
 // initialized.
-TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDisableOne) {
+TEST_F(SyncServiceFactoryTest, CreatePSSDisableOne) {
   syncer::ModelTypeSet disabled_types(syncer::AUTOFILL);
   SetDisabledTypes(disabled_types);
   syncer::ProfileSyncService* pss =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(profile());
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile());
   syncer::ModelTypeSet types = pss->GetRegisteredDataTypesForTest();
   EXPECT_EQ(DefaultDatatypesCount() - disabled_types.Size(), types.Size());
   CheckDefaultDatatypesInSetExcept(types, disabled_types);
@@ -223,12 +221,12 @@
 
 // Verify that a PSS with multiple disabled datatypes can be created and
 // properly initialized.
-TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDisableMultiple) {
+TEST_F(SyncServiceFactoryTest, CreatePSSDisableMultiple) {
   syncer::ModelTypeSet disabled_types(syncer::AUTOFILL_PROFILE,
                                       syncer::BOOKMARKS);
   SetDisabledTypes(disabled_types);
   syncer::ProfileSyncService* pss =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(profile());
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile());
   syncer::ModelTypeSet types = pss->GetRegisteredDataTypesForTest();
   EXPECT_EQ(DefaultDatatypesCount() - disabled_types.Size(), types.Size());
   CheckDefaultDatatypesInSetExcept(types, disabled_types);
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc
index 620077d..e8fc02cd 100644
--- a/chrome/browser/sync/sync_ui_util.cc
+++ b/chrome/browser/sync/sync_ui_util.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/singleton_tabs.h"
@@ -220,7 +220,7 @@
 
 StatusLabels GetStatusLabels(Profile* profile) {
   DCHECK(profile);
-  return GetStatusLabels(ProfileSyncServiceFactory::GetForProfile(profile),
+  return GetStatusLabels(SyncServiceFactory::GetForProfile(profile),
                          IdentityManagerFactory::GetForProfile(profile),
                          signin_util::IsUserSignoutAllowedForProfile(profile));
 }
@@ -231,7 +231,7 @@
 
 absl::optional<AvatarSyncErrorType> GetAvatarSyncErrorType(Profile* profile) {
   const syncer::SyncService* service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
 
   // If there is no SyncService (probably because sync is disabled from the
   // command line), then there's no error to show.
diff --git a/chrome/browser/sync/test/integration/local_sync_test.cc b/chrome/browser/sync/test/integration/local_sync_test.cc
index 2f014a38..bec2f9f 100644
--- a/chrome/browser/sync/test/integration/local_sync_test.cc
+++ b/chrome/browser/sync/test/integration/local_sync_test.cc
@@ -13,7 +13,7 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -77,7 +77,7 @@
     (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 IN_PROC_BROWSER_TEST_F(LocalSyncTest, ShouldStart) {
   ProfileSyncService* service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(
           browser()->profile());
 
   // Wait until the first sync cycle is completed.
diff --git a/chrome/browser/sync/test/integration/passwords_helper.cc b/chrome/browser/sync/test/integration/passwords_helper.cc
index 665e488..39c0d1e 100644
--- a/chrome/browser/sync/test/integration/passwords_helper.cc
+++ b/chrome/browser/sync/test/integration/passwords_helper.cc
@@ -18,7 +18,6 @@
 #include "base/time/time.h"
 #include "chrome/browser/password_manager/account_password_store_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
 #include "components/password_manager/core/browser/insecure_credentials_consumer.h"
diff --git a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc
index e2860b5..78e05c8 100644
--- a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc
+++ b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc
@@ -18,7 +18,7 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/quiesce_status_change_checker.h"
 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
 #include "chrome/browser/sync/test/integration/sync_signin_delegate.h"
@@ -187,8 +187,7 @@
     const std::string& password,
     SigninType signin_type)
     : profile_(profile),
-      service_(ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
-          profile)),
+      service_(SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile)),
       username_(username),
       password_(password),
       signin_type_(signin_type),
diff --git a/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc b/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc
index e6dedb3..00f4baa 100644
--- a/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc
@@ -7,7 +7,7 @@
 #include "ash/constants/ash_features.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/apps_helper.h"
 #include "chrome/browser/sync/test/integration/os_sync_test.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
@@ -174,7 +174,7 @@
   app_list::AppListSyncableService* service =
       app_list::AppListSyncableServiceFactory::GetForProfile(profile);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
 
   const size_t kNumApps = 5;
   syncer::StringOrdinal pin_position =
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index 420d8b03..705a7e40 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -33,8 +33,8 @@
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_invalidations_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/committed_all_nudged_changes_checker.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
@@ -588,7 +588,7 @@
 }
 
 ProfileSyncService* SyncTest::GetSyncService(int index) {
-  return ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
+  return SyncServiceFactory::GetAsProfileSyncServiceForProfile(
       GetProfile(index));
 }
 
@@ -735,8 +735,7 @@
   // ProfileSyncServiceHarness - some tests expect the ProfileSyncService to
   // already exist.
   ProfileSyncService* profile_sync_service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
-          GetProfile(index));
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(GetProfile(index));
 
   if (server_type_ == IN_PROCESS_FAKE_SERVER) {
     profile_sync_service->OverrideNetworkForTest(
@@ -851,7 +850,7 @@
       break;
     case IN_PROCESS_FAKE_SERVER: {
       configuration_refresher_->Observe(
-          ProfileSyncServiceFactory::GetForProfile(GetProfile(index)));
+          SyncServiceFactory::GetForProfile(GetProfile(index)));
       break;
     }
     case SERVER_TYPE_UNDECIDED:
diff --git a/chrome/browser/sync_file_system/sync_file_system_service.cc b/chrome/browser/sync_file_system/sync_file_system_service.cc
index 48a5006..86a6845 100644
--- a/chrome/browser/sync_file_system/sync_file_system_service.cc
+++ b/chrome/browser/sync_file_system/sync_file_system_service.cc
@@ -22,7 +22,7 @@
 #include "chrome/browser/apps/platform_apps/api/sync_file_system/extension_sync_event_observer.h"
 #include "chrome/browser/apps/platform_apps/api/sync_file_system/sync_file_system_api_helpers.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync_file_system/local/local_file_sync_service.h"
 #include "chrome/browser/sync_file_system/logger.h"
 #include "chrome/browser/sync_file_system/sync_direction.h"
@@ -269,7 +269,7 @@
   remote_service_.reset();
 
   syncer::SyncService* profile_sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   if (profile_sync_service)
     profile_sync_service->RemoveObserver(this);
 
@@ -472,7 +472,7 @@
   remote_sync_runners_.push_back(std::move(remote_syncer));
 
   syncer::SyncService* profile_sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   if (profile_sync_service) {
     UpdateSyncEnabledStatus(profile_sync_service);
     profile_sync_service->AddObserver(this);
diff --git a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc
index 14e99b1..64fa80977 100644
--- a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc
+++ b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc
@@ -73,6 +73,17 @@
       android_icon_id = ResourceMapper::MapToJavaDrawableId(
           GetIconResourceID(suggestion.icon));
     }
+
+    std::u16string value;
+    std::u16string label;
+    if (controller_->GetSuggestionMinorTextAt(i).empty()) {
+      value = controller_->GetSuggestionMainTextAt(i);
+      label = controller_->GetSuggestionLabelAt(i);
+    } else {
+      value = controller_->GetSuggestionMainTextAt(i);
+      label = controller_->GetSuggestionMinorTextAt(i);
+    }
+
     // Set the offer title to display as the item tag.
     std::u16string item_tag = std::u16string();
     if (base::FeatureList::IsEnabled(
@@ -85,9 +96,8 @@
           ResourceMapper::MapToJavaDrawableId(GetIconResourceID("offerTag"));
     }
     Java_AutofillKeyboardAccessoryViewBridge_addToAutofillSuggestionArray(
-        env, data_array, position++,
-        ConvertUTF16ToJavaString(env, controller_->GetSuggestionValueAt(i)),
-        ConvertUTF16ToJavaString(env, controller_->GetSuggestionLabelAt(i)),
+        env, data_array, position++, ConvertUTF16ToJavaString(env, value),
+        ConvertUTF16ToJavaString(env, label),
         ConvertUTF16ToJavaString(env, item_tag), android_icon_id,
         suggestion.frontend_id,
         controller_->GetRemovalConfirmationText(i, nullptr, nullptr),
diff --git a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
index 23609ac..04ee75b4 100644
--- a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
+++ b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
@@ -10,6 +10,7 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
 #include "base/command_line.h"
+#include "base/strings/strcat.h"
 #include "chrome/android/chrome_jni_headers/AutofillPopupBridge_jni.h"
 #include "chrome/browser/android/resource_mapper.h"
 #include "chrome/browser/autofill/autofill_keyboard_accessory_adapter.h"
@@ -76,8 +77,13 @@
       Java_AutofillPopupBridge_createAutofillSuggestionArray(env, count);
 
   for (size_t i = 0; i < count; ++i) {
-    ScopedJavaLocalRef<jstring> value = base::android::ConvertUTF16ToJavaString(
-        env, controller_->GetSuggestionValueAt(i));
+    std::u16string value_text =
+        controller_->GetSuggestionMinorTextAt(i).empty()
+            ? controller_->GetSuggestionMainTextAt(i)
+            : base::StrCat({controller_->GetSuggestionMainTextAt(i), u" ",
+                            controller_->GetSuggestionMinorTextAt(i)});
+    ScopedJavaLocalRef<jstring> value =
+        base::android::ConvertUTF16ToJavaString(env, value_text);
     ScopedJavaLocalRef<jstring> label = base::android::ConvertUTF16ToJavaString(
         env, controller_->GetSuggestionLabelAt(i));
     int android_icon_id = 0;
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 489f411..33efe9fe 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -26,7 +26,7 @@
 #include "chrome/browser/chromeos/file_manager/app_id.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/app_list_client_impl.h"
 #include "chrome/browser/ui/app_list/app_list_model_updater.h"
 #include "chrome/browser/ui/app_list/app_service/app_service_app_model_builder.h"
@@ -444,9 +444,9 @@
   // Install default page brakes for tablet form factor devices here as
   // these devices do not have app list sync turned on.
   if (chromeos::switches::IsTabletFormFactor() && profile_->IsNewProfile()) {
-    DCHECK(!ProfileSyncServiceFactory::GetForProfile(profile_)
-                ->GetActiveDataTypes()
-                .Has(syncer::APP_LIST));
+    DCHECK(
+        !SyncServiceFactory::GetForProfile(profile_)->GetActiveDataTypes().Has(
+            syncer::APP_LIST));
     // Create call back to create the default page break items at later time so
     // that default page break items are not removed by
     // |PruneRedundantPageBreakItems|
diff --git a/chrome/browser/ui/app_list/app_sync_ui_state.cc b/chrome/browser/ui/app_list/app_sync_ui_state.cc
index 6ee22b3..3a37151 100644
--- a/chrome/browser/ui/app_list/app_sync_ui_state.cc
+++ b/chrome/browser/ui/app_list/app_sync_ui_state.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/pending_extension_manager.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/app_sync_ui_state_factory.h"
 #include "chrome/browser/ui/app_list/app_sync_ui_state_observer.h"
 #include "components/prefs/pref_service.h"
@@ -38,7 +38,7 @@
   if (!profile || profile->IsOffTheRecord())
     return false;
 
-  if (!ProfileSyncServiceFactory::HasSyncService(profile))
+  if (!SyncServiceFactory::HasSyncService(profile))
     return false;
 
   return profile->IsNewProfile();
@@ -77,7 +77,7 @@
   extension_registry_ = extensions::ExtensionRegistry::Get(profile_);
   extension_registry_->AddObserver(this);
 
-  sync_service_ = ProfileSyncServiceFactory::GetForProfile(profile_);
+  sync_service_ = SyncServiceFactory::GetForProfile(profile_);
   CHECK(sync_service_);
   sync_service_->AddObserver(this);
 }
diff --git a/chrome/browser/ui/app_list/app_sync_ui_state_factory.cc b/chrome/browser/ui/app_list/app_sync_ui_state_factory.cc
index 9bc9a00..eb977be 100644
--- a/chrome/browser/ui/app_list/app_sync_ui_state_factory.cc
+++ b/chrome/browser/ui/app_list/app_sync_ui_state_factory.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/app_list/app_sync_ui_state_factory.h"
 
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/app_sync_ui_state.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "extensions/browser/extension_registry_factory.h"
@@ -29,7 +29,7 @@
           "AppSyncUIState",
           BrowserContextDependencyManager::GetInstance()) {
   DependsOn(extensions::ExtensionRegistryFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 AppSyncUIStateFactory::~AppSyncUIStateFactory() {}
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
index 5157519..4eebecdf 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -43,7 +43,7 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_service_test_base.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/app_service/app_service_app_icon_loader.h"
 #include "chrome/browser/ui/app_list/app_service/app_service_app_item.h"
 #include "chrome/browser/ui/app_list/app_service/app_service_app_model_builder.h"
@@ -3240,20 +3240,20 @@
 }
 
 TEST_P(ArcAppModelBuilderTest, PackageSyncableServiceEnabled) {
-  EXPECT_TRUE(ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
-                  profile_.get())
-                  ->GetRegisteredDataTypesForTest()
-                  .Has(syncer::ARC_PACKAGE));
+  EXPECT_TRUE(
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile_.get())
+          ->GetRegisteredDataTypesForTest()
+          .Has(syncer::ARC_PACKAGE));
 }
 
 TEST_P(ArcAppModelBuilderTest, PackageSyncableServiceDisabled) {
   base::test::ScopedCommandLine command_line;
   command_line.GetProcessCommandLine()->AppendSwitch(
       chromeos::switches::kArcDisableAppSync);
-  EXPECT_FALSE(ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
-                   profile_.get())
-                   ->GetRegisteredDataTypesForTest()
-                   .Has(syncer::ARC_PACKAGE));
+  EXPECT_FALSE(
+      SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile_.get())
+          ->GetRegisteredDataTypesForTest()
+          .Has(syncer::ARC_PACKAGE));
 }
 
 TEST_P(ArcDefaultAppTest, DefaultApps) {
diff --git a/chrome/browser/ui/ash/chrome_shelf_prefs.cc b/chrome/browser/ui/ash/chrome_shelf_prefs.cc
index 041b475..64de612 100644
--- a/chrome/browser/ui/ash/chrome_shelf_prefs.cc
+++ b/chrome/browser/ui/ash/chrome_shelf_prefs.cc
@@ -19,7 +19,7 @@
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/prefs/pref_service_syncable_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
@@ -150,7 +150,7 @@
 // mode.
 bool IsSafeToApplyDefaultPinLayout(Profile* profile) {
   const syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   // No |sync_service| in incognito mode.
   if (!sync_service)
     return true;
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
index 107b4d6..519c0c1 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -56,7 +56,7 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/prefs/browser_prefs.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_icon_loader.h"
 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_icon.h"
@@ -388,7 +388,7 @@
         extensions::manifest_keys::kPlatformAppBackgroundScripts,
         std::move(scripts));
 
-    ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+    SyncServiceFactory::GetInstance()->SetTestingFactory(
         profile(), base::BindRepeating(&BuildTestSyncService));
 
     extensions::TestExtensionSystem* extension_system(
@@ -413,7 +413,7 @@
     // Many pinned app tests assume OS sync is enabled.
     if (chromeos::features::IsSplitSettingsSyncEnabled()) {
       syncer::SyncService* sync_service =
-          ProfileSyncServiceFactory::GetForProfile(profile());
+          SyncServiceFactory::GetForProfile(profile());
       sync_service->GetUserSettings()->SetOsSyncFeatureEnabled(true);
     }
 
@@ -1436,7 +1436,7 @@
 TEST_F(ChromeShelfControllerSplitSettingsSyncTest, PreinstalledApps) {
   // Simulate a user who opted out of sync.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile());
+      SyncServiceFactory::GetForProfile(profile());
   sync_service->GetUserSettings()->SetOsSyncFeatureEnabled(false);
 
   InitShelfController();
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller.h b/chrome/browser/ui/autofill/autofill_popup_controller.h
index 4864b38..9fe8755 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller.h
+++ b/chrome/browser/ui/autofill/autofill_popup_controller.h
@@ -37,13 +37,22 @@
   // Returns the full set of autofill suggestions, if applicable.
   virtual std::vector<Suggestion> GetSuggestions() const = 0;
 
-  // Returns the suggestion at the given |row| index.
+  // Returns the suggestion at the given |row| index. The |Suggestion| is the
+  // data model including information that is to be shown in the UI.
   virtual const Suggestion& GetSuggestionAt(int row) const = 0;
 
-  // Returns the suggestion value string at the given |row| index.
-  virtual const std::u16string& GetSuggestionValueAt(int row) const = 0;
+  // Returns the suggestion main text string at the given |row| index. The main
+  // text is shown in primary or secondary text style, serving as the title of
+  // the suggestion.
+  virtual std::u16string GetSuggestionMainTextAt(int row) const = 0;
 
-  // Returns the suggestion label string at the given |row| index.
+  // Returns the suggestion minor text string at the given |row| index. The
+  // minor text is shown in secondary text style, serving as the sub-title of
+  // the suggestion item.
+  virtual std::u16string GetSuggestionMinorTextAt(int row) const = 0;
+
+  // Returns the suggestion label string at the given |row| index. The label
+  // includes detailed but less important information for the suggestion.
   virtual const std::u16string& GetSuggestionLabelAt(int row) const = 0;
 
   // Returns whether the item at |list_index| can be removed. If so, fills
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
index ac4dc2e..72b4c6dc 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -20,6 +20,7 @@
 #include "components/autofill/core/browser/ui/autofill_popup_delegate.h"
 #include "components/autofill/core/browser/ui/popup_item_ids.h"
 #include "components/autofill/core/browser/ui/suggestion.h"
+#include "components/strings/grit/components_strings.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
@@ -28,6 +29,7 @@
 #include "ui/accessibility/ax_tree_id.h"
 #include "ui/accessibility/ax_tree_manager_map.h"
 #include "ui/accessibility/platform/ax_platform_node.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/events/event.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/text_elider.h"
@@ -330,9 +332,21 @@
   return suggestions_[row];
 }
 
-const std::u16string& AutofillPopupControllerImpl::GetSuggestionValueAt(
+std::u16string AutofillPopupControllerImpl::GetSuggestionMainTextAt(
     int row) const {
-  return suggestions_[row].value;
+  return suggestions_[row].frontend_id ==
+                 POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY
+             ? l10n_util::GetStringUTF16(
+                   IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE)
+             : suggestions_[row].value;
+}
+
+std::u16string AutofillPopupControllerImpl::GetSuggestionMinorTextAt(
+    int row) const {
+  return suggestions_[row].frontend_id ==
+                 POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY
+             ? suggestions_[row].value
+             : std::u16string();
 }
 
 const std::u16string& AutofillPopupControllerImpl::GetSuggestionLabelAt(
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.h b/chrome/browser/ui/autofill/autofill_popup_controller_impl.h
index b716b34e..5e8abc07 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.h
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.h
@@ -105,7 +105,8 @@
   void AcceptSuggestion(int index) override;
   int GetLineCount() const override;
   const Suggestion& GetSuggestionAt(int row) const override;
-  const std::u16string& GetSuggestionValueAt(int row) const override;
+  std::u16string GetSuggestionMainTextAt(int row) const override;
+  std::u16string GetSuggestionMinorTextAt(int row) const override;
   const std::u16string& GetSuggestionLabelAt(int row) const override;
   bool GetRemovalConfirmationText(int list_index,
                                   std::u16string* title,
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
index dc55418..8c71662 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
@@ -160,7 +160,7 @@
   using AutofillPopupControllerImpl::GetRootAXPlatformNodeForWebContents;
   using AutofillPopupControllerImpl::GetSuggestionAt;
   using AutofillPopupControllerImpl::GetSuggestionLabelAt;
-  using AutofillPopupControllerImpl::GetSuggestionValueAt;
+  using AutofillPopupControllerImpl::GetSuggestionMainTextAt;
   using AutofillPopupControllerImpl::GetWeakPtr;
   using AutofillPopupControllerImpl::RemoveSelectedLine;
   using AutofillPopupControllerImpl::selected_line;
@@ -507,7 +507,7 @@
 
   Suggestion result0 = autofill_popup_controller_->GetSuggestionAt(0);
   EXPECT_EQ(value1, result0.value);
-  EXPECT_EQ(value1, autofill_popup_controller_->GetSuggestionValueAt(0));
+  EXPECT_EQ(value1, autofill_popup_controller_->GetSuggestionMainTextAt(0));
   EXPECT_EQ(label1, result0.label);
   EXPECT_EQ(std::u16string(), result0.additional_label);
   EXPECT_EQ(label1, autofill_popup_controller_->GetSuggestionLabelAt(0));
@@ -537,12 +537,12 @@
 
   // Original one first, followed by new one, then separator.
   EXPECT_EQ(value1, autofill_popup_controller_->GetSuggestionAt(0).value);
-  EXPECT_EQ(value1, autofill_popup_controller_->GetSuggestionValueAt(0));
+  EXPECT_EQ(value1, autofill_popup_controller_->GetSuggestionMainTextAt(0));
   EXPECT_EQ(label1, autofill_popup_controller_->GetSuggestionAt(0).label);
   EXPECT_EQ(std::u16string(),
             autofill_popup_controller_->GetSuggestionAt(0).additional_label);
   EXPECT_EQ(value2, autofill_popup_controller_->GetSuggestionAt(1).value);
-  EXPECT_EQ(value2, autofill_popup_controller_->GetSuggestionValueAt(1));
+  EXPECT_EQ(value2, autofill_popup_controller_->GetSuggestionMainTextAt(1));
   EXPECT_EQ(label2, autofill_popup_controller_->GetSuggestionAt(1).label);
   EXPECT_EQ(std::u16string(),
             autofill_popup_controller_->GetSuggestionAt(1).additional_label);
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index 48a43a8..99d3a90 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -27,7 +27,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_promo_util.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h"
 #include "chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.h"
@@ -153,7 +153,7 @@
 syncer::SyncService* ChromeAutofillClient::GetSyncService() {
   Profile* profile =
       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
-  return ProfileSyncServiceFactory::GetForProfile(profile);
+  return SyncServiceFactory::GetForProfile(profile);
 }
 
 signin::IdentityManager* ChromeAutofillClient::GetIdentityManager() {
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
index 286e86d..29c7cadc 100644
--- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
+++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/autofill/autofill_bubble_base.h"
 #include "chrome/browser/ui/autofill/autofill_bubble_handler.h"
 #include "chrome/browser/ui/autofill/payments/payments_ui_constants.h"
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index cfefe1f..2f1b65d 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -32,7 +32,6 @@
 #include "chrome/browser/sharing_hub/sharing_hub_features.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/browser/signin/signin_promo.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/apps/app_info_dialog.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm
index 0d63e0d1..5277d16a0 100644
--- a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm
+++ b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm
@@ -115,7 +115,7 @@
 
 - (NSButton*)createCreditCardButtonAtRow:(int)row {
   NSString* label =
-      base::SysUTF16ToNSString(_controller->GetSuggestionValueAt(row));
+      base::SysUTF16ToNSString(_controller->GetSuggestionMainTextAt(row));
   NSString* subtext =
       base::SysUTF16ToNSString(_controller->GetSuggestionLabelAt(row));
 
diff --git a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm
index b18b9bf..bd0647e4 100644
--- a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm
@@ -67,10 +67,14 @@
     return suggestions_.at(row);
   }
 
-  const std::u16string& GetSuggestionValueAt(int row) const override {
+  std::u16string GetSuggestionMainTextAt(int row) const override {
     return suggestions_.at(row).value;
   }
 
+  std::u16string GetSuggestionMinorTextAt(int row) const override {
+    return std::u16string();
+  }
+
   const std::u16string& GetSuggestionLabelAt(int row) const override {
     return suggestions_.at(row).label;
   }
diff --git a/chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller.cc b/chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller.cc
index a8f6c18..3bd12f62 100644
--- a/chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller.cc
+++ b/chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller.cc
@@ -7,7 +7,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/favicon/core/favicon_util.h"
@@ -109,8 +109,7 @@
   metrics_util::LogMoveUIDismissalReason(
       dismissal_reason_,
       password_manager::features_util::ComputePasswordAccountStorageUserState(
-          profile->GetPrefs(),
-          ProfileSyncServiceFactory::GetForProfile(profile)));
+          profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile)));
   // TODO(crbug.com/1063852): Consider recording UKM here, via:
   // metrics_recorder_->RecordUIDismissalReason(dismissal_reason_)
 }
diff --git a/chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller_unittest.cc b/chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller_unittest.cc
index 3c4614f..10ce044e 100644
--- a/chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate_mock.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/testing_profile.h"
@@ -43,7 +43,7 @@
 
     // Make sure no real SyncService gets created (it's not needed for these
     // tests, and it'd require more setup).
-    ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+    SyncServiceFactory::GetInstance()->SetTestingFactory(
         &profile_, base::BindRepeating(&BuildTestSyncService));
 
     web_contents_ =
diff --git a/chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller.cc b/chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller.cc
index c04309a..21d126a 100644
--- a/chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller.cc
+++ b/chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller.cc
@@ -9,7 +9,7 @@
 #include "base/time/default_clock.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate.h"
 #include "chrome/grit/generated_resources.h"
@@ -81,7 +81,7 @@
 
 bool IsSyncUser(Profile* profile) {
   const syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   return password_bubble_experiment::IsSmartLockUser(sync_service);
 }
 
@@ -208,7 +208,7 @@
     return false;
   PrefService* prefs = profile->GetPrefs();
   const syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   // Signin promotion.
   if (password_bubble_experiment::ShouldShowChromeSignInPasswordPromo(
           prefs, sync_service)) {
@@ -281,8 +281,7 @@
     if (profile) {
       user_state = password_manager::features_util::
           ComputePasswordAccountStorageUserState(
-              profile->GetPrefs(),
-              ProfileSyncServiceFactory::GetForProfile(profile));
+              profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
     }
     metrics_util::LogSaveUIDismissalReason(dismissal_reason_, user_state);
   }
diff --git a/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.cc b/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.cc
index d0d907c1..188c614a 100644
--- a/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.cc
+++ b/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate.h"
 #include "chrome/grit/generated_resources.h"
@@ -349,8 +349,7 @@
     if (profile) {
       user_state = password_manager::features_util::
           ComputePasswordAccountStorageUserState(
-              profile->GetPrefs(),
-              ProfileSyncServiceFactory::GetForProfile(profile));
+              profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
     }
     metrics_util::LogSaveUIDismissalReason(dismissal_reason_, user_state);
   }
diff --git a/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller_unittest.cc b/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller_unittest.cc
index 0d4af5e..3deebaf 100644
--- a/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/bubble_controllers/save_update_with_account_store_bubble_controller_unittest.cc
@@ -17,7 +17,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate_mock.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/password_manager/core/browser/mock_password_feature_manager.h"
@@ -94,7 +94,7 @@
             &password_manager::BuildPasswordStore<
                 content::BrowserContext,
                 testing::StrictMock<password_manager::MockPasswordStore>>));
-    ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+    SyncServiceFactory::GetInstance()->SetTestingFactory(
         profile(), base::BindRepeating(&BuildTestSyncService));
     pending_password_.url = GURL(kSiteOrigin);
     pending_password_.signon_realm = kSiteOrigin;
diff --git a/chrome/browser/ui/passwords/credential_manager_dialog_controller_impl.cc b/chrome/browser/ui/passwords/credential_manager_dialog_controller_impl.cc
index 4d1e620..3a4d6d58 100644
--- a/chrome/browser/ui/passwords/credential_manager_dialog_controller_impl.cc
+++ b/chrome/browser/ui/passwords/credential_manager_dialog_controller_impl.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/passwords/credential_manager_dialog_controller_impl.h"
 
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/browser/ui/passwords/password_dialog_prompts.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate.h"
@@ -87,7 +87,7 @@
 
 bool CredentialManagerDialogControllerImpl::ShouldShowFooter() const {
   const syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   return password_bubble_experiment::IsSmartLockUser(sync_service);
 }
 
diff --git a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
index cd0cd720..c65b0e9 100644
--- a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc
@@ -13,7 +13,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/chrome_pages.h"
@@ -169,7 +169,7 @@
 
 bool IsSyncingAutosignSetting(Profile* profile) {
   const syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   return (sync_service &&
           sync_service->GetUserSettings()->IsFirstSetupComplete() &&
           sync_service->IsSyncFeatureActive() &&
diff --git a/chrome/browser/ui/passwords/settings/password_manager_presenter.cc b/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
index dbef79e..3a273b3 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
+++ b/chrome/browser/ui/passwords/settings/password_manager_presenter.cc
@@ -27,7 +27,7 @@
 #include "chrome/browser/password_manager/password_store_utils.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/browser/ui/passwords/settings/password_ui_view.h"
 #include "chrome/common/chrome_switches.h"
@@ -379,7 +379,7 @@
     const std::vector<std::string>& sort_keys,
     password_manager::PasswordManagerClient* client) {
   if (!client->GetPasswordFeatureManager()->IsOptedInForAccountStorage() ||
-      ProfileSyncServiceFactory::GetForProfile(password_view_->GetProfile())
+      SyncServiceFactory::GetForProfile(password_view_->GetProfile())
           ->IsSyncFeatureEnabled()) {
     return;
   }
@@ -426,9 +426,9 @@
   DCHECK(!it->second.empty());
   const auto& form = *it->second[0];
   syncer::SyncService* sync_service = nullptr;
-  if (ProfileSyncServiceFactory::HasSyncService(password_view_->GetProfile())) {
+  if (SyncServiceFactory::HasSyncService(password_view_->GetProfile())) {
     sync_service =
-        ProfileSyncServiceFactory::GetForProfile(password_view_->GetProfile());
+        SyncServiceFactory::GetForProfile(password_view_->GetProfile());
   }
   if (password_manager::sync_util::IsSyncAccountCredential(
           form, sync_service,
diff --git a/chrome/browser/ui/passwords/settings/password_manager_presenter_unittest.cc b/chrome/browser/ui/passwords/settings/password_manager_presenter_unittest.cc
index 4a00ebed..86dbfe9 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_presenter_unittest.cc
+++ b/chrome/browser/ui/passwords/settings/password_manager_presenter_unittest.cc
@@ -19,7 +19,7 @@
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/password_manager/core/browser/mock_password_feature_manager.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/stub_password_manager_client.h"
@@ -156,7 +156,7 @@
 
 void SetUpSyncInTransportMode(Profile* profile) {
   auto* sync_service = static_cast<syncer::TestSyncService*>(
-      ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+      SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
           profile,
           base::BindRepeating(
               [](content::BrowserContext*) -> std::unique_ptr<KeyedService> {
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index d3370d3..a6fb8db 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -28,7 +28,6 @@
 #include "chrome/browser/search/search_suggest/search_suggest_service_factory.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/bookmarks/bookmark_stats.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h
index 6b4ba6ea..60f651e 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.h
+++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -138,6 +138,8 @@
   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
                            OpenAppShortcutWindowPref);
   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, OpenAppUrlShortcut);
+  FRIEND_TEST_ALL_PREFIXES(StartupBrowserWithRealWebAppTest,
+                           LastUsedProfilesWithRealWebApp);
   FRIEND_TEST_ALL_PREFIXES(web_app::WebAppEngagementBrowserTest,
                            CommandLineTab);
   FRIEND_TEST_ALL_PREFIXES(web_app::WebAppEngagementBrowserTest,
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index 9e6868ff..73711f1 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -24,6 +24,7 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/buildflags.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -40,7 +41,9 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/scoped_profile_keep_alive.h"
 #include "chrome/browser/search/search.h"
+#include "chrome/browser/sessions/app_session_service_factory.h"
 #include "chrome/browser/sessions/session_restore.h"
+#include "chrome/browser/sessions/session_service_factory.h"
 #include "chrome/browser/signin/signin_promo.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -55,10 +58,12 @@
 #include "chrome/browser/ui/startup/startup_tab_provider.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/ui_features.h"
+#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/install_manager.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_provider_factory.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
@@ -1417,6 +1422,197 @@
   EXPECT_EQ("/title2.html", tab_strip->GetWebContentsAt(0)->GetURL().path());
 }
 
+#if BUILDFLAG(ENABLE_APP_SESSION_SERVICE)
+class StartupBrowserWithRealWebAppTest : public StartupBrowserCreatorTest {
+ protected:
+  StartupBrowserWithRealWebAppTest() = default;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {}
+
+  web_app::WebAppProvider& provider() {
+    return *web_app::WebAppProvider::Get(profile());
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(StartupBrowserWithRealWebAppTest,
+                       PRE_PRE_LastUsedProfilesWithRealWebApp) {
+  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
+  // Simulate a browser restart by creating the profiles in the PRE_PRE part.
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Create a profile.
+  base::FilePath dest_path = profile_manager->user_data_dir();
+
+  Profile* profile1 = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile1 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
+    ASSERT_TRUE(profile1);
+  }
+  DisableWelcomePages({profile1});
+
+  // Open some urls with the browsers, and close them.
+  SessionServiceFactory::GetForProfileForSessionRestore(profile1);
+  Browser* browser1 = Browser::Create({Browser::TYPE_NORMAL, profile1, true});
+  chrome::NewTab(browser1);
+  ui_test_utils::NavigateToURL(browser1,
+                               embedded_test_server()->GetURL("/title1.html"));
+  browser1->window()->Show();
+  browser1->window()->Maximize();
+
+  // Set startup preferences to restore last session.
+  SessionStartupPref pref1(SessionStartupPref::LAST);
+  SessionStartupPref::SetStartupPref(profile1, pref1);
+  profile1->GetPrefs()->CommitPendingWrite();
+
+  SessionStartupPref::SetStartupPref(browser()->profile(), pref1);
+  browser()->profile()->GetPrefs()->CommitPendingWrite();
+
+  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
+  ASSERT_EQ(1u, chrome::GetBrowserCount(profile1));
+  ASSERT_EQ(2u, BrowserList::GetInstance()->size());
+}
+
+web_app::AppId InstallPWA(Profile* profile, const GURL& start_url) {
+  auto web_app_info = std::make_unique<WebApplicationInfo>();
+  web_app_info->start_url = start_url;
+  web_app_info->scope = start_url.GetWithoutFilename();
+  web_app_info->open_as_window = true;
+  web_app_info->title = u"A Web App";
+  return web_app::test::InstallWebApp(profile, std::move(web_app_info));
+}
+
+IN_PROC_BROWSER_TEST_F(StartupBrowserWithRealWebAppTest,
+                       PRE_LastUsedProfilesWithRealWebApp) {
+  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
+
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+  base::FilePath dest_path = profile_manager->user_data_dir();
+  Profile* profile1 = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile1 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
+    ASSERT_TRUE(profile1);
+  }
+
+  auto example_url = GURL("http://www.example.com");
+  web_app::AppId new_app_id = InstallPWA(profile1, example_url);
+  Browser* app = web_app::LaunchWebAppBrowserAndWait(profile1, new_app_id);
+  ASSERT_TRUE(app);
+
+  // destroy session services so we don't record this closure.
+  // This simulates a user choosing ... -> Exit Chromium.
+  for (auto* profile : profile_manager->GetLoadedProfiles()) {
+    // Don't construct SessionServices for every type just to
+    // shut them down. If they were never created, just skip.
+    if (SessionServiceFactory::GetForProfileIfExisting(profile))
+      SessionServiceFactory::ShutdownForProfile(profile);
+
+    if (AppSessionServiceFactory::GetForProfileIfExisting(profile))
+      AppSessionServiceFactory::ShutdownForProfile(profile);
+  }
+
+  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
+  ASSERT_EQ(2u, chrome::GetBrowserCount(profile1));
+
+  // On ozone-linux, for some reason, these profile 1 windows come back in
+  // the next test. To reliably ensure they don't, but don't destroy the
+  // session restore state, close them while the session services are shutdown.
+
+  Browser* close_this = FindOneOtherBrowserForProfile(profile1, app);
+  CloseBrowserSynchronously(close_this);
+  CloseBrowserSynchronously(app);
+}
+
+#if defined(OS_MAC)
+#define MAYBE_LastUsedProfilesWithRealWebApp \
+  DISABLED_LastUsedProfilesWithRealWebApp
+#else
+#define MAYBE_LastUsedProfilesWithRealWebApp LastUsedProfilesWithRealWebApp
+#endif
+// TODO(stahon@microsoft.com) App restores are disabled on mac.
+// see http://crbug.com/1194201
+IN_PROC_BROWSER_TEST_F(StartupBrowserWithRealWebAppTest,
+                       MAYBE_LastUsedProfilesWithRealWebApp) {
+  // Make StartupBrowserCreator::WasRestarted() return true.
+  StartupBrowserCreator::was_restarted_read_ = false;
+  PrefService* pref_service = g_browser_process->local_state();
+  pref_service->SetBoolean(prefs::kWasRestarted, true);
+
+  ASSERT_TRUE(StartupBrowserCreator::WasRestarted());
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+
+  base::FilePath dest_path = profile_manager->user_data_dir();
+
+  Profile* profile1 = nullptr;
+  Profile* default_profile = nullptr;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    profile1 = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("New Profile 1")));
+    ASSERT_TRUE(profile1);
+  }
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    default_profile = profile_manager->GetProfile(
+        dest_path.Append(FILE_PATH_LITERAL("Default")));
+    ASSERT_TRUE(profile1);
+  }
+
+  // At this point, nothing is open except the basic browser.
+  ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
+  ASSERT_EQ(1u, BrowserList::GetInstance()->size());
+
+  // Trigger the restore via StartupBrowserCreator.
+  base::CommandLine dummy(base::CommandLine::NO_PROGRAM);
+  StartupBrowserCreatorImpl launch(base::FilePath(), dummy,
+                                   chrome::startup::IS_NOT_FIRST_RUN);
+  // Fake |process_startup| true.
+  EXPECT_TRUE(launch.Launch(profile1, std::vector<GURL>(),
+                            /* process_startup */ true, nullptr));
+
+  // We should get two windows from profile1.
+  ASSERT_EQ(3u, BrowserList::GetInstance()->size());
+  ASSERT_EQ(1u, chrome::GetBrowserCount(default_profile));
+  ASSERT_EQ(2u, chrome::GetBrowserCount(profile1));
+
+  while (SessionRestore::IsRestoring(profile1)) {
+    base::RunLoop().RunUntilIdle();
+  }
+
+  // Since there's one app being restored, ensure the provider is ready.
+  web_app::WebAppProvider* provider =
+      web_app::WebAppProviderFactory::GetForProfile(profile1);
+  ASSERT_TRUE(provider->on_registry_ready().is_signaled());
+
+  // The last open sessions should be restored.
+  EXPECT_TRUE(profile1->restored_last_session());
+
+  Browser* new_browser = nullptr;
+
+  // 2x profile1, 1x default profile here.
+  ASSERT_EQ(3u, BrowserList::GetInstance()->size());
+  ASSERT_EQ(2u, chrome::GetBrowserCount(profile1));
+  ASSERT_EQ(1u, chrome::GetBrowserCount(default_profile));
+  new_browser = FindOneOtherBrowserForProfile(profile1, nullptr);
+  if (new_browser->type() != Browser::Type::TYPE_NORMAL) {
+    new_browser = FindOneOtherBrowserForProfile(profile1, new_browser);
+  }
+  ASSERT_TRUE(new_browser);
+  EXPECT_EQ(new_browser->type(), Browser::Type::TYPE_NORMAL);
+
+  TabStripModel* tab_strip = new_browser->tab_strip_model();
+  EXPECT_EQ("/title1.html", tab_strip->GetWebContentsAt(0)->GetURL().path());
+
+  // Now get the app, it should just be the other browser from this profile.
+  new_browser = FindOneOtherBrowserForProfile(profile1, new_browser);
+  ASSERT_EQ(new_browser->type(), Browser::Type::TYPE_APP);
+}
+#endif  // BUILDFLAG(ENABLE_APP_SESSION_SERVICE)
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if defined(OS_WIN) || defined(OS_MAC) || \
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index 8af47d1..d813c2a 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -53,6 +53,8 @@
 #include "chrome/browser/ui/startup/startup_tab_provider.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/welcome/helpers.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_provider_factory.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -106,12 +108,10 @@
 bool ShouldRestoreApps(bool is_post_restart) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   return true;
-#elif defined(OS_MAC) || defined(OS_LINUX) || defined(OS_WIN)
+#elif defined(OS_MAC)
   // TODO(stahon@microsoft.com)
   // Even when app restores are enabled on mac, don't actually restore apps
   // because they do not restore correctly. http://crbug.com/1194201
-  // On windows and linux, apps can be restored without the proper app frame,
-  // disabling restorations for now. http://crbug.com/1199109
   return false;
 #else
   return is_post_restart;
diff --git a/chrome/browser/ui/startup/startup_tab_provider.cc b/chrome/browser/ui/startup/startup_tab_provider.cc
index 30374a1..d3b1e2e 100644
--- a/chrome/browser/ui/startup/startup_tab_provider.cc
+++ b/chrome/browser/ui/startup/startup_tab_provider.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/profile_resetter/triggered_profile_resetter_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/chrome_pages.h"
@@ -60,7 +60,7 @@
   standard_params.has_seen_welcome_page =
       prefs && prefs->GetBoolean(prefs::kHasSeenWelcomePage);
   standard_params.is_signin_allowed =
-      ProfileSyncServiceFactory::IsSyncAllowed(profile);
+      SyncServiceFactory::IsSyncAllowed(profile);
   if (auto* identity_manager = IdentityManagerFactory::GetForProfile(profile)) {
     standard_params.is_signed_in =
         identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync);
@@ -80,7 +80,7 @@
   if (!process_startup || !browser_creator)
     return tabs;
   if (browser_creator->welcome_back_page() &&
-      CanShowWelcome(ProfileSyncServiceFactory::IsSyncAllowed(profile),
+      CanShowWelcome(SyncServiceFactory::IsSyncAllowed(profile),
                      profile->IsSupervised(),
                      signin_util::IsForceSigninEnabled())) {
     tabs.emplace_back(GetWelcomePageUrl(false), false);
diff --git a/chrome/browser/ui/sync/sync_promo_ui.cc b/chrome/browser/ui/sync/sync_promo_ui.cc
index 75c2d526..f0b62c6 100644
--- a/chrome/browser/ui/sync/sync_promo_ui.cc
+++ b/chrome/browser/ui/sync/sync_promo_ui.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/signin_promo_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "components/sync/base/sync_prefs.h"
 
 bool SyncPromoUI::ShouldShowSyncPromo(Profile* profile) {
@@ -17,7 +17,7 @@
 
   syncer::SyncPrefs prefs(profile->GetPrefs());
   // Don't show if sync is not allowed to start or is running in local mode.
-  if (!ProfileSyncServiceFactory::IsSyncAllowed(profile) ||
+  if (!SyncServiceFactory::IsSyncAllowed(profile) ||
       prefs.IsLocalSyncEnabled()) {
     return false;
   }
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
index 8939362..8b63d88 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -259,10 +259,6 @@
   void OnGestureEvent(ui::GestureEvent* event) override;
 
  protected:
-  // Holds a view and a label that is stored inside the view. It can be the
-  // same object.
-  using ViewWithLabel = std::pair<std::unique_ptr<views::View>, views::Label*>;
-
   AutofillPopupItemView(AutofillPopupViewNativeViews* popup_view,
                         int line_number,
                         int frontend_id)
@@ -277,11 +273,14 @@
   int GetFrontendId() const;
 
   virtual int GetPrimaryTextStyle() = 0;
-  // Returns a value view. The label part is optional but allow caller to keep
-  // track of all the labels for background color update.
-  virtual ViewWithLabel CreateValueLabel();
+  // Returns a main text label view. The label part is optional but allow caller
+  // to keep track of all the labels for background color update.
+  virtual std::unique_ptr<views::View> CreateMainTextView();
+  // Returns a minor text label view. The label is shown side by side with the
+  // main text view, but in a secondary style. Can be nullptr.
+  virtual std::unique_ptr<views::View> CreateMinorTextView();
   // The description view can be nullptr.
-  virtual ViewWithLabel CreateDescriptionLabel();
+  virtual std::unique_ptr<views::View> CreateDescriptionView();
 
   // Returns the font weight to be applied to primary info.
   virtual gfx::Font::Weight GetPrimaryTextWeight() const = 0;
@@ -297,7 +296,7 @@
 
  private:
   // Returns a vector of optional labels to be displayed beneath value.
-  virtual std::vector<ViewWithLabel> CreateSubtextLabels();
+  virtual std::vector<std::unique_ptr<views::View>> CreateSubtextViews();
 
   // Returns the minimum cross axis size depending on the length of
   // GetSubtexts();
@@ -336,7 +335,7 @@
   // AutofillPopupItemView:
   int GetPrimaryTextStyle() override;
   gfx::Font::Weight GetPrimaryTextWeight() const override;
-  std::vector<ViewWithLabel> CreateSubtextLabels() override;
+  std::vector<std::unique_ptr<views::View>> CreateSubtextViews() override;
   AutofillPopupSuggestionView(AutofillPopupViewNativeViews* popup_view,
                               int line_number,
                               int frontend_id);
@@ -361,9 +360,9 @@
 
  protected:
   // AutofillPopupItemView:
-  ViewWithLabel CreateValueLabel() override;
-  std::vector<ViewWithLabel> CreateSubtextLabels() override;
-  ViewWithLabel CreateDescriptionLabel() override;
+  std::unique_ptr<views::View> CreateMainTextView() override;
+  std::vector<std::unique_ptr<views::View>> CreateSubtextViews() override;
+  std::unique_ptr<views::View> CreateDescriptionView() override;
   gfx::Font::Weight GetPrimaryTextWeight() const override;
 
  private:
@@ -476,15 +475,23 @@
 
 void AutofillPopupItemView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
   AutofillPopupController* controller = popup_view()->controller();
-  auto suggestion = controller->GetSuggestionAt(GetLineNumber());
   std::vector<std::u16string> text;
-  text.push_back(suggestion.value);
 
-  if (!suggestion.label.empty()) {
+  auto main_text = controller->GetSuggestionMainTextAt(GetLineNumber());
+  text.push_back(main_text);
+
+  auto minor_text = controller->GetSuggestionMinorTextAt(GetLineNumber());
+  if (!minor_text.empty())
+    text.push_back(minor_text);
+
+  auto label_text = controller->GetSuggestionLabelAt(GetLineNumber());
+  if (!label_text.empty()) {
     // |label| is not populated for footers or autocomplete entries.
-    text.push_back(suggestion.label);
+    text.push_back(label_text);
   }
 
+  // TODO(siyua): GetSuggestionLabelAt should return a vector of strings.
+  auto suggestion = controller->GetSuggestionAt(GetLineNumber());
   if (!suggestion.offer_label.empty()) {
     // |offer_label| is only populated for credit card suggestions.
     text.push_back(suggestion.offer_label);
@@ -581,29 +588,52 @@
                       /*resize=*/false, layout_manager);
   }
 
-  ViewWithLabel value_label = CreateValueLabel();
-  std::vector<ViewWithLabel> subtext_labels = CreateSubtextLabels();
-  ViewWithLabel description_label = CreateDescriptionLabel();
+  std::unique_ptr<views::View> main_text_label = CreateMainTextView();
+  std::unique_ptr<views::View> minor_text_label = CreateMinorTextView();
+  std::vector<std::unique_ptr<views::View>> subtext_labels =
+      CreateSubtextViews();
+  std::unique_ptr<views::View> description_label = CreateDescriptionView();
 
   std::unique_ptr<views::View> all_labels = std::make_unique<views::View>();
   views::GridLayout* grid_layout =
       all_labels->SetLayoutManager(std::make_unique<views::GridLayout>());
   BuildColumnSet(grid_layout);
   grid_layout->StartRow(0, 0);
-  grid_layout->AddView(std::move(value_label.first));
-  KeepLabel(value_label.second);
-  if (description_label.first) {
-    grid_layout->AddView(std::move(description_label.first));
-    KeepLabel(description_label.second);
+
+  // Create the first line text view.
+  if (minor_text_label) {
+    auto first_line_container = std::make_unique<views::View>();
+    first_line_container
+        ->SetLayoutManager(std::make_unique<views::FlexLayout>())
+        ->SetOrientation(views::LayoutOrientation::kHorizontal)
+        .SetMainAxisAlignment(views::LayoutAlignment::kStart)
+        .SetCrossAxisAlignment(views::LayoutAlignment::kCenter)
+        .SetIgnoreDefaultMainAxisMargins(true)
+        .SetCollapseMargins(true)
+        .SetDefault(views::kMarginsKey,
+                    gfx::Insets(
+                        /*vertical=*/0,
+                        /*horizontal=*/
+                        ChromeLayoutProvider::Get()->GetDistanceMetric(
+                            views::DISTANCE_RELATED_LABEL_HORIZONTAL)));
+
+    first_line_container->AddChildView(std::move(main_text_label));
+    first_line_container->AddChildView(std::move(minor_text_label));
+    grid_layout->AddView(std::move(first_line_container));
+  } else {
+    grid_layout->AddView(std::move(main_text_label));
+  }
+
+  if (description_label) {
+    grid_layout->AddView(std::move(description_label));
   } else {
     grid_layout->SkipColumns(1);
   }
 
   UpdateLayoutSize(layout_manager, subtext_labels.size());
-  for (ViewWithLabel& subtext_label : subtext_labels) {
+  for (std::unique_ptr<views::View>& subtext_label : subtext_labels) {
     grid_layout->StartRowWithPadding(0, 0, 0, kAdjacentLabelsVerticalSpacing);
-    grid_layout->AddView(std::move(subtext_label.first));
-    KeepLabel(subtext_label.second);
+    grid_layout->AddView(std::move(subtext_label));
     grid_layout->SkipColumns(1);
   }
 
@@ -643,11 +673,10 @@
                     : popup_view()->GetBackgroundColor());
 }
 
-AutofillPopupItemView::ViewWithLabel AutofillPopupItemView::CreateValueLabel() {
+std::unique_ptr<views::View> AutofillPopupItemView::CreateMainTextView() {
   // TODO(crbug.com/831603): Remove elision responsibilities from controller.
-  ViewWithLabel view_and_label;
   std::u16string text =
-      popup_view()->controller()->GetSuggestionValueAt(GetLineNumber());
+      popup_view()->controller()->GetSuggestionMainTextAt(GetLineNumber());
   if (popup_view()
           ->controller()
           ->GetSuggestionAt(GetLineNumber())
@@ -655,33 +684,42 @@
     std::unique_ptr<views::Label> label = CreateLabelWithStyleAndContext(
         text, views::style::CONTEXT_DIALOG_BODY_TEXT,
         views::style::STYLE_SECONDARY);
-    view_and_label.second = label.get();
-    view_and_label.first = std::move(label);
-    return view_and_label;
+    KeepLabel(label.get());
+    return label;
   }
 
-  auto text_label = CreateLabelWithStyleAndContext(
-      popup_view()->controller()->GetSuggestionValueAt(GetLineNumber()),
+  std::unique_ptr<views::Label> label = CreateLabelWithStyleAndContext(
+      popup_view()->controller()->GetSuggestionMainTextAt(GetLineNumber()),
       views::style::CONTEXT_DIALOG_BODY_TEXT, GetPrimaryTextStyle());
 
   const gfx::Font::Weight font_weight = GetPrimaryTextWeight();
-  if (font_weight != text_label->font_list().GetFontWeight()) {
-    text_label->SetFontList(
-        text_label->font_list().DeriveWithWeight(font_weight));
+  if (font_weight != label->font_list().GetFontWeight()) {
+    label->SetFontList(label->font_list().DeriveWithWeight(font_weight));
   }
 
-  view_and_label.second = text_label.get();
-  view_and_label.first = std::move(text_label);
-  return view_and_label;
+  KeepLabel(label.get());
+  return label;
 }
 
-AutofillPopupItemView::ViewWithLabel
-AutofillPopupItemView::CreateDescriptionLabel() {
-  return ViewWithLabel();
+std::unique_ptr<views::View> AutofillPopupItemView::CreateMinorTextView() {
+  std::u16string text =
+      popup_view()->controller()->GetSuggestionMinorTextAt(GetLineNumber());
+  if (text.empty())
+    return nullptr;
+
+  std::unique_ptr<views::Label> label = CreateLabelWithStyleAndContext(
+      text, views::style::CONTEXT_DIALOG_BODY_TEXT,
+      views::style::STYLE_SECONDARY);
+  KeepLabel(label.get());
+  return label;
 }
 
-std::vector<AutofillPopupItemView::ViewWithLabel>
-AutofillPopupItemView::CreateSubtextLabels() {
+std::unique_ptr<views::View> AutofillPopupItemView::CreateDescriptionView() {
+  return nullptr;
+}
+
+std::vector<std::unique_ptr<views::View>>
+AutofillPopupItemView::CreateSubtextViews() {
   return {};
 }
 
@@ -744,14 +782,14 @@
   SetFocusBehavior(FocusBehavior::ALWAYS);
 }
 
-std::vector<AutofillPopupItemView::ViewWithLabel>
-AutofillPopupSuggestionView::CreateSubtextLabels() {
+std::vector<std::unique_ptr<views::View>>
+AutofillPopupSuggestionView::CreateSubtextViews() {
   const std::u16string& second_row_label =
-      popup_view()->controller()->GetSuggestionAt(GetLineNumber()).label;
+      popup_view()->controller()->GetSuggestionLabelAt(GetLineNumber());
   const std::u16string& third_row_label =
       popup_view()->controller()->GetSuggestionAt(GetLineNumber()).offer_label;
 
-  std::vector<AutofillPopupItemView::ViewWithLabel> labels;
+  std::vector<std::unique_ptr<views::View>> labels;
   for (const std::u16string& text : {second_row_label, third_row_label}) {
     // If a row is missing, do not include any further rows.
     if (text.empty())
@@ -760,10 +798,8 @@
     auto label = CreateLabelWithStyleAndContext(
         text, ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL,
         views::style::STYLE_SECONDARY);
-    ViewWithLabel result;
-    result.second = label.get();
-    result.first = std::move(label);
-    labels.emplace_back(std::move(result));
+    KeepLabel(label.get());
+    labels.emplace_back(std::move(label));
   }
 
   return labels;
@@ -781,41 +817,41 @@
   return result;
 }
 
-AutofillPopupItemView::ViewWithLabel
-PasswordPopupSuggestionView::CreateValueLabel() {
-  ViewWithLabel label = AutofillPopupSuggestionView::CreateValueLabel();
-  label.first = std::make_unique<ConstrainedWidthView>(
-      std::move(label.first), kAutofillPopupUsernameMaxWidth);
+std::unique_ptr<views::View> PasswordPopupSuggestionView::CreateMainTextView() {
+  std::unique_ptr<views::View> label =
+      AutofillPopupSuggestionView::CreateMainTextView();
+  label = std::make_unique<ConstrainedWidthView>(
+      std::move(label), kAutofillPopupUsernameMaxWidth);
   return label;
 }
 
-std::vector<AutofillPopupItemView::ViewWithLabel>
-PasswordPopupSuggestionView::CreateSubtextLabels() {
-  auto label = CreateLabelWithStyleAndContext(
+std::vector<std::unique_ptr<views::View>>
+PasswordPopupSuggestionView::CreateSubtextViews() {
+  std::unique_ptr<views::Label> label = CreateLabelWithStyleAndContext(
       masked_password_, views::style::CONTEXT_DIALOG_BODY_TEXT,
       views::style::STYLE_SECONDARY);
   label->SetElideBehavior(gfx::TRUNCATE);
-  ViewWithLabel result;
-  result.second = label.get();
-  result.first = std::make_unique<ConstrainedWidthView>(
+  KeepLabel(label.get());
+
+  std::unique_ptr<views::View> result = std::make_unique<ConstrainedWidthView>(
       std::move(label), kAutofillPopupPasswordMaxWidth);
-  std::vector<AutofillPopupItemView::ViewWithLabel> labels;
+  std::vector<std::unique_ptr<views::View>> labels;
   labels.emplace_back(std::move(result));
   return labels;
 }
 
-AutofillPopupItemView::ViewWithLabel
-PasswordPopupSuggestionView::CreateDescriptionLabel() {
+std::unique_ptr<views::View>
+PasswordPopupSuggestionView::CreateDescriptionView() {
   if (origin_.empty())
-    return ViewWithLabel();
+    return nullptr;
 
-  auto label = CreateLabelWithStyleAndContext(
+  std::unique_ptr<views::Label> label = CreateLabelWithStyleAndContext(
       origin_, views::style::CONTEXT_DIALOG_BODY_TEXT,
       views::style::STYLE_SECONDARY);
   label->SetElideBehavior(gfx::ELIDE_HEAD);
-  ViewWithLabel result;
-  result.second = label.get();
-  result.first = std::make_unique<ConstrainedWidthView>(
+  KeepLabel(label.get());
+
+  std::unique_ptr<views::View> result = std::make_unique<ConstrainedWidthView>(
       std::move(label), kAutofillPopupUsernameMaxWidth);
   return result;
 }
@@ -879,10 +915,9 @@
       views::MenuConfig::instance().touchable_menu_height +
       AutofillPopupBaseView::GetCornerRadius());
 
-  ViewWithLabel value_label = CreateValueLabel();
-  value_label.first->SetEnabled(!suggestion.is_loading);
-  AddChildView(std::move(value_label.first));
-  KeepLabel(value_label.second);
+  auto main_text_label = CreateMainTextView();
+  main_text_label->SetEnabled(!suggestion.is_loading);
+  AddChildView(std::move(main_text_label));
   AddSpacerWithSize(
       ChromeLayoutProvider::Get()->GetDistanceMetric(
           DISTANCE_BETWEEN_PRIMARY_AND_SECONDARY_LABELS_HORIZONTAL),
@@ -1003,7 +1038,7 @@
       gfx::Insets(vertical_margin, horizontal_margin)));
 
   auto text_label = std::make_unique<views::Label>(
-      controller->GetSuggestionValueAt(GetLineNumber()),
+      controller->GetSuggestionMainTextAt(GetLineNumber()),
       views::style::CONTEXT_DIALOG_BODY_TEXT, ChromeTextStyle::STYLE_RED);
   text_label->SetEnabledColor(popup_view()->GetWarningColor());
   text_label->SetMultiLine(true);
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc
index bc4f931..3220416 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views_unittest.cc
@@ -46,6 +46,7 @@
     {autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_RE_SIGNIN, 1},
     {autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE, 1},
     {autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_EMPTY, 1},
+    {autofill::POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY, 1},
 };
 
 class AutofillPopupViewNativeViewsTest : public ChromeViewsTestBase {
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc
index b76e16a..0d005b4 100644
--- a/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_browsertest.cc
@@ -20,7 +20,7 @@
 #include "chrome/browser/autofill/autofill_uitest_util.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
@@ -168,8 +168,7 @@
         "components/test/data/autofill");
     embedded_test_server()->StartAcceptingConnections();
 
-    ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
-        browser()->profile())
+    SyncServiceFactory::GetAsProfileSyncServiceForProfile(browser()->profile())
         ->OverrideNetworkForTest(
             fake_server::CreateFakeServerHttpPostProviderFactory(
                 GetFakeServer()->AsWeakPtr()));
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
index 177d509..2aa5961d 100644
--- a/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/payments/save_card_bubble_views_browsertest.cc
@@ -17,7 +17,7 @@
 #include "chrome/browser/autofill/autofill_uitest_util.h"
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/secondary_account_helper.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
@@ -172,8 +172,7 @@
         "components/test/data/autofill");
     embedded_test_server()->StartAcceptingConnections();
 
-    ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
-        browser()->profile())
+    SyncServiceFactory::GetAsProfileSyncServiceForProfile(browser()->profile())
         ->OverrideNetworkForTest(
             fake_server::CreateFakeServerHttpPostProviderFactory(
                 GetFakeServer()->AsWeakPtr()));
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
index 83dfdb9..92e7e28 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -128,7 +128,7 @@
   // the toggle button functionality is implemented for OpaqueBrowserFrameView.
   web_app::AppBrowserController* controller =
       browser_view->browser()->app_controller();
-  if (controller) {
+  if (controller && controller->AppUsesWindowControlsOverlay()) {
     controller->ToggleWindowControlsOverlayEnabled();
     layout_->set_window_controls_overlay_enabled(
         browser_view->IsWindowControlsOverlayEnabled());
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
index ea55079..9590233 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
@@ -92,7 +92,7 @@
  protected:
   void SetupSyncForAccount(Profile* profile) {
     syncer::ProfileSyncService* sync_service =
-        ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(profile);
+        SyncServiceFactory::GetAsProfileSyncServiceForProfile(profile);
 
     sync_service->OverrideNetworkForTest(
         fake_server::CreateFakeServerHttpPostProviderFactory(
diff --git a/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view_unittest.cc b/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view_unittest.cc
index 64c44d0..4a24646 100644
--- a/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view_unittest.cc
+++ b/chrome/browser/ui/views/passwords/password_save_update_with_account_store_view_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/views/passwords/password_bubble_view_test_base.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/password_manager/core/browser/mock_password_feature_manager.h"
@@ -93,7 +93,7 @@
           &password_manager::BuildPasswordStore<
               content::BrowserContext,
               testing::NiceMock<password_manager::MockPasswordStore>>));
-  ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+  SyncServiceFactory::GetInstance()->SetTestingFactory(
       profile(), base::BindRepeating(&BuildTestSyncService));
 }
 
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc
index ad6450e3..44d5be1 100644
--- a/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc
+++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_ui_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "components/signin/public/identity_manager/consent_level.h"
@@ -94,7 +94,7 @@
       last_avatar_error_(sync_ui_util::GetAvatarSyncErrorType(profile)) {
   profile_observation_.Observe(&GetProfileAttributesStorage());
 
-  if (auto* sync_service = ProfileSyncServiceFactory::GetForProfile(profile_))
+  if (auto* sync_service = SyncServiceFactory::GetForProfile(profile_))
     sync_service_observation_.Observe(sync_service);
 
   AvatarToolbarButton::State state = GetState();
@@ -176,7 +176,7 @@
     return AvatarToolbarButton::State::kAnimatedUserIdentity;
   }
 
-  if (!ProfileSyncServiceFactory::IsSyncAllowed(profile_) ||
+  if (!SyncServiceFactory::IsSyncAllowed(profile_) ||
       !IdentityManagerFactory::GetForProfile(profile_)->HasPrimaryAccount(
           signin::ConsentLevel::kSync)) {
     return AvatarToolbarButton::State::kNormal;
diff --git a/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.cc b/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.cc
index 70ab65a..999e6963 100644
--- a/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.cc
+++ b/chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.h"
 
 #include "base/metrics/histogram_functions.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/browser.h"
@@ -58,7 +58,7 @@
                                              views::View* anchor_view,
                                              SkColor suggested_profile_color) {
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   // TODO(crbug.com/1213112): A speculative fix, remove if not functional or not
   // needed.
   if (!profile || !anchor_view || !sync_service)
@@ -92,7 +92,7 @@
 bool ProfileCustomizationBubbleSyncController::CanThemeSyncStart(
     Profile* profile) {
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   return CanSyncStart(sync_service);
 }
 
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc
index 9a075aa..640acbd 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -29,7 +29,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_error_controller_factory.h"
 #include "chrome/browser/signin/signin_ui_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_dialogs.h"
@@ -535,7 +535,7 @@
   Profile* profile = browser()->profile();
   // Only show the sync info if signin and sync are allowed.
   if (!profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed) ||
-      !ProfileSyncServiceFactory::IsSyncAllowed(profile)) {
+      !SyncServiceFactory::IsSyncAllowed(profile)) {
     return;
   }
 
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
index 7bc0b0e..13e275e 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
@@ -28,7 +28,7 @@
 #include "chrome/browser/profiles/profile_metrics.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/secondary_account_helper.h"
 #include "chrome/browser/sync/test/integration/status_change_checker.h"
@@ -556,7 +556,7 @@
   }
 
   syncer::ProfileSyncService* sync_service() {
-    return ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile(
+    return SyncServiceFactory::GetAsProfileSyncServiceForProfile(
         browser()->profile());
   }
 
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
index 402bb79..c4ffeff 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
@@ -20,7 +20,7 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/dice_tab_helper.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/browser.h"
@@ -996,7 +996,7 @@
   syncer::SyncPrefs prefs(profile_being_created->GetPrefs());
   prefs.SetManagedForTest(true);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_being_created);
+      SyncServiceFactory::GetForProfile(profile_being_created);
 
   // Consumer-looking gmail address avoids code that forces the sync service to
   // actually start which would add overhead in mocking further stuff.
@@ -1055,7 +1055,7 @@
   syncer::SyncPrefs prefs(profile_being_created->GetPrefs());
   prefs.SetManagedForTest(true);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_being_created);
+      SyncServiceFactory::GetForProfile(profile_being_created);
 
   // Inject a fake tab helper that confirms the enterprise dialog right away.
   base::RunLoop loop_until_enterprise_confirmed;
@@ -1216,7 +1216,7 @@
   syncer::SyncPrefs prefs(profile_being_created->GetPrefs());
   prefs.SetManagedForTest(true);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_being_created);
+      SyncServiceFactory::GetForProfile(profile_being_created);
 
   // Consumer-looking gmail address avoids code that forces the sync service to
   // actually start which would add overhead in mocking further stuff.
diff --git a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc
index 1091130..c703e66 100644
--- a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc
+++ b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/signin/reauth_result.h"
 #include "chrome/browser/signin/reauth_util.h"
 #include "chrome/browser/signin/signin_promo.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
 #include "chrome/browser/ui/signin_view_controller.h"
@@ -49,7 +49,7 @@
 int GetSyncConfirmationDialogPreferredHeight(Profile* profile) {
   // If sync is disabled, then the sync confirmation dialog looks like an error
   // dialog and thus it has the same preferred size.
-  return ProfileSyncServiceFactory::IsSyncAllowed(profile)
+  return SyncServiceFactory::IsSyncAllowed(profile)
              ? kSyncConfirmationDialogHeight
              : kSigninErrorDialogHeight;
 }
diff --git a/chrome/browser/ui/views/sharing/sharing_browsertest.cc b/chrome/browser/ui/views/sharing/sharing_browsertest.cc
index 8c3e4fa..caeac69d 100644
--- a/chrome/browser/ui/views/sharing/sharing_browsertest.cc
+++ b/chrome/browser/ui/views/sharing/sharing_browsertest.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/sharing/sharing_service_factory.h"
 #include "chrome/browser/sharing/sharing_utils.h"
 #include "chrome/browser/sync/device_info_sync_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/sessions_helper.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/toolbar_button_provider.h"
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.cc
index a641f18..14a6f27 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.cc
@@ -152,6 +152,10 @@
 void WebAppFrameToolbarView::LayoutForWindowControlsOverlay(
     gfx::Rect available_rect) {
   DCHECK(!left_container_);
+  // The center_container_ might have been laid out by the frame view such that
+  // it interferes with hit testing in the ToolbarButtonContainer. Ensure that
+  // its bounds are cleared when laying out WCO.
+  center_container_->SetBounds(0, 0, 0, 0);
 
   const int width = std::min(available_rect.width(),
                              right_container_->GetPreferredSize().width());
@@ -255,7 +259,6 @@
 
 void WebAppFrameToolbarView::OnWindowControlsOverlayEnabledChanged() {
   if (browser_view_->IsWindowControlsOverlayEnabled()) {
-    center_container_->SetBounds(0, 0, 0, 0);
     SetBackground(views::CreateSolidBackground(
         paint_as_active_ ? active_background_color_
                          : inactive_background_color_));
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc
index 4e79060..ab765f0 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.cc
+++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -327,9 +327,7 @@
   return false;
 }
 
-void AppBrowserController::ToggleWindowControlsOverlayEnabled() {
-  window_controls_overlay_enabled_ = !window_controls_overlay_enabled_;
-}
+void AppBrowserController::ToggleWindowControlsOverlayEnabled() {}
 
 bool AppBrowserController::HasReloadButton() const {
   if (!system_app_type_)
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.h b/chrome/browser/ui/web_applications/app_browser_controller.h
index ffe5327..e3375d3 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.h
+++ b/chrome/browser/ui/web_applications/app_browser_controller.h
@@ -210,9 +210,6 @@
 
   void SetOnUpdateDraggableRegionForTesting(base::OnceClosure done);
 
-  // TODO(crbug.com/937121) Remove this after persisting state.
-  bool window_controls_overlay_enabled_ = false;
-
  protected:
   explicit AppBrowserController(Browser* browser,
                                 absl::optional<web_app::AppId> app_id);
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 46e5476..8f95eea 100644
--- a/chrome/browser/ui/web_applications/web_app_browser_controller.cc
+++ b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_ui_manager_impl.h"
 #include "chrome/browser/web_applications/components/app_icon_manager.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_helpers.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
@@ -46,6 +47,7 @@
       provider_(*WebAppProvider::Get(browser->profile())) {
   registrar_observation_.Observe(&provider_.registrar());
   PerformDigitalAssetLinkVerification(browser);
+  DCHECK(HasAppId());
 }
 
 WebAppBrowserController::~WebAppBrowserController() = default;
@@ -77,10 +79,18 @@
 #if defined(OS_MAC)
   return AppUsesWindowControlsOverlay();
 #else
-  return AppUsesWindowControlsOverlay() && window_controls_overlay_enabled_;
+  return AppUsesWindowControlsOverlay() &&
+         registrar().GetWindowControlsOverlayEnabled(GetAppId());
 #endif
 }
 
+void WebAppBrowserController::ToggleWindowControlsOverlayEnabled() {
+  DCHECK(AppUsesWindowControlsOverlay());
+
+  provider_.registry_controller().SetAppWindowControlsOverlayEnabled(
+      GetAppId(), !registrar().GetWindowControlsOverlayEnabled(GetAppId()));
+}
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 bool WebAppBrowserController::ShouldShowCustomTabBar() const {
   if (AppBrowserController::ShouldShowCustomTabBar())
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 b0aeae57..b80988c0a 100644
--- a/chrome/browser/ui/web_applications/web_app_browser_controller.h
+++ b/chrome/browser/ui/web_applications/web_app_browser_controller.h
@@ -70,6 +70,7 @@
   bool IsHostedApp() const override;
   bool AppUsesWindowControlsOverlay() const override;
   bool IsWindowControlsOverlayEnabled() const override;
+  void ToggleWindowControlsOverlayEnabled() override;
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   bool ShouldShowCustomTabBar() const override;
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
index e8f9191..ead97e8 100644
--- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
@@ -9,7 +9,7 @@
 #include "base/check_op.h"
 #include "base/values.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/webui/settings/chromeos/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/sync/base/pref_names.h"
@@ -189,21 +189,20 @@
 }
 
 syncer::SyncService* OSSyncHandler::GetSyncService() const {
-  const bool is_sync_allowed =
-      ProfileSyncServiceFactory::IsSyncAllowed(profile_);
-  return is_sync_allowed ? ProfileSyncServiceFactory::GetForProfile(profile_)
+  const bool is_sync_allowed = SyncServiceFactory::IsSyncAllowed(profile_);
+  return is_sync_allowed ? SyncServiceFactory::GetForProfile(profile_)
                          : nullptr;
 }
 
 void OSSyncHandler::AddSyncServiceObserver() {
   // Observe even if sync isn't allowed. IsSyncAllowed() can change mid-session.
-  SyncService* service = ProfileSyncServiceFactory::GetForProfile(profile_);
+  SyncService* service = SyncServiceFactory::GetForProfile(profile_);
   if (service)
     service->AddObserver(this);
 }
 
 void OSSyncHandler::RemoveSyncServiceObserver() {
-  SyncService* service = ProfileSyncServiceFactory::GetForProfile(profile_);
+  SyncService* service = SyncServiceFactory::GetForProfile(profile_);
   if (service)
     service->RemoveObserver(this);
 }
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc
index 16827f9..7a730f6 100644
--- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc
+++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/bind.h"
 #include "base/values.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/webui/settings/chromeos/pref_names.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/test_chrome_web_ui_controller_factory.h"
@@ -113,7 +113,7 @@
         "test@gmail.com", signin::ConsentLevel::kSync);
 
     sync_service_ = static_cast<syncer::TestSyncService*>(
-        ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+        SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
             profile(), base::BindRepeating(&BuildTestSyncService)));
     user_settings_ = sync_service_->GetUserSettings();
 
diff --git a/chrome/browser/ui/webui/history/browsing_history_handler.cc b/chrome/browser/ui/webui/history/browsing_history_handler.cc
index 0a53cd6d..733a05b 100644
--- a/chrome/browser/ui/webui/history/browsing_history_handler.cc
+++ b/chrome/browser/ui/webui/history/browsing_history_handler.cc
@@ -26,7 +26,7 @@
 #include "chrome/browser/history/history_utils.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/device_info_sync_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
@@ -342,7 +342,7 @@
   HistoryService* local_history = HistoryServiceFactory::GetForProfile(
       profile, ServiceAccessType::EXPLICIT_ACCESS);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   browsing_history_service_ = std::make_unique<BrowsingHistoryService>(
       this, local_history, sync_service);
 
diff --git a/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc b/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc
index b2c46abc..786c083 100644
--- a/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc
+++ b/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc
@@ -19,7 +19,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/history/web_history_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/history/core/browser/browsing_history_service.h"
@@ -86,7 +86,7 @@
     ChromeRenderViewHostTestHarness::SetUp();
 
     sync_service_ = static_cast<syncer::TestSyncService*>(
-        ProfileSyncServiceFactory::GetForProfile(profile()));
+        SyncServiceFactory::GetForProfile(profile()));
     web_history_service_ = static_cast<history::FakeWebHistoryService*>(
         WebHistoryServiceFactory::GetForProfile(profile()));
     ASSERT_TRUE(web_history_service_);
@@ -102,7 +102,7 @@
 
   TestingProfile::TestingFactories GetTestingFactories() const override {
     return {
-        {ProfileSyncServiceFactory::GetInstance(),
+        {SyncServiceFactory::GetInstance(),
          base::BindRepeating(&BuildTestSyncService)},
         {WebHistoryServiceFactory::GetInstance(),
          base::BindRepeating(&BuildFakeWebHistoryService)},
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
index 6a1931d..fd3d2f2e 100644
--- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
 #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h"
 #include "chromeos/components/local_search_service/public/cpp/local_search_service_proxy_factory.h"
@@ -44,7 +44,7 @@
       local_search_service::LocalSearchServiceProxyFactory::GetInstance());
   DependsOn(multidevice_setup::MultiDeviceSetupClientFactory::GetInstance());
   DependsOn(phonehub::PhoneHubManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(SupervisedUserServiceFactory::GetInstance());
   DependsOn(KerberosCredentialsManagerFactory::GetInstance());
   DependsOn(ArcAppListPrefsFactory::GetInstance());
@@ -75,7 +75,7 @@
           GetForBrowserContext(context),
       multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(profile),
       phonehub::PhoneHubManagerFactory::GetForProfile(profile),
-      ProfileSyncServiceFactory::GetForProfile(profile),
+      SyncServiceFactory::GetForProfile(profile),
       SupervisedUserServiceFactory::GetForProfile(profile),
       kerberos_credentials_manager,
       ArcAppListPrefsFactory::GetForBrowserContext(profile),
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
index 5524951..df0fc05 100644
--- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
@@ -17,7 +17,7 @@
 #include "chrome/browser/chromeos/printing/cups_printers_manager_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
 #include "chrome/browser/ui/webui/settings/chromeos/constants/constants_util.h"
 #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
@@ -63,7 +63,7 @@
         multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(
             profile),
         phonehub::PhoneHubManagerFactory::GetForProfile(profile),
-        ProfileSyncServiceFactory::GetForProfile(profile),
+        SyncServiceFactory::GetForProfile(profile),
         SupervisedUserServiceFactory::GetForProfile(profile),
         kerberos_credentials_manager,
         ArcAppListPrefsFactory::GetForBrowserContext(profile),
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index bc843d0..b22eecd 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -26,7 +26,7 @@
 #include "chrome/browser/signin/signin_promo.h"
 #include "chrome/browser/signin/signin_ui_util.h"
 #include "chrome/browser/signin/signin_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
@@ -342,7 +342,7 @@
   // This is intentionally not using GetSyncService(), to go around the
   // Profile::IsSyncAllowed() check.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+      SyncServiceFactory::GetForProfile(profile_);
   if (sync_service)
     sync_service_observation_.Observe(sync_service);
 }
@@ -413,8 +413,8 @@
 }
 
 syncer::SyncService* PeopleHandler::GetSyncService() const {
-  return ProfileSyncServiceFactory::IsSyncAllowed(profile_)
-             ? ProfileSyncServiceFactory::GetForProfile(profile_)
+  return SyncServiceFactory::IsSyncAllowed(profile_)
+             ? SyncServiceFactory::GetForProfile(profile_)
              : nullptr;
 }
 
@@ -905,8 +905,7 @@
   // This is intentionally not using GetSyncService(), in order to access more
   // nuanced information, since GetSyncService() returns nullptr if anything
   // makes Profile::IsSyncAllowed() false.
-  syncer::SyncService* service =
-      ProfileSyncServiceFactory::GetForProfile(profile_);
+  syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
   bool disallowed_by_policy =
       service && service->HasDisableReason(
                      syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
index cbc301c..0af90da 100644
--- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -22,7 +22,7 @@
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/signin/signin_error_controller_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
@@ -220,7 +220,7 @@
         std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile());
 
     mock_sync_service_ = static_cast<syncer::MockSyncService*>(
-        ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+        SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
             profile(), base::BindRepeating(&BuildMockSyncService)));
 
     ON_CALL(*mock_sync_service_, IsAuthenticatedAccountPrimary())
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
index 40e6fa08f..2ff9589 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
@@ -21,7 +21,7 @@
 #include "chrome/browser/history/web_history_service_factory.h"
 #include "chrome/browser/signin/account_reconcilor_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/pref_names.h"
@@ -76,7 +76,7 @@
 ClearBrowsingDataHandler::ClearBrowsingDataHandler(content::WebUI* webui,
                                                    Profile* profile)
     : profile_(profile),
-      sync_service_(ProfileSyncServiceFactory::GetForProfile(profile_)),
+      sync_service_(SyncServiceFactory::GetForProfile(profile_)),
       show_history_deletion_dialog_(false) {}
 
 ClearBrowsingDataHandler::~ClearBrowsingDataHandler() {
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 273e1256..373a81f 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -28,7 +28,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_shortcut_manager.h"
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/webui/management/management_ui.h"
@@ -1102,7 +1102,7 @@
       "migrationEnabled",
       !is_guest_mode && autofill::IsCreditCardMigrationEnabled(
                             personal_data, profile->GetPrefs(),
-                            ProfileSyncServiceFactory::GetForProfile(profile),
+                            SyncServiceFactory::GetForProfile(profile),
                             /*is_test_mode=*/false,
                             /*log_manager=*/nullptr));
   html_source->AddBoolean(
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
index fcc979c..dab0be8 100644
--- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
+++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
@@ -30,7 +30,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/signin_features.h"
 #include "chrome/browser/signin/signin_util.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tab_dialogs.h"
 #include "chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_delegate_impl.h"
@@ -78,7 +78,7 @@
       : BrowserContextKeyedServiceShutdownNotifierFactory(
             "DiceTurnSyncOnHelperShutdownNotifier") {
     DependsOn(IdentityManagerFactory::GetInstance());
-    DependsOn(ProfileSyncServiceFactory::GetInstance());
+    DependsOn(SyncServiceFactory::GetInstance());
     DependsOn(UnifiedConsentServiceFactory::GetInstance());
     DependsOn(policy::UserPolicySigninServiceFactory::GetInstance());
   }
@@ -458,8 +458,8 @@
 }
 
 syncer::SyncService* DiceTurnSyncOnHelper::GetSyncService() {
-  return ProfileSyncServiceFactory::IsSyncAllowed(profile_)
-             ? ProfileSyncServiceFactory::GetForProfile(profile_)
+  return SyncServiceFactory::IsSyncAllowed(profile_)
+             ? SyncServiceFactory::GetForProfile(profile_)
              : nullptr;
 }
 
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
index 4bd580a..b307b863 100644
--- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
+++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
@@ -25,7 +25,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/signin/test_signin_client_builder.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/webui/signin/signin_ui_error.h"
 #include "chrome/test/base/fake_profile_manager.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
@@ -202,7 +202,7 @@
   profile_builder.AddTestingFactory(
       ChromeSigninClientFactory::GetInstance(),
       base::BindRepeating(&signin::BuildTestSigninClient));
-  profile_builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+  profile_builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                                     base::BindRepeating(&BuildMockSyncService));
   profile_builder.AddTestingFactory(
       policy::UserPolicySigninServiceFactory::GetInstance(),
@@ -299,7 +299,7 @@
 
   syncer::MockSyncService* GetMockSyncService(Profile* profile) {
     return static_cast<syncer::MockSyncService*>(
-        ProfileSyncServiceFactory::GetForProfile(profile));
+        SyncServiceFactory::GetForProfile(profile));
   }
 
   DiceTurnSyncOnHelper* CreateDiceTurnOnSyncHelper(
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
index 116fdde..87388f2 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/signin_view_controller_delegate.h"
@@ -92,7 +92,7 @@
 }
 
 void SyncConfirmationHandler::HandleGoToSettings(const base::ListValue* args) {
-  DCHECK(ProfileSyncServiceFactory::IsSyncAllowed(profile_));
+  DCHECK(SyncServiceFactory::IsSyncAllowed(profile_));
   did_user_explicitly_interact_ = true;
   RecordConsent(args);
   CloseModalSigninWindow(LoginUIService::CONFIGURE_SYNC_FIRST);
@@ -105,7 +105,7 @@
 
 void SyncConfirmationHandler::HandleAccountInfoRequest(
     const base::ListValue* args) {
-  DCHECK(ProfileSyncServiceFactory::IsSyncAllowed(profile_));
+  DCHECK(SyncServiceFactory::IsSyncAllowed(profile_));
   absl::optional<AccountInfo> primary_account_info =
       identity_manager_->FindExtendedAccountInfoForAccountWithRefreshToken(
           identity_manager_->GetPrimaryAccountInfo(ConsentLevel::kSignin));
@@ -157,7 +157,7 @@
 
 void SyncConfirmationHandler::SetAccountInfo(const AccountInfo& info) {
   DCHECK(info.IsValid());
-  if (!ProfileSyncServiceFactory::IsSyncAllowed(profile_)) {
+  if (!SyncServiceFactory::IsSyncAllowed(profile_)) {
     // The sync disabled confirmation handler does not present the user image.
     // Avoid updating the image URL in this case.
     return;
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
index e2da39f..9e6e83a 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/signin/profile_colors_util.h"
 #include "chrome/browser/ui/webui/signin/sync_confirmation_handler.h"
@@ -63,8 +63,7 @@
 
 void SyncConfirmationUI::Initialize(
     absl::optional<SkColor> profile_creation_flow_color) {
-  const bool is_sync_allowed =
-      ProfileSyncServiceFactory::IsSyncAllowed(profile_);
+  const bool is_sync_allowed = SyncServiceFactory::IsSyncAllowed(profile_);
 
   content::WebUIDataSource* source =
       content::WebUIDataSource::Create(chrome::kChromeUISyncConfirmationHost);
diff --git a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
index a2cb8d1..5db5011 100644
--- a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
@@ -12,8 +12,8 @@
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/sync_invalidations_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
 #include "chrome/common/channel_info.h"
 #include "components/sync/base/model_type.h"
@@ -384,7 +384,7 @@
 }
 
 SyncService* SyncInternalsMessageHandler::GetSyncService() {
-  return ProfileSyncServiceFactory::GetForProfile(
+  return SyncServiceFactory::GetForProfile(
       Profile::FromWebUI(web_ui())->GetOriginalProfile());
 }
 
diff --git a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler_unittest.cc b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler_unittest.cc
index 59ab84a..dce23432 100644
--- a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler_unittest.cc
+++ b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler_unittest.cc
@@ -10,7 +10,7 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/sync/user_event_service_factory.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
@@ -102,7 +102,7 @@
 
     web_ui_.set_web_contents(web_contents());
     test_sync_service_ = static_cast<TestSyncService*>(
-        ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+        SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
             profile(), base::BindRepeating(&BuildTestSyncService)));
     fake_user_event_service_ = static_cast<FakeUserEventService*>(
         browser_sync::UserEventServiceFactory::GetInstance()
@@ -234,7 +234,7 @@
 
 TEST_F(SyncInternalsMessageHandlerTest, AddRemoveObserversSyncDisabled) {
   // Simulate completely disabling sync by flag or other mechanism.
-  ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+  SyncServiceFactory::GetInstance()->SetTestingFactory(
       profile(), BrowserContextKeyedServiceFactory::TestingFactory());
 
   ListValue empty_list;
@@ -281,7 +281,7 @@
 
 TEST_F(SyncInternalsMessageHandlerTest, SendAboutInfoSyncDisabled) {
   // Simulate completely disabling sync by flag or other mechanism.
-  ProfileSyncServiceFactory::GetInstance()->SetTestingFactory(
+  SyncServiceFactory::GetInstance()->SetTestingFactory(
       profile(), BrowserContextKeyedServiceFactory::TestingFactory());
 
   handler()->AllowJavascriptForTesting();
diff --git a/chrome/browser/unified_consent/unified_consent_browsertest.cc b/chrome/browser/unified_consent/unified_consent_browsertest.cc
index 8b73397..072e9ce3 100644
--- a/chrome/browser/unified_consent/unified_consent_browsertest.cc
+++ b/chrome/browser/unified_consent/unified_consent_browsertest.cc
@@ -6,7 +6,6 @@
 #include <string>
 
 #include "base/test/metrics/histogram_tester.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h"
diff --git a/chrome/browser/unified_consent/unified_consent_service_factory.cc b/chrome/browser/unified_consent/unified_consent_service_factory.cc
index cf51a90..6a8af00 100644
--- a/chrome/browser/unified_consent/unified_consent_service_factory.cc
+++ b/chrome/browser/unified_consent/unified_consent_service_factory.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/prefs/pref_service_syncable_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/pref_names.h"
 #include "components/embedder_support/pref_names.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -50,7 +50,7 @@
           "UnifiedConsentService",
           BrowserContextDependencyManager::GetInstance()) {
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 UnifiedConsentServiceFactory::~UnifiedConsentServiceFactory() = default;
@@ -81,7 +81,7 @@
   RecordSettingsHistogram(pref_service);
 
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForProfile(profile);
+      SyncServiceFactory::GetForProfile(profile);
   if (!sync_service)
     return nullptr;
 
diff --git a/chrome/browser/web_applications/components/app_registrar.h b/chrome/browser/web_applications/components/app_registrar.h
index be60f6c..bfd45d4 100644
--- a/chrome/browser/web_applications/components/app_registrar.h
+++ b/chrome/browser/web_applications/components/app_registrar.h
@@ -153,6 +153,8 @@
   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.
diff --git a/chrome/browser/web_applications/components/app_registry_controller.h b/chrome/browser/web_applications/components/app_registry_controller.h
index d917781d..227a4fb 100644
--- a/chrome/browser/web_applications/components/app_registry_controller.h
+++ b/chrome/browser/web_applications/components/app_registry_controller.h
@@ -69,6 +69,9 @@
   virtual void SetAppRunOnOsLoginMode(const AppId& app_id,
                                       RunOnOsLoginMode mode) = 0;
 
+  virtual void SetAppWindowControlsOverlayEnabled(const AppId& app_id,
+                                                  bool enabled) = 0;
+
   // Safe downcast:
   virtual WebAppSyncBridge* AsWebAppSyncBridge() = 0;
 
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto
index 8e2a43d..10fc4c3 100644
--- a/chrome/browser/web_applications/proto/web_app.proto
+++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -206,4 +206,6 @@
   // |downloaded_icon_sizes_purpose_any|,
   // |downloaded_icon_sizes_purpose_maskable|.
   repeated int32 downloaded_icon_sizes_purpose_monochrome = 33;
+
+  optional bool window_controls_overlay_enabled = 34;
 }
diff --git a/chrome/browser/web_applications/test/test_app_registrar.cc b/chrome/browser/web_applications/test/test_app_registrar.cc
index a135e8a..d51020a 100644
--- a/chrome/browser/web_applications/test/test_app_registrar.cc
+++ b/chrome/browser/web_applications/test/test_app_registrar.cc
@@ -229,6 +229,12 @@
   return RunOnOsLoginMode::kNotRun;
 }
 
+bool TestAppRegistrar::GetWindowControlsOverlayEnabled(
+    const AppId& app_id) const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
 std::vector<AppId> TestAppRegistrar::GetAppIds() const {
   std::vector<AppId> result;
   for (const std::pair<const AppId, AppInfo>& it : installed_apps_) {
diff --git a/chrome/browser/web_applications/test/test_app_registrar.h b/chrome/browser/web_applications/test/test_app_registrar.h
index 7c79b08..916a284 100644
--- a/chrome/browser/web_applications/test/test_app_registrar.h
+++ b/chrome/browser/web_applications/test/test_app_registrar.h
@@ -93,6 +93,7 @@
   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;
diff --git a/chrome/browser/web_applications/test/test_app_registry_controller.cc b/chrome/browser/web_applications/test/test_app_registry_controller.cc
index 20ab19c..2df35b1 100644
--- a/chrome/browser/web_applications/test/test_app_registry_controller.cc
+++ b/chrome/browser/web_applications/test/test_app_registry_controller.cc
@@ -38,6 +38,10 @@
 void TestAppRegistryController::SetAppRunOnOsLoginMode(const AppId& app_id,
                                                        RunOnOsLoginMode mode) {}
 
+void TestAppRegistryController::SetAppWindowControlsOverlayEnabled(
+    const AppId& app_id,
+    bool enabled) {}
+
 WebAppSyncBridge* TestAppRegistryController::AsWebAppSyncBridge() {
   return nullptr;
 }
diff --git a/chrome/browser/web_applications/test/test_app_registry_controller.h b/chrome/browser/web_applications/test/test_app_registry_controller.h
index 160401f..927f72c 100644
--- a/chrome/browser/web_applications/test/test_app_registry_controller.h
+++ b/chrome/browser/web_applications/test/test_app_registry_controller.h
@@ -30,6 +30,8 @@
   void SetAppInstallTime(const AppId& app_id, const base::Time& time) override;
   void SetAppRunOnOsLoginMode(const AppId& app_id,
                               RunOnOsLoginMode mode) override;
+  void SetAppWindowControlsOverlayEnabled(const AppId& app_id,
+                                          bool enabled) override;
 
   WebAppSyncBridge* AsWebAppSyncBridge() override;
 };
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc
index 5df5dc6..e941779 100644
--- a/chrome/browser/web_applications/test/web_app_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -356,6 +356,8 @@
 
   app->SetFileHandlerPermissionBlocked(false);
 
+  app->SetWindowControlsOverlayEnabled(false);
+
   WebApp::SyncFallbackData sync_fallback_data;
   sync_fallback_data.name = "Sync" + name;
   sync_fallback_data.theme_color = synced_theme_color;
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index cd28a70..685b469 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -301,6 +301,10 @@
   file_handler_permission_blocked_ = permission_blocked;
 }
 
+void WebApp::SetWindowControlsOverlayEnabled(bool enabled) {
+  window_controls_overlay_enabled_ = enabled;
+}
+
 WebApp::ClientData::ClientData() = default;
 
 WebApp::ClientData::~ClientData() = default;
@@ -490,6 +494,9 @@
   out << "system_web_app:" << std::endl
       << Indent(app.client_data_.system_web_app_data) << std::endl;
 
+  out << "window_controls_overlay_enabled:" << std::endl
+      << Indent(app.window_controls_overlay_enabled_) << std::endl;
+
   return out;
 }
 
@@ -551,7 +558,8 @@
         app.manifest_url_,
         app.manifest_id_,
         app.client_data_.system_web_app_data,
-        app.file_handler_permission_blocked_
+        app.file_handler_permission_blocked_,
+        app.window_controls_overlay_enabled_
         // clang-format on
     );
   };
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h
index b0c0bdf..7b7c6b2 100644
--- a/chrome/browser/web_applications/web_app.h
+++ b/chrome/browser/web_applications/web_app.h
@@ -153,6 +153,10 @@
     return run_on_os_login_mode_;
   }
 
+  bool window_controls_overlay_enabled() const {
+    return window_controls_overlay_enabled_;
+  }
+
   // While local |name| and |theme_color| may vary from device to device, the
   // synced copies of these fields are replicated to all devices. The synced
   // copies are read by a device to generate a placeholder icon (if needed). Any
@@ -252,6 +256,7 @@
   void SetManifestUrl(const GURL& manifest_url);
   void SetManifestId(const absl::optional<std::string>& manifest_id);
   void SetFileHandlerPermissionBlocked(bool permission_blocked);
+  void SetWindowControlsOverlayEnabled(bool enabled);
 
   // For logging and debug purposes.
   bool operator==(const WebApp&) const;
@@ -313,6 +318,7 @@
   GURL manifest_url_;
   absl::optional<std::string> manifest_id_;
   bool file_handler_permission_blocked_ = false;
+  bool window_controls_overlay_enabled_ = false;
   // New fields must be added to:
   //  - |operator==|
   //  - |operator<<|
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc
index 91faa5c0..586313c2 100644
--- a/chrome/browser/web_applications/web_app_database.cc
+++ b/chrome/browser/web_applications/web_app_database.cc
@@ -386,6 +386,9 @@
 
   local_data->set_file_handler_permission_blocked(
       web_app.file_handler_permission_blocked());
+
+  local_data->set_window_controls_overlay_enabled(
+      web_app.window_controls_overlay_enabled());
   return local_data;
 }
 
@@ -788,6 +791,11 @@
   if (local_data.has_file_handler_permission_blocked())
     web_app->SetFileHandlerPermissionBlocked(
         local_data.file_handler_permission_blocked());
+
+  if (local_data.has_window_controls_overlay_enabled()) {
+    web_app->SetWindowControlsOverlayEnabled(
+        local_data.window_controls_overlay_enabled());
+  }
   return web_app;
 }
 
diff --git a/chrome/browser/web_applications/web_app_mover.cc b/chrome/browser/web_applications/web_app_mover.cc
index 5aa654a..cfcdcaeb 100644
--- a/chrome/browser/web_applications/web_app_mover.cc
+++ b/chrome/browser/web_applications/web_app_mover.cc
@@ -13,7 +13,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/sync/profile_sync_service_factory.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"
@@ -142,7 +142,7 @@
 void WebAppMover::Start() {
   // We cannot grab the SyncService in the constructor without creating a
   // circular KeyedService dependency.
-  sync_service_ = ProfileSyncServiceFactory::GetForProfile(profile_);
+  sync_service_ = SyncServiceFactory::GetForProfile(profile_);
   // This can be a nullptr if the --disable-sync switch is specified.
   if (sync_service_)
     sync_observer_.Observe(sync_service_);
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc
index 6f0bdc0..3a5e2bb 100644
--- a/chrome/browser/web_applications/web_app_registrar.cc
+++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -267,6 +267,12 @@
   return web_app ? web_app->run_on_os_login_mode() : RunOnOsLoginMode::kNotRun;
 }
 
+bool WebAppRegistrar::GetWindowControlsOverlayEnabled(
+    const AppId& app_id) const {
+  auto* web_app = GetAppById(app_id);
+  return web_app ? web_app->window_controls_overlay_enabled() : false;
+}
+
 WebAppRegistrar* WebAppRegistrar::AsWebAppRegistrar() {
   return this;
 }
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h
index 4c94599..55f7704 100644
--- a/chrome/browser/web_applications/web_app_registrar.h
+++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -91,6 +91,7 @@
   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;
diff --git a/chrome/browser/web_applications/web_app_registrar_unittest.cc b/chrome/browser/web_applications/web_app_registrar_unittest.cc
index 4708473..8abe81b 100644
--- a/chrome/browser/web_applications/web_app_registrar_unittest.cc
+++ b/chrome/browser/web_applications/web_app_registrar_unittest.cc
@@ -915,4 +915,20 @@
             registrar().GetAppRunOnOsLoginMode(app_id));
 }
 
+TEST_F(WebAppRegistrarTest, WindowControlsOverlay) {
+  controller().Init();
+
+  auto web_app = CreateWebApp("https://example.com/path");
+  const AppId app_id = web_app->app_id();
+  RegisterApp(std::move(web_app));
+
+  EXPECT_EQ(false, registrar().GetWindowControlsOverlayEnabled(app_id));
+
+  sync_bridge().SetAppWindowControlsOverlayEnabled(app_id, true);
+  EXPECT_EQ(true, registrar().GetWindowControlsOverlayEnabled(app_id));
+
+  sync_bridge().SetAppWindowControlsOverlayEnabled(app_id, false);
+  EXPECT_EQ(false, registrar().GetWindowControlsOverlayEnabled(app_id));
+}
+
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc
index c35412a..7c291042 100644
--- a/chrome/browser/web_applications/web_app_sync_bridge.cc
+++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -212,6 +212,13 @@
   if (web_app)
     web_app->SetRunOnOsLoginMode(mode);
 }
+void WebAppSyncBridge::SetAppWindowControlsOverlayEnabled(const AppId& app_id,
+                                                          bool enabled) {
+  ScopedRegistryUpdate update(this);
+  WebApp* web_app = update->UpdateApp(app_id);
+  if (web_app)
+    web_app->SetWindowControlsOverlayEnabled(enabled);
+}
 
 void WebAppSyncBridge::SetAppIsDisabled(const AppId& app_id, bool is_disabled) {
   if (!IsChromeOsDataMandatory())
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.h b/chrome/browser/web_applications/web_app_sync_bridge.h
index 04f00de..27a9177 100644
--- a/chrome/browser/web_applications/web_app_sync_bridge.h
+++ b/chrome/browser/web_applications/web_app_sync_bridge.h
@@ -84,6 +84,8 @@
   void SetAppInstallTime(const AppId& app_id, const base::Time& time) override;
   void SetAppRunOnOsLoginMode(const AppId& app_id,
                               RunOnOsLoginMode mode) override;
+  void SetAppWindowControlsOverlayEnabled(const AppId& app_id,
+                                          bool enabled) override;
   WebAppSyncBridge* AsWebAppSyncBridge() override;
 
   // These methods are used by extensions::AppSorting, which manages the sorting
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc
index a1f05851..78695b57 100644
--- a/chrome/browser/web_applications/web_app_unittest.cc
+++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -194,6 +194,8 @@
   nullopt
 system_web_app:
   nullopt
+window_controls_overlay_enabled:
+  0
 )") << "Copypastable expectation: \n"
     << debug_string;
 }
@@ -348,6 +350,8 @@
   nullopt
 system_web_app:
   nullopt
+window_controls_overlay_enabled:
+  0
 )") << "Copypastable expectation: \n"
     << debug_string;
 }
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index aa2ea51..6a4b74a 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-master-1622548311-634ae7aa517bfdcc37267c34eaf23279f6ac6ae5.profdata
+chrome-win64-master-1622559517-888d0ce4885aac3784e12cd03c7ecbcbaa85a2a9.profdata
diff --git a/chrome/common/extensions/api/speech/tts_engine_manifest_handler_unittest.cc b/chrome/common/extensions/api/speech/tts_engine_manifest_handler_unittest.cc
new file mode 100644
index 0000000..355b75b6
--- /dev/null
+++ b/chrome/common/extensions/api/speech/tts_engine_manifest_handler_unittest.cc
@@ -0,0 +1,65 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/extensions/api/speech/tts_engine_manifest_handler.h"
+#include "base/strings/stringprintf.h"
+#include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
+#include "extensions/common/manifest_constants.h"
+#include "media/base/limits.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+using TtsManifestTest = ChromeManifestTest;
+
+namespace errors = manifest_errors;
+
+TEST_F(TtsManifestTest, TtsEngine) {
+  std::string error_invalid_sample_rate_range = base::StringPrintf(
+      errors::kInvalidTtsSampleRateRange, media::limits::kMinSampleRate,
+      media::limits::kMaxSampleRate);
+  std::string error_invalid_buffer_size_range =
+      base::StringPrintf(errors::kInvalidTtsBufferSizeRange, 1,
+                         media::limits::kMaxSamplesPerPacket);
+
+  Testcase testcases[] = {
+      Testcase("tts_engine_invalid_voices_1.json", errors::kInvalidTts),
+      Testcase("tts_engine_invalid_voices_2.json", errors::kInvalidTtsVoices),
+      Testcase("tts_engine_invalid_voices_3.json", errors::kInvalidTtsVoices),
+      Testcase("tts_engine_invalid_voices_4.json",
+               errors::kInvalidTtsVoicesVoiceName),
+      Testcase("tts_engine_invalid_voices_5.json",
+               errors::kInvalidTtsVoicesLang),
+      Testcase("tts_engine_invalid_voices_6.json",
+               errors::kInvalidTtsVoicesLang),
+      Testcase("tts_engine_invalid_voices_7.json",
+               errors::kInvalidTtsVoicesEventTypes),
+      Testcase("tts_engine_invalid_voices_8.json",
+               errors::kInvalidTtsVoicesEventTypes),
+
+      Testcase("tts_engine_invalid_sample_rate_1.json",
+               errors::kInvalidTtsSampleRateFormat),
+      Testcase("tts_engine_invalid_sample_rate_2.json",
+               error_invalid_sample_rate_range),
+      Testcase("tts_engine_invalid_sample_rate_3.json",
+               error_invalid_sample_rate_range),
+      Testcase("tts_engine_invalid_sample_rate_4.json",
+               errors::kInvalidTtsRequiresSampleRateAndBufferSize),
+
+      Testcase("tts_engine_invalid_buffer_size_1.json",
+               errors::kInvalidTtsBufferSizeFormat),
+      Testcase("tts_engine_invalid_buffer_size_2.json",
+               error_invalid_buffer_size_range),
+      Testcase("tts_engine_invalid_buffer_size_3.json",
+               error_invalid_buffer_size_range),
+      Testcase("tts_engine_invalid_buffer_size_4.json",
+               errors::kInvalidTtsRequiresSampleRateAndBufferSize),
+  };
+  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+
+  LoadAndExpectSuccess("tts_engine_valid_voices.json");
+  LoadAndExpectSuccess("tts_engine_valid_sample_rate_buffer_size.json");
+}
+
+}  // namespace extensions
diff --git a/chrome/renderer/cart/commerce_hint_agent.cc b/chrome/renderer/cart/commerce_hint_agent.cc
index 2ba0bee..2a4add8 100644
--- a/chrome/renderer/cart/commerce_hint_agent.cc
+++ b/chrome/renderer/cart/commerce_hint_agent.cc
@@ -59,6 +59,12 @@
       url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
 }
 
+bool IsCartHeuristicsImprovementEnabled() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      ntp_features::kNtpChromeCartModule,
+      ntp_features::kNtpChromeCartModuleHeuristicsImprovementParam, false);
+}
+
 enum class CommerceEvent {
   kAddToCartByForm,
   kAddToCartByURL,
@@ -414,6 +420,19 @@
                           "");
 }
 
+const WebString& GetProductExtractionScript() {
+  static base::NoDestructor<WebString> script([] {
+    std::string script_string =
+        ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
+            IDR_CART_PRODUCT_EXTRACTION_JS);
+    if (IsCartHeuristicsImprovementEnabled()) {
+      script_string = "var isImprovementEnabled = true;\n" + script_string;
+    }
+    return WebString::FromUTF8(std::move(script_string));
+  }());
+  return *script;
+}
+
 }  // namespace
 
 CommerceHintAgent::CommerceHintAgent(content::RenderFrame* render_frame)
@@ -481,14 +500,9 @@
 void CommerceHintAgent::ExtractProducts() {
   // TODO(crbug/1164236): Implement rate control.
   blink::WebLocalFrame* main_frame = render_frame()->GetWebFrame();
-
-  std::string script =
-      ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
-          IDR_CART_PRODUCT_EXTRACTION_JS);
-
   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
   blink::WebScriptSource source =
-      blink::WebScriptSource(WebString::FromUTF8(script));
+      blink::WebScriptSource(GetProductExtractionScript());
 
   JavaScriptRequest* request =
       new JavaScriptRequest(weak_factory_.GetWeakPtr());
diff --git a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
index fcec4c04..ed036b0 100644
--- a/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
+++ b/chrome/renderer/cart/commerce_hint_agent_browsertest.cc
@@ -109,6 +109,13 @@
         kMockExample,
         kMockExampleURL,
         {"https://static.guitarcenter.com/product-image/foo_123-0-medium",
+         "https://images.cymax.com/Images/3/bar_456-baz_789-0-medium",
+         "https://static.guitarcenter.com/product-image/qux_357-0-medium"});
+const cart_db::ChromeCartContentProto
+    kMockExampleProtoWithProductsWithoutSaved = BuildProtoWithProducts(
+        kMockExample,
+        kMockExampleURL,
+        {"https://static.guitarcenter.com/product-image/foo_123-0-medium",
          "https://images.cymax.com/Images/3/bar_456-baz_789-0-medium"});
 
 const char kMockAmazon[] = "amazon.com";
@@ -125,6 +132,8 @@
 const ShoppingCarts kExpectedExample = {{kMockExample, kMockExampleProto}};
 const ShoppingCarts kExpectedExampleWithProducts = {
     {kMockExample, kMockExampleProtoWithProducts}};
+const ShoppingCarts kExpectedExampleWithProductsWithoutSaved = {
+    {kMockExample, kMockExampleProtoWithProductsWithoutSaved}};
 const ShoppingCarts kExpectedAmazon = {{kMockAmazon, kMockAmazonProto}};
 const ShoppingCarts kEmptyExpected = {};
 
@@ -387,7 +396,7 @@
 }
 
 IN_PROC_BROWSER_TEST_F(CommerceHintAgentTest, ExtractCart) {
-  // This page has two products.
+  // This page has three products.
   NavigateToURL("https://www.guitarcenter.com/cart.html");
 
   WaitForProductCount(kExpectedExampleWithProducts);
@@ -572,8 +581,9 @@
       BuildProtoWithProducts(
           kMockExample, kMockExampleURL,
           {"https://static.guitarcenter.com/product-image/foo_123-0-medium",
-           "https://images.cymax.com/Images/3/bar_456-baz_789-0-medium"},
-          {"foo_123", "bar_456"});
+           "https://images.cymax.com/Images/3/bar_456-baz_789-0-medium",
+           "https://static.guitarcenter.com/product-image/qux_357-0-medium"},
+          {"foo_123", "bar_456", "qux_357"});
   const ShoppingCarts expected_carts = {{kMockExample, expected_cart_protos}};
   WaitForProductCount(expected_carts);
 }
@@ -609,4 +619,27 @@
   WaitForCartCount(kExpectedExampleFallbackCart);
 }
 
+class CommerceHintImprovementTest : public CommerceHintAgentTest {
+ public:
+  void SetUpInProcessBrowserTestFixture() override {
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {{ntp_features::kNtpChromeCartModule,
+          {{ntp_features::kNtpChromeCartModuleHeuristicsImprovementParam,
+            "true"},
+           {"product-skip-pattern", "(^|\\W)(?i)(skipped)(\\W|$)"}}}},
+        {optimization_guide::features::kOptimizationHints});
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(CommerceHintImprovementTest, ExtractCart) {
+  // This page has three products but should ignore the one in saved for later
+  // section.
+  NavigateToURL("https://www.guitarcenter.com/cart.html");
+
+  WaitForProductCount(kExpectedExampleWithProductsWithoutSaved);
+}
+
 }  // namespace
diff --git a/chrome/renderer/chrome_content_renderer_client_browsertest.cc b/chrome/renderer/chrome_content_renderer_client_browsertest.cc
index 6b10abd..af0783e 100644
--- a/chrome/renderer/chrome_content_renderer_client_browsertest.cc
+++ b/chrome/renderer/chrome_content_renderer_client_browsertest.cc
@@ -55,11 +55,10 @@
   ChromeContentRendererClient* client =
       static_cast<ChromeContentRendererClient*>(content_renderer_client_.get());
 
-  // Create a thumbnail URL containing the correct render view ID and an
+  // Create a thumbnail URL containing the correct render frame ID and an
   // arbitrary instant restricted ID.
-  GURL thumbnail_url(base::StringPrintf(
-      "chrome-search:/thumb/%i/1",
-      render_frame->GetRenderView()->GetRoutingID()));
+  GURL thumbnail_url(base::StringPrintf("chrome-search:/thumb/%i/1",
+                                        render_frame->GetRoutingID()));
 
   GURL result;
   // Make sure the SearchBox rewrites a thumbnail request from the main frame.
diff --git a/chrome/renderer/resources/cart/cart-product-extraction.js b/chrome/renderer/resources/cart/cart-product-extraction.js
index 8bae4f78..a4edb01 100644
--- a/chrome/renderer/resources/cart/cart-product-extraction.js
+++ b/chrome/renderer/resources/cart/cart-product-extraction.js
@@ -26,6 +26,7 @@
 var productIdHTMLRegex = new RegExp('<a href="#modal-(\\w+)', 'i');
 var productIdURLRegex = new RegExp(
     '((\\w+)-\\d+-medium)|(images.cymax.com/Images/\\d+/(\\w+)-)', 'i');
+var saveForLaterRegex = new RegExp('save for later', 'i');
 
 function getLazyLoadingURL(image) {
   // FIXME: some lazy images in Nordstrom and Staples don't have URLs in the
@@ -609,7 +610,8 @@
       item.outerHTML.toLowerCase().match(cartItemHTMLRegex);
 }
 
-function extractOneItem(item, extracted_items, processed, output) {
+function extractOneItem(item, extracted_items, processed, output,
+  savedForLaterSection) {
   if (!isCartItem(item))
     return;
   if (verbose > 1)
@@ -654,6 +656,8 @@
   }
   if (processed.has(item))
     return;
+  if (isInSavedForLater(item, savedForLaterSection))
+    return;
   processed.add(item);
   if (verbose > 0)
     console.log('trying', item);
@@ -664,6 +668,47 @@
   }
 }
 
+function isInSavedForLater(item, savedForLaterSection) {
+  return savedForLaterSection !== null
+    && savedForLaterSection.getBoundingClientRect().top
+    < item.getBoundingClientRect().top
+    && !item.textContent.toLowerCase().match(saveForLaterRegex);
+}
+
+function getSavedForLaterSection() {
+  const nodes = document.evaluate(
+    "//*[contains(translate(" +
+    "text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), " +
+    "'your saved items')" +
+    "or contains(translate(" +
+    "text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), " +
+    "'saved for later')" +
+    "or contains(translate(" +
+    "text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), " +
+    "'my saved items')" +
+    "or contains(translate(" +
+    "text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), " +
+    "'wishlist items')]", document,
+  null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
+  let node = nodes.iterateNext();
+  let section = null;
+  while (node) {
+    if (node!= null && node.offsetHeight >= 1 && node.offsetWidth >= 1) {
+      section = node;
+    }
+    node = nodes.iterateNext();
+  }
+  return section
+}
+
+function isHeuristicsImprovementEnabled() {
+  if (typeof isImprovementEnabled === 'undefined'
+    || typeof isImprovementEnabled !== 'boolean') {
+    return false;
+  }
+  return isImprovementEnabled;
+}
+
 function documentPositionComparator(a, b) {
   if (a === b)
     return 0;
@@ -743,8 +788,15 @@
   const outputMap = new Map();
   const processed = new Set();
   const extracted_items = [];
+  let savedForLaterSection = null;
+  if (isHeuristicsImprovementEnabled()) {
+    savedForLaterSection = getSavedForLaterSection();
+    if (verbose > 0)
+      console.log(savedForLaterSection);
+  }
   for (const item of items) {
-    extractOneItem(item, extracted_items, processed, outputMap);
+    extractOneItem(item, extracted_items, processed, outputMap,
+      savedForLaterSection);
   }
   const keysInDocOrder =
       Array.from(outputMap.keys()).sort(documentPositionComparator);
diff --git a/chrome/renderer/searchbox/searchbox.cc b/chrome/renderer/searchbox/searchbox.cc
index bdc2683c..b2b4e9a1 100644
--- a/chrome/renderer/searchbox/searchbox.cc
+++ b/chrome/renderer/searchbox/searchbox.cc
@@ -60,7 +60,7 @@
  public:
   explicit SearchBoxIconURLHelper(const SearchBox* search_box);
   ~SearchBoxIconURLHelper() override;
-  int GetViewID() const override;
+  int GetMainFrameID() const override;
   std::string GetURLStringFromRestrictedID(InstantRestrictedID rid) const
       override;
 
@@ -75,8 +75,8 @@
 SearchBoxIconURLHelper::~SearchBoxIconURLHelper() {
 }
 
-int SearchBoxIconURLHelper::GetViewID() const {
-  return search_box_->render_frame()->GetRenderView()->GetRoutingID();
+int SearchBoxIconURLHelper::GetMainFrameID() const {
+  return search_box_->render_frame()->GetRoutingID();
 }
 
 std::string SearchBoxIconURLHelper::GetURLStringFromRestrictedID(
@@ -92,12 +92,12 @@
 
 namespace internal {  // for testing
 
-// Parses "<view_id>/<restricted_id>". If successful, assigns
-// |*view_id| := "<view_id>", |*rid| := "<restricted_id>", and returns true.
-bool ParseViewIdAndRestrictedId(const std::string& id_part,
-                                int* view_id_out,
-                                InstantRestrictedID* rid_out) {
-  DCHECK(view_id_out);
+// Parses "<frame_id>/<restricted_id>". If successful, assigns
+// |*frame_id| := "<frame_id>", |*rid| := "<restricted_id>", and returns true.
+bool ParseFrameIdAndRestrictedId(const std::string& id_part,
+                                 int* frame_id_out,
+                                 InstantRestrictedID* rid_out) {
+  DCHECK(frame_id_out);
   DCHECK(rid_out);
   // Check that the path is of Most visited item ID form.
   std::vector<base::StringPiece> tokens = base::SplitStringPiece(
@@ -105,30 +105,30 @@
   if (tokens.size() != 2)
     return false;
 
-  int view_id;
+  int frame_id;
   InstantRestrictedID rid;
-  if (!base::StringToInt(tokens[0], &view_id) || view_id < 0 ||
+  if (!base::StringToInt(tokens[0], &frame_id) || frame_id < 0 ||
       !base::StringToInt(tokens[1], &rid) || rid < 0)
     return false;
 
-  *view_id_out = view_id;
+  *frame_id_out = frame_id;
   *rid_out = rid;
   return true;
 }
 
 // Takes a favicon |url| that looks like:
 //
-//   chrome-search://favicon/<view_id>/<restricted_id>
-//   chrome-search://favicon/<parameters>/<view_id>/<restricted_id>
+//   chrome-search://favicon/<frame_id>/<restricted_id>
+//   chrome-search://favicon/<parameters>/<frame_id>/<restricted_id>
 //
 // If successful, assigns |*param_part| := "" or "<parameters>/" (note trailing
-// slash), |*view_id| := "<view_id>", |*rid| := "rid", and returns true.
+// slash), |*frame_id| := "<frame_id>", |*rid| := "rid", and returns true.
 bool ParseIconRestrictedUrl(const GURL& url,
                             std::string* param_part,
-                            int* view_id,
+                            int* frame_id,
                             InstantRestrictedID* rid) {
   DCHECK(param_part);
-  DCHECK(view_id);
+  DCHECK(frame_id);
   DCHECK(rid);
   // Strip leading slash.
   std::string raw_path = url.path();
@@ -145,7 +145,7 @@
   int path_index = parsed.path_index;
 
   std::string id_part = raw_path.substr(path_index);
-  if (!ParseViewIdAndRestrictedId(id_part, view_id, rid))
+  if (!ParseFrameIdAndRestrictedId(id_part, frame_id, rid))
     return false;
 
   *param_part = raw_path.substr(0, path_index);
@@ -156,12 +156,12 @@
                                 const SearchBox::IconURLHelper& helper,
                                 GURL* url) {
   std::string params;
-  int view_id = -1;
+  int frame_id = -1;
   InstantRestrictedID rid = -1;
 
-  if (!internal::ParseIconRestrictedUrl(transient_url, &params, &view_id,
+  if (!internal::ParseIconRestrictedUrl(transient_url, &params, &frame_id,
                                         &rid) ||
-      view_id != helper.GetViewID()) {
+      frame_id != helper.GetMainFrameID()) {
     *url = GURL(base::StringPrintf("chrome-search://%s/",
                                    chrome::kChromeUIFaviconHost));
   } else {
diff --git a/chrome/renderer/searchbox/searchbox.h b/chrome/renderer/searchbox/searchbox.h
index 27839c019..31741eb36 100644
--- a/chrome/renderer/searchbox/searchbox.h
+++ b/chrome/renderer/searchbox/searchbox.h
@@ -35,8 +35,8 @@
    public:
     IconURLHelper();
     virtual ~IconURLHelper();
-    // Retruns view id for validating icon URL.
-    virtual int GetViewID() const = 0;
+    // Returns main frame id for validating icon URL.
+    virtual int GetMainFrameID() const = 0;
     // Returns the page URL string for |rid|, or empty string for invalid |rid|.
     virtual std::string GetURLStringFromRestrictedID(InstantRestrictedID rid)
         const = 0;
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc
index cdf5bee..0c34ba3 100644
--- a/chrome/renderer/searchbox/searchbox_extension.cc
+++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -37,7 +37,6 @@
 #include "content/public/renderer/chrome_object_extensions_utils.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/render_view.h"
 #include "gin/data_object_builder.h"
 #include "gin/handle.h"
 #include "gin/object_template_builder.h"
@@ -100,13 +99,14 @@
 v8::Local<v8::Object> GenerateMostVisitedItem(
     v8::Isolate* isolate,
     float device_pixel_ratio,
-    int render_view_id,
+    int render_frame_id,
     InstantRestrictedID restricted_id) {
   return gin::DataObjectBuilder(isolate)
       .Set("rid", restricted_id)
-      .Set("faviconUrl", base::StringPrintf(
-                             "chrome-search://favicon/size/16@%fx/%d/%d",
-                             device_pixel_ratio, render_view_id, restricted_id))
+      .Set("faviconUrl",
+           base::StringPrintf("chrome-search://favicon/size/16@%fx/%d/%d",
+                              device_pixel_ratio, render_frame_id,
+                              restricted_id))
       .Build();
 }
 
@@ -811,14 +811,13 @@
     return v8::Null(isolate);
 
   content::RenderFrame* render_frame = GetMainRenderFrameForCurrentContext();
-  content::RenderView* render_view = render_frame->GetRenderView();
 
   // This corresponds to "window.devicePixelRatio" in JavaScript.
   float zoom_factor =
       blink::PageZoomLevelToZoomFactor(render_frame->GetWebView()->ZoomLevel());
   float device_pixel_ratio = render_frame->GetDeviceScaleFactor() * zoom_factor;
 
-  int render_view_id = render_view->GetRoutingID();
+  int render_frame_id = render_frame->GetRoutingID();
 
   std::vector<InstantMostVisitedItemIDPair> instant_mv_items;
   search_box->GetMostVisitedItems(&instant_mv_items);
@@ -830,8 +829,8 @@
     v8_mv_items
         ->CreateDataProperty(
             context, i,
-            GenerateMostVisitedItem(isolate, device_pixel_ratio, render_view_id,
-                                    rid))
+            GenerateMostVisitedItem(isolate, device_pixel_ratio,
+                                    render_frame_id, rid))
         .Check();
   }
   return v8_mv_items;
@@ -943,9 +942,8 @@
   if (!search_box->GetMostVisitedItemWithID(rid, &item))
     return v8::Null(isolate);
 
-  int render_view_id =
-      GetMainRenderFrameForCurrentContext()->GetRenderView()->GetRoutingID();
-  return GenerateMostVisitedItemData(isolate, render_view_id, rid, item);
+  int render_frame_id = GetMainRenderFrameForCurrentContext()->GetRoutingID();
+  return GenerateMostVisitedItemData(isolate, render_frame_id, rid, item);
 }
 
 // static
diff --git a/chrome/renderer/searchbox/searchbox_unittest.cc b/chrome/renderer/searchbox/searchbox_unittest.cc
index 1baf4ef..e9130c73 100644
--- a/chrome/renderer/searchbox/searchbox_unittest.cc
+++ b/chrome/renderer/searchbox/searchbox_unittest.cc
@@ -25,7 +25,7 @@
  public:
   MockIconURLHelper();
   ~MockIconURLHelper() override;
-  int GetViewID() const override;
+  int GetMainFrameID() const override;
   std::string GetURLStringFromRestrictedID(InstantRestrictedID rid) const
       override;
 
@@ -42,7 +42,7 @@
 MockIconURLHelper::~MockIconURLHelper() {
 }
 
-int MockIconURLHelper::GetViewID() const {
+int MockIconURLHelper::GetMainFrameID() const {
   return 137;
 }
 
@@ -57,14 +57,14 @@
 namespace internal {
 
 // Defined in searchbox.cc
-bool ParseViewIdAndRestrictedId(const std::string& id_part,
-                                int* view_id_out,
-                                InstantRestrictedID* rid_out);
+bool ParseFrameIdAndRestrictedId(const std::string& id_part,
+                                 int* frame_id_out,
+                                 InstantRestrictedID* rid_out);
 
 // Defined in searchbox.cc
 bool ParseIconRestrictedUrl(const GURL& url,
                             std::string* param_part,
-                            int* view_id,
+                            int* frame_id,
                             InstantRestrictedID* rid);
 
 // Defined in searchbox.cc
@@ -75,42 +75,42 @@
 // Defined in searchbox.cc
 std::string FixupAndValidateUrl(const std::string& url);
 
-TEST(SearchBoxUtilTest, ParseViewIdAndRestrictedIdSuccess) {
-  int view_id = -1;
+TEST(SearchBoxUtilTest, ParseFrameIdAndRestrictedIdSuccess) {
+  int frame_id = -1;
   InstantRestrictedID rid = -1;
 
-  EXPECT_TRUE(ParseViewIdAndRestrictedId("2/3", &view_id, &rid));
-  EXPECT_EQ(2, view_id);
+  EXPECT_TRUE(ParseFrameIdAndRestrictedId("2/3", &frame_id, &rid));
+  EXPECT_EQ(2, frame_id);
   EXPECT_EQ(3, rid);
 
-  EXPECT_TRUE(ParseViewIdAndRestrictedId("0/0", &view_id, &rid));
-  EXPECT_EQ(0, view_id);
+  EXPECT_TRUE(ParseFrameIdAndRestrictedId("0/0", &frame_id, &rid));
+  EXPECT_EQ(0, frame_id);
   EXPECT_EQ(0, rid);
 
-  EXPECT_TRUE(ParseViewIdAndRestrictedId("1048576/314", &view_id, &rid));
-  EXPECT_EQ(1048576, view_id);
+  EXPECT_TRUE(ParseFrameIdAndRestrictedId("1048576/314", &frame_id, &rid));
+  EXPECT_EQ(1048576, frame_id);
   EXPECT_EQ(314, rid);
 
   // Odd but not fatal.
-  EXPECT_TRUE(ParseViewIdAndRestrictedId("00/09", &view_id, &rid));
-  EXPECT_EQ(0, view_id);
+  EXPECT_TRUE(ParseFrameIdAndRestrictedId("00/09", &frame_id, &rid));
+  EXPECT_EQ(0, frame_id);
   EXPECT_EQ(9, rid);
 
   // Tolerates multiple, leading, and trailing "/".
-  EXPECT_TRUE(ParseViewIdAndRestrictedId("2////3", &view_id, &rid));
-  EXPECT_EQ(2, view_id);
+  EXPECT_TRUE(ParseFrameIdAndRestrictedId("2////3", &frame_id, &rid));
+  EXPECT_EQ(2, frame_id);
   EXPECT_EQ(3, rid);
 
-  EXPECT_TRUE(ParseViewIdAndRestrictedId("5/6/", &view_id, &rid));
-  EXPECT_EQ(5, view_id);
+  EXPECT_TRUE(ParseFrameIdAndRestrictedId("5/6/", &frame_id, &rid));
+  EXPECT_EQ(5, frame_id);
   EXPECT_EQ(6, rid);
 
-  EXPECT_TRUE(ParseViewIdAndRestrictedId("/7/8", &view_id, &rid));
-  EXPECT_EQ(7, view_id);
+  EXPECT_TRUE(ParseFrameIdAndRestrictedId("/7/8", &frame_id, &rid));
+  EXPECT_EQ(7, frame_id);
   EXPECT_EQ(8, rid);
 }
 
-TEST(SearchBoxUtilTest, ParseViewIdAndRestrictedIdFailure) {
+TEST(SearchBoxUtilTest, ParseFrameIdAndRestrictedIdFailure) {
   const char* test_cases[] = {
     "",
     "    ",
@@ -131,11 +131,11 @@
     "0xA/0x10",
   };
   for (size_t i = 0; i < base::size(test_cases); ++i) {
-    int view_id = -1;
+    int frame_id = -1;
     InstantRestrictedID rid = -1;
-    EXPECT_FALSE(ParseViewIdAndRestrictedId(test_cases[i], &view_id, &rid))
-      << " for test_cases[" << i << "]";
-    EXPECT_EQ(-1, view_id);
+    EXPECT_FALSE(ParseFrameIdAndRestrictedId(test_cases[i], &frame_id, &rid))
+        << " for test_cases[" << i << "]";
+    EXPECT_EQ(-1, frame_id);
     EXPECT_EQ(-1, rid);
   }
 }
@@ -144,7 +144,7 @@
   struct {
     const char* transient_url_str;
     const char* expected_param_part;
-    int expected_view_id;
+    int expected_frame_id;
     InstantRestrictedID expected_rid;
   } test_cases[] = {
       {"chrome-search://favicon/1/2", "", 1, 2},
@@ -153,14 +153,14 @@
   };
   for (size_t i = 0; i < base::size(test_cases); ++i) {
     std::string param_part = "(unwritten)";
-    int view_id = -1;
+    int frame_id = -1;
     InstantRestrictedID rid = -1;
     EXPECT_TRUE(ParseIconRestrictedUrl(GURL(test_cases[i].transient_url_str),
-                                       &param_part, &view_id, &rid))
+                                       &param_part, &frame_id, &rid))
         << " for test_cases[" << i << "]";
     EXPECT_EQ(test_cases[i].expected_param_part, param_part)
         << " for test_cases[" << i << "]";
-    EXPECT_EQ(test_cases[i].expected_view_id, view_id)
+    EXPECT_EQ(test_cases[i].expected_frame_id, frame_id)
         << " for test_cases[" << i << "]";
     EXPECT_EQ(test_cases[i].expected_rid, rid)
         << " for test_cases[" << i << "]";
@@ -179,13 +179,13 @@
   };
   for (size_t i = 0; i < base::size(test_cases); ++i) {
     std::string param_part = "(unwritten)";
-    int view_id = -1;
+    int frame_id = -1;
     InstantRestrictedID rid = -1;
     EXPECT_FALSE(ParseIconRestrictedUrl(GURL(test_cases[i].transient_url_str),
-                                        &param_part, &view_id, &rid))
+                                        &param_part, &frame_id, &rid))
         << " for test_cases[" << i << "]";
     EXPECT_EQ("(unwritten)", param_part);
-    EXPECT_EQ(-1, view_id);
+    EXPECT_EQ(-1, frame_id);
     EXPECT_EQ(-1, rid);
   }
 }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 40a3838..081cb42 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4371,10 +4371,10 @@
     "../browser/storage/durable_storage_permission_context_unittest.cc",
     "../browser/storage_access_api/storage_access_grant_permission_context_unittest.cc",
     "../browser/subresource_filter/subresource_filter_history_observer_unittest.cc",
-    "../browser/sync/profile_sync_service_factory_unittest.cc",
     "../browser/sync/session_sync_service_factory_unittest.cc",
     "../browser/sync/sessions/sync_sessions_web_contents_router_unittest.cc",
     "../browser/sync/sync_encryption_keys_tab_helper_unittest.cc",
+    "../browser/sync/sync_service_factory_unittest.cc",
     "../browser/sync/sync_startup_tracker_unittest.cc",
     "../browser/tracing/background_tracing_field_trial_unittest.cc",
     "../browser/tracing/background_tracing_metrics_provider_unittest.cc",
@@ -6067,6 +6067,7 @@
       "../common/extensions/api/common_extension_api_unittest.cc",
       "../common/extensions/api/extension_action/browser_action_manifest_unittest.cc",
       "../common/extensions/api/extension_action/page_action_manifest_unittest.cc",
+      "../common/extensions/api/speech/tts_engine_manifest_handler_unittest.cc",
       "../common/extensions/api/storage/storage_schema_manifest_handler_unittest.cc",
       "../common/extensions/api/system_indicator/system_indicator_handler_unittest.cc",
       "../common/extensions/chrome_extensions_client_unittest.cc",
diff --git a/chrome/test/data/cart/cart.html b/chrome/test/data/cart/cart.html
index f6f6913..2389f7c6 100644
--- a/chrome/test/data/cart/cart.html
+++ b/chrome/test/data/cart/cart.html
@@ -25,4 +25,10 @@
         <img src="https://static.walmart.com/product-image/12-0-medium" height=300 width=300></a>
     <span>$1.2</span><a>remove</a><a>Move to cart</a>
 </div>
+<div><span>Saved for later</span></div>
+<div>
+    <a href="/products/357/">Product two
+        <img src="https://static.guitarcenter.com/product-image/qux_357-0-medium" height=300 width=300></a>
+    <span>$56.78</span><a>remove</a>
+</div>
 </body>
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_1.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_1.json
new file mode 100644
index 0000000..5fca6a6
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_1.json
@@ -0,0 +1,10 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": 4000,
+    "buffer_size": "asdf"
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_2.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_2.json
new file mode 100644
index 0000000..831a8df
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_2.json
@@ -0,0 +1,10 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": 20000,
+    "buffer_size": -1
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_3.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_3.json
new file mode 100644
index 0000000..c34619d
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_3.json
@@ -0,0 +1,10 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": 10000,
+    "buffer_size": 1000000
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_4.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_4.json
new file mode 100644
index 0000000..db0b5da9
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_buffer_size_4.json
@@ -0,0 +1,9 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": 10000
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_1.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_1.json
new file mode 100644
index 0000000..8983f264
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_1.json
@@ -0,0 +1,10 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": "1",
+    "buffer_size": 128
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_2.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_2.json
new file mode 100644
index 0000000..f365293
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_2.json
@@ -0,0 +1,10 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": 100,
+    "buffer_size": 128
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_3.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_3.json
new file mode 100644
index 0000000..69fae60
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_3.json
@@ -0,0 +1,10 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": 1000000,
+    "buffer_size": 128
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_4.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_4.json
new file mode 100644
index 0000000..0de34c7a
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_sample_rate_4.json
@@ -0,0 +1,9 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": 100000
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_1.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_1.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_invalid_1.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_1.json
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_2.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_2.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_invalid_2.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_2.json
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_3.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_3.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_invalid_3.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_3.json
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_4.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_4.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_invalid_4.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_4.json
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_5.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_5.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_invalid_5.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_5.json
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_6.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_6.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_invalid_6.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_6.json
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_9.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_7.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_invalid_9.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_7.json
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_8.json b/chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_8.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_invalid_8.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_invalid_voices_8.json
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_valid_sample_rate_buffer_size.json b/chrome/test/data/extensions/manifest_tests/tts_engine_valid_sample_rate_buffer_size.json
new file mode 100644
index 0000000..ba235123
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/tts_engine_valid_sample_rate_buffer_size.json
@@ -0,0 +1,10 @@
+{
+  "name": "test",
+  "manifest_version": 2,
+  "version": "1",
+  "tts_engine": {
+    "voices": [],
+    "sample_rate": 10000,
+    "buffer_size": 100
+  }
+}
diff --git a/chrome/test/data/extensions/manifest_tests/tts_engine_valid.json b/chrome/test/data/extensions/manifest_tests/tts_engine_valid_voices.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/tts_engine_valid.json
rename to chrome/test/data/extensions/manifest_tests/tts_engine_valid_voices.json
diff --git a/chrome/test/data/webui/chromeos/diagnostics/fake_network_health_provider_test.js b/chrome/test/data/webui/chromeos/diagnostics/fake_network_health_provider_test.js
index 0542fca..be6fa31 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/fake_network_health_provider_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/fake_network_health_provider_test.js
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {NetworkListObserver, NetworkStateObserver} from 'chrome://diagnostics/diagnostics_types.js';
+import {NetworkListObserverRemote, NetworkStateObserverRemote} from 'chrome://diagnostics/diagnostics_types.js';
 import {fakeCellularNetwork, fakeEthernetNetwork, fakeNetworkGuidInfoList, fakeWifiNetwork} from 'chrome://diagnostics/fake_data.js';
 import {FakeNetworkHealthProvider} from 'chrome://diagnostics/fake_network_health_provider.js';
 import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
 
-import {assertDeepEquals, assertTrue} from '../../chai_assert.js';
+import {assertDeepEquals, assertEquals, assertTrue} from '../../chai_assert.js';
 
 export function fakeNetworkHealthProviderTestSuite() {
   /** @type {?FakeNetworkHealthProvider} */
@@ -31,24 +31,29 @@
     let firstResolver = new PromiseResolver();
     let completeResolver = new PromiseResolver();
 
-    /** @type {!NetworkListObserver} */
-    const networkListObserverRemote = /** @type {!NetworkListObserver} */ ({
-      onNetworkListChanged: (networkGuids) => {
-        // Only expect 2 calls.
-        assertTrue(whichSample >= 0);
-        assertTrue(whichSample <= 1);
-        assertDeepEquals(fakeNetworkGuidInfoList[whichSample], networkGuids);
+    const networkListObserverRemote =
+        /** @type {!NetworkListObserverRemote} */ ({
+          onNetworkListChanged: (networkGuids, activeGuid) => {
+            // Only expect 2 calls.
+            assertTrue(whichSample >= 0);
+            assertTrue(whichSample <= 1);
+            assertDeepEquals(
+                fakeNetworkGuidInfoList[whichSample].networkGuids,
+                networkGuids);
+            assertEquals(
+                fakeNetworkGuidInfoList[whichSample].activeGuid, activeGuid);
 
-        if (whichSample === 0) {
-          firstResolver.resolve();
-        } else {
-          completeResolver.resolve();
-        }
-        whichSample++;
-      }
-    });
+            if (whichSample === 0) {
+              firstResolver.resolve();
+            } else {
+              completeResolver.resolve();
+            }
+            whichSample++;
+          }
+        });
 
-    return provider.observeNetworkList(networkListObserverRemote)
+    provider.observeNetworkList(networkListObserverRemote);
+    return provider.getObserveNetworkListPromiseForTesting()
         .then(() => firstResolver.promise)
         .then(() => {
           // After the observer fires the first time, trigger it to
@@ -63,17 +68,17 @@
     provider.setFakeNetworkState('cellularGuid', [fakeCellularNetwork]);
     let resolver = new PromiseResolver();
 
-    /** @type {!NetworkStateObserver} */
     const networkStateObserverRemote =
-        /** @type {!NetworkStateObserver} */ ({
+        /** @type {!NetworkStateObserverRemote} */ ({
           onNetworkStateChanged: (network) => {
             assertDeepEquals(fakeCellularNetwork, network);
             resolver.resolve();
           }
         });
 
-    return provider.observeNetwork(networkStateObserverRemote, 'cellularGuid')
-        .then(() => resolver.promise);
+    provider.observeNetwork(networkStateObserverRemote, 'cellularGuid');
+    return provider.getObserveNetworkStatePromiseForTesting().then(
+        () => resolver.promise);
   });
 
   test('ObserveNetworkSupportsMultipleObservers', () => {
@@ -83,25 +88,24 @@
     let wifiResolver = new PromiseResolver();
     let ethernetResolver = new PromiseResolver();
 
-    /** @type {!NetworkStateObserver} */
     const wifiNetworkStateObserverRemote =
-        /** @type {!NetworkStateObserver} */ ({
+        /** @type {!NetworkStateObserverRemote} */ ({
           onNetworkStateChanged: (network) => {
             assertDeepEquals(fakeWifiNetwork, network);
             wifiResolver.resolve();
           }
         });
 
-    /** @type {!NetworkStateObserver} */
     const ethernetNetworkStateObserverRemote =
-        /** @type {!NetworkStateObserver} */ ({
+        /** @type {!NetworkStateObserverRemote} */ ({
           onNetworkStateChanged: (network) => {
             assertDeepEquals(fakeEthernetNetwork, network);
             ethernetResolver.resolve();
           }
         });
 
-    return provider.observeNetwork(wifiNetworkStateObserverRemote, 'wifiGuid')
+    provider.observeNetwork(wifiNetworkStateObserverRemote, 'wifiGuid');
+    return provider.getObserveNetworkStatePromiseForTesting()
         .then(() => wifiResolver.promise)
         .then(
             () => provider.observeNetwork(
diff --git a/chrome/test/data/webui/chromeos/diagnostics/network_list_test.js b/chrome/test/data/webui/chromeos/diagnostics/network_list_test.js
index 4105025..6996aa1 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/network_list_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/network_list_test.js
@@ -156,8 +156,10 @@
   test('NetworkCardElementsPopulated', () => {
     let networkCardElements;
     return initializeNetworkList(fakeNetworkGuidInfoList)
-        .then(async () => {
+        .then(() => flushTasks())
+        .then(() => {
           networkCardElements = getNetworkCardElements();
+
           // The first network list observation provides guids for Cellular
           // and WiFi. The connectivity-card is responsbile for the Ethernet
           // guid as it's the currently active guid.
@@ -176,7 +178,9 @@
 
           return triggerNetworkListObserver();
         })
+        .then(() => flushTasks())
         .then(() => {
+          networkCardElements = getNetworkCardElements();
           const cellularInfoElement = dx_utils.getCellularInfoElement(
               networkCardElements[0].$$('network-info'));
           dx_utils.assertTextContains(
diff --git a/chrome/test/data/webui/chromeos/diagnostics/wifi_info_test.js b/chrome/test/data/webui/chromeos/diagnostics/wifi_info_test.js
index 185f600a..06fc0d8 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/wifi_info_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/wifi_info_test.js
@@ -43,35 +43,34 @@
           `${fakeWifiNetwork.state}`);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#signalStrength'),
-          fakeWifiNetwork.networkProperties.signalStrength);
+          `${fakeWifiNetwork.typeProperties.wifi.signalStrength}`);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#frequency'),
-          fakeWifiNetwork.networkProperties.frequency);
+          `${fakeWifiNetwork.typeProperties.wifi.frequency}`);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#bssid'),
-          fakeWifiNetwork.networkProperties.bssid);
+          fakeWifiNetwork.typeProperties.wifi.bssid);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#ssid'),
-          fakeWifiNetwork.networkProperties.ssid);
+          fakeWifiNetwork.typeProperties.wifi.ssid);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#guid'),
           fakeWifiNetwork.guid);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#macAddress'),
-          fakeWifiNetwork.macAddress);
+          `${fakeWifiNetwork.macAddress}`);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#ipAddress'),
-          /** @type {string} */ (fakeWifiNetwork.ipConfigProperties.ipAddress));
+          `${fakeWifiNetwork.ipConfig.ipAddress}`);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#gateway'),
-          /** @type {string} */ (fakeWifiNetwork.ipConfigProperties.gateway));
+          `${fakeWifiNetwork.ipConfig.gateway}`);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#nameServers'),
-          fakeWifiNetwork.ipConfigProperties.nameServers[0]);
+          fakeWifiNetwork.ipConfig.nameServers[0]);
       dx_utils.assertTextContains(
           dx_utils.getDataPointValue(wifiInfoElement, '#subnetMask'),
-          /** @type {string} */
-          (fakeWifiNetwork.ipConfigProperties.subnetMask));
+          `${fakeWifiNetwork.ipConfig.routingPrefix}`);
     });
   });
 }
\ No newline at end of file
diff --git a/chrome/test/data/webui/welcome/navigation_behavior_test.js b/chrome/test/data/webui/welcome/navigation_mixin_test.js
similarity index 98%
rename from chrome/test/data/webui/welcome/navigation_behavior_test.js
rename to chrome/test/data/webui/welcome/navigation_mixin_test.js
index 8009c7dd..f4e4ed024 100644
--- a/chrome/test/data/webui/welcome/navigation_behavior_test.js
+++ b/chrome/test/data/webui/welcome/navigation_mixin_test.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {navigateTo, navigateToNextStep, NavigationMixin, Routes} from 'chrome://welcome/navigation_behavior.js';
+import {navigateTo, navigateToNextStep, NavigationMixin, Routes} from 'chrome://welcome/navigation_mixin.js';
 
 import {eventToPromise} from '../test_util.m.js';
 
diff --git a/chrome/test/data/webui/welcome/welcome_app_test.js b/chrome/test/data/webui/welcome/welcome_app_test.js
index dbbb2b81..6bcc29c 100644
--- a/chrome/test/data/webui/welcome/welcome_app_test.js
+++ b/chrome/test/data/webui/welcome/welcome_app_test.js
@@ -5,7 +5,7 @@
 import 'chrome://welcome/welcome_app.js';
 
 import {LandingViewProxyImpl} from 'chrome://welcome/landing_view_proxy.js';
-import {navigateTo, Routes} from 'chrome://welcome/navigation_behavior.js';
+import {navigateTo, Routes} from 'chrome://welcome/navigation_mixin.js';
 import {NuxSetAsDefaultProxyImpl} from 'chrome://welcome/set_as_default/nux_set_as_default_proxy.js';
 import {BookmarkProxyImpl} from 'chrome://welcome/shared/bookmark_proxy.js';
 import {WelcomeBrowserProxyImpl} from 'chrome://welcome/welcome_browser_proxy.js';
diff --git a/chrome/test/data/webui/welcome/welcome_browsertest.js b/chrome/test/data/webui/welcome/welcome_browsertest.js
index 9cb2303..543c6e6b 100644
--- a/chrome/test/data/webui/welcome/welcome_browsertest.js
+++ b/chrome/test/data/webui/welcome/welcome_browsertest.js
@@ -68,7 +68,7 @@
 var WelcomeNavigationBehaviorTest = class extends WelcomeBrowserTest {
   /** @override */
   get browsePreload() {
-    return 'chrome://welcome/test_loader.html?module=welcome/navigation_behavior_test.js';
+    return 'chrome://welcome/test_loader.html?module=welcome/navigation_mixin_test.js';
   }
 };
 
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn
index d6b3ee1..0c50854 100644
--- a/chrome/updater/BUILD.gn
+++ b/chrome/updater/BUILD.gn
@@ -110,6 +110,7 @@
       "update_service_internal_impl_inactive.h",
       "updater.cc",
       "updater.h",
+      "updater_scope.cc",
       "updater_scope.h",
       "util.cc",
       "util.h",
diff --git a/chrome/updater/app/app.cc b/chrome/updater/app/app.cc
index 86c85247..2c5daa459 100644
--- a/chrome/updater/app/app.cc
+++ b/chrome/updater/app/app.cc
@@ -14,6 +14,7 @@
 #include "base/run_loop.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
 #include "base/threading/thread_restrictions.h"
+#include "chrome/updater/constants.h"
 #include "chrome/updater/tag.h"
 #include "chrome/updater/updater_scope.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -22,23 +23,7 @@
 
 constexpr base::StringPiece App::kThreadPoolName;
 
-App::App()
-    : process_scope_(GetProcessScope()),
-      tag_args_([]() -> absl::optional<tagging::TagArgs> {
-        base::CommandLine* command_line =
-            base::CommandLine::ForCurrentProcess();
-        const std::string tag = command_line->GetSwitchValueASCII(kTagSwitch);
-        if (tag.empty())
-          return absl::nullopt;
-        tagging::TagArgs tag_args;
-        const tagging::ErrorCode error =
-            tagging::Parse(tag, absl::nullopt, &tag_args);
-        VLOG_IF(1, error != tagging::ErrorCode::kSuccess)
-            << "Tag parsing returned " << error << ".";
-        return error == tagging::ErrorCode::kSuccess
-                   ? absl::make_optional(tag_args)
-                   : absl::nullopt;
-      }()) {}
+App::App() : updater_scope_(GetUpdaterScope()) {}
 
 App::~App() = default;
 
@@ -74,25 +59,7 @@
 }
 
 UpdaterScope App::updater_scope() const {
-  // TODO(crbug.com/1208946): handle conflicts between NeedAdmin and --system.
-  if (tag_args_ && !tag_args_->apps.empty() &&
-      tag_args_->apps.front().needs_admin) {
-    // TODO(crbug.com/1128631): support bundles. For now, assume one app.
-    DCHECK_EQ(tag_args_->apps.size(), size_t{1});
-    switch (*tag_args_->apps.front().needs_admin) {
-      case tagging::AppArgs::NeedsAdmin::kYes:
-      case tagging::AppArgs::NeedsAdmin::kPrefers:
-        return UpdaterScope::kSystem;
-      case tagging::AppArgs::NeedsAdmin::kNo:
-        return UpdaterScope::kUser;
-    }
-  }
-
-  return process_scope_;
-}
-
-absl::optional<tagging::TagArgs> App::tag_args() const {
-  return tag_args_;
+  return updater_scope_;
 }
 
 }  // namespace updater
diff --git a/chrome/updater/app/app.h b/chrome/updater/app/app.h
index 0192889..800da19 100644
--- a/chrome/updater/app/app.h
+++ b/chrome/updater/app/app.h
@@ -11,7 +11,6 @@
 #include "base/strings/string_piece.h"
 #include "chrome/updater/tag.h"
 #include "chrome/updater/updater_scope.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace updater {
 
@@ -54,12 +53,8 @@
   // will exit with the specified code.
   void Shutdown(int exit_code);
 
-  // The scope in which the updater is running. This is determined from
-  // the command line arguments, including the tag arguments.
   UpdaterScope updater_scope() const;
 
-  absl::optional<tagging::TagArgs> tag_args() const;
-
  private:
   // Allows initialization of the thread pool for specific environments, in
   // cases where the thread pool must be started with different init parameters,
@@ -78,11 +73,8 @@
   // A callback that quits the main sequence runloop.
   base::OnceCallback<void(int)> quit_;
 
-  // Indicates the presence of --system on the command line.
-  const UpdaterScope process_scope_;
-
-  // Contains the tag if a tag is present on the command line.
-  const absl::optional<tagging::TagArgs> tag_args_;
+  // Indicates the scope of the updater: per-system or per-user.
+  const UpdaterScope updater_scope_;
 };
 
 }  // namespace updater
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc
index 8d130af..74902848 100644
--- a/chrome/updater/app/app_install.cc
+++ b/chrome/updater/app/app_install.cc
@@ -27,6 +27,7 @@
 #include "chrome/updater/update_service.h"
 #include "chrome/updater/update_service_internal.h"
 #include "chrome/updater/updater_version.h"
+#include "chrome/updater/util.h"
 #include "components/prefs/pref_service.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -144,8 +145,8 @@
 }
 
 void AppInstall::MaybeInstallApp() {
-  const std::string app_id = [this]() {
-    absl::optional<tagging::TagArgs> tag_args = this->tag_args();
+  const std::string app_id = []() {
+    absl::optional<tagging::TagArgs> tag_args = GetTagArgs();
     if (tag_args && !tag_args->apps.empty()) {
       // TODO(crbug.com/1128631): support bundles. For now, assume one app.
       DCHECK_EQ(tag_args->apps.size(), size_t{1});
diff --git a/chrome/updater/app/app_server_unittest.cc b/chrome/updater/app/app_server_unittest.cc
index 54f06d98..69ffe6c 100644
--- a/chrome/updater/app/app_server_unittest.cc
+++ b/chrome/updater/app/app_server_unittest.cc
@@ -16,6 +16,7 @@
 #include "chrome/updater/prefs.h"
 #include "chrome/updater/update_service.h"
 #include "chrome/updater/update_service_internal.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/updater_version.h"
 #include "chrome/updater/util.h"
 #include "components/prefs/pref_service.h"
@@ -57,8 +58,10 @@
 };
 
 void ClearPrefs() {
+  const UpdaterScope updater_scope = GetUpdaterScope();
   for (const absl::optional<base::FilePath>& path :
-       {GetBaseDirectory(), GetVersionedDirectory()}) {
+       {GetBaseDirectory(updater_scope),
+        GetVersionedDirectory(updater_scope)}) {
     ASSERT_TRUE(path);
     ASSERT_TRUE(
         base::DeleteFile(path->Append(FILE_PATH_LITERAL("prefs.json"))));
diff --git a/chrome/updater/app/server/win/server.cc b/chrome/updater/app/server/win/server.cc
index 89c9095..8ba3329 100644
--- a/chrome/updater/app/server/win/server.cc
+++ b/chrome/updater/app/server/win/server.cc
@@ -217,7 +217,8 @@
 bool ComServerApp::SwapRPCInterfaces() {
   std::unique_ptr<WorkItemList> list(WorkItem::CreateWorkItemList());
 
-  absl::optional<base::FilePath> versioned_directory = GetVersionedDirectory();
+  const absl::optional<base::FilePath> versioned_directory =
+      GetVersionedDirectory(updater_scope());
   if (!versioned_directory)
     return false;
   for (const CLSID& clsid : GetActiveServers()) {
diff --git a/chrome/updater/configurator.cc b/chrome/updater/configurator.cc
index af2d9b8..404164c 100644
--- a/chrome/updater/configurator.cc
+++ b/chrome/updater/configurator.cc
@@ -48,7 +48,7 @@
     : prefs_(std::move(prefs)),
       external_constants_(CreateExternalConstants()),
       activity_data_service_(
-          std::make_unique<ActivityDataService>(GetProcessScope())),
+          std::make_unique<ActivityDataService>(GetUpdaterScope())),
       unzip_factory_(
           base::MakeRefCounted<update_client::InProcessUnzipperFactory>()),
       patch_factory_(
diff --git a/chrome/updater/crash_client.cc b/chrome/updater/crash_client.cc
index 0d9f374..0092601 100644
--- a/chrome/updater/crash_client.cc
+++ b/chrome/updater/crash_client.cc
@@ -13,6 +13,7 @@
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
@@ -49,13 +50,14 @@
   return crash_client.get();
 }
 
-bool CrashClient::InitializeDatabaseOnly() {
+bool CrashClient::InitializeDatabaseOnly(UpdaterScope updater_scope) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   base::FilePath handler_path;
   base::PathService::Get(base::FILE_EXE, &handler_path);
 
-  absl::optional<base::FilePath> database_path = GetVersionedDirectory();
+  const absl::optional<base::FilePath> database_path =
+      GetVersionedDirectory(updater_scope);
   if (!database_path) {
     LOG(ERROR) << "Failed to get the database path.";
     return false;
@@ -70,10 +72,10 @@
   return true;
 }
 
-bool CrashClient::InitializeCrashReporting() {
+bool CrashClient::InitializeCrashReporting(UpdaterScope updater_scope) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  if (!InitializeDatabaseOnly())
+  if (!InitializeDatabaseOnly(updater_scope))
     return false;
 
 #if defined(OS_WIN)
diff --git a/chrome/updater/crash_client.h b/chrome/updater/crash_client.h
index b5ca8e1d..f96ee05 100644
--- a/chrome/updater/crash_client.h
+++ b/chrome/updater/crash_client.h
@@ -21,6 +21,8 @@
 
 namespace updater {
 
+enum class UpdaterScope;
+
 // This class manages interaction with the crash reporter.
 class CrashClient {
  public:
@@ -37,11 +39,11 @@
   static bool IsUploadEnabled();
 
   // Initializes collection and upload of crash reports.
-  bool InitializeCrashReporting();
+  bool InitializeCrashReporting(UpdaterScope updater_scope);
 
   // Initializes the crash database only. Used in the crash reporter, which
   // cannot connect to itself to upload its own crashes.
-  bool InitializeDatabaseOnly();
+  bool InitializeDatabaseOnly(UpdaterScope updater_scope);
 
   crashpad::CrashReportDatabase* database() { return database_.get(); }
 
diff --git a/chrome/updater/crash_reporter.cc b/chrome/updater/crash_reporter.cc
index 9c06367..5c5f0ee 100644
--- a/chrome/updater/crash_reporter.cc
+++ b/chrome/updater/crash_reporter.cc
@@ -19,6 +19,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/updater_branding.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/crashpad/crashpad/client/crashpad_client.h"
@@ -61,7 +62,8 @@
   base::FilePath handler_path;
   base::PathService::Get(base::FILE_EXE, &handler_path);
 
-  absl::optional<base::FilePath> database_path = GetVersionedDirectory();
+  const absl::optional<base::FilePath> database_path =
+      GetVersionedDirectory(GetUpdaterScope());
   if (!database_path) {
     LOG(DFATAL) << "Failed to get the database path.";
     return;
diff --git a/chrome/updater/device_management/dm_storage.cc b/chrome/updater/device_management/dm_storage.cc
index 9023c71..15ebfc3 100644
--- a/chrome/updater/device_management/dm_storage.cc
+++ b/chrome/updater/device_management/dm_storage.cc
@@ -17,6 +17,7 @@
 #include "chrome/updater/device_management/dm_cached_policy_info.h"
 #include "chrome/updater/device_management/dm_message.h"
 #include "chrome/updater/protos/omaha_settings.pb.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -193,8 +194,8 @@
 }
 
 scoped_refptr<DMStorage> GetDefaultDMStorage() {
-  absl::optional<base::FilePath> updater_versioned_path =
-      GetVersionedDirectory();
+  const absl::optional<base::FilePath> updater_versioned_path =
+      GetVersionedDirectory(GetUpdaterScope());
   if (!updater_versioned_path)
     return nullptr;
 
diff --git a/chrome/updater/external_constants_builder.cc b/chrome/updater/external_constants_builder.cc
index e77c4e6..95d8eeb 100644
--- a/chrome/updater/external_constants_builder.cc
+++ b/chrome/updater/external_constants_builder.cc
@@ -10,6 +10,7 @@
 #include "base/json/json_file_value_serializer.h"
 #include "base/logging.h"
 #include "chrome/updater/constants.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -72,7 +73,8 @@
 }
 
 bool ExternalConstantsBuilder::Overwrite() {
-  absl::optional<base::FilePath> base_path = GetBaseDirectory();
+  const absl::optional<base::FilePath> base_path =
+      GetBaseDirectory(GetUpdaterScope());
   if (!base_path) {
     LOG(ERROR) << "Can't find base directory; can't save constant overrides.";
     return false;
diff --git a/chrome/updater/external_constants_builder_unittest.cc b/chrome/updater/external_constants_builder_unittest.cc
index c0b38de..575903a 100644
--- a/chrome/updater/external_constants_builder_unittest.cc
+++ b/chrome/updater/external_constants_builder_unittest.cc
@@ -16,16 +16,17 @@
 #include "chrome/updater/external_constants_builder.h"
 #include "chrome/updater/external_constants_override.h"
 #include "chrome/updater/updater_branding.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace updater {
-
 namespace {
 
 void DeleteOverridesFile() {
-  absl::optional<base::FilePath> target = GetBaseDirectory();
+  const absl::optional<base::FilePath> target =
+      GetBaseDirectory(GetUpdaterScope());
   if (!target) {
     LOG(ERROR) << "Could not get base directory to clean out overrides file.";
     return;
diff --git a/chrome/updater/external_constants_override.cc b/chrome/updater/external_constants_override.cc
index 778e9dc..9f51825 100644
--- a/chrome/updater/external_constants_override.cc
+++ b/chrome/updater/external_constants_override.cc
@@ -19,6 +19,7 @@
 #include "chrome/updater/external_constants.h"
 #include "chrome/updater/external_constants_override.h"
 #include "chrome/updater/updater_branding.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/updater_version.h"
 #include "chrome/updater/util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -117,7 +118,8 @@
 std::unique_ptr<ExternalConstantsOverrider>
 ExternalConstantsOverrider::FromDefaultJSONFile(
     std::unique_ptr<ExternalConstants> next_provider) {
-  absl::optional<base::FilePath> data_dir_path = GetBaseDirectory();
+  const absl::optional<base::FilePath> data_dir_path =
+      GetBaseDirectory(GetUpdaterScope());
   if (!data_dir_path) {
     LOG(ERROR) << "Cannot find app data path.";
     return nullptr;
diff --git a/chrome/updater/installer.cc b/chrome/updater/installer.cc
index 9a6f7c5..a2fcd1fe 100644
--- a/chrome/updater/installer.cc
+++ b/chrome/updater/installer.cc
@@ -19,6 +19,7 @@
 #include "chrome/updater/action_handler.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/policy/service.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 #include "components/crx_file/crx_verifier.h"
 #include "components/update_client/update_client_errors.h"
@@ -26,7 +27,6 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace updater {
-
 namespace {
 
 // This task joins a process, hence .WithBaseSyncPrimitives().
@@ -37,8 +37,9 @@
 
 // Returns the full path to the installation directory for the application
 // identified by the |app_id|.
-absl::optional<base::FilePath> GetAppInstallDir(const std::string& app_id) {
-  absl::optional<base::FilePath> app_install_dir = GetBaseDirectory();
+absl::optional<base::FilePath> GetAppInstallDir(UpdaterScope scope,
+                                                const std::string& app_id) {
+  absl::optional<base::FilePath> app_install_dir = GetBaseDirectory(scope);
   if (!app_install_dir)
     return absl::nullopt;
 
@@ -49,7 +50,9 @@
 
 Installer::Installer(const std::string& app_id,
                      scoped_refptr<PersistedData> persisted_data)
-    : app_id_(app_id), persisted_data_(persisted_data) {}
+    : updater_scope_(GetUpdaterScope()),
+      app_id_(app_id),
+      persisted_data_(persisted_data) {}
 
 Installer::~Installer() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -98,7 +101,7 @@
                                                 base::BlockingType::WILL_BLOCK);
 
   const absl::optional<base::FilePath> app_install_dir =
-      GetAppInstallDir(app_id_);
+      GetAppInstallDir(updater_scope_, app_id_);
   if (!app_install_dir || !base::PathExists(*app_install_dir)) {
     return;
   }
@@ -143,7 +146,7 @@
     return Result(update_client::InstallError::VERSION_NOT_UPGRADED);
 
   const absl::optional<base::FilePath> app_install_dir =
-      GetAppInstallDir(app_id_);
+      GetAppInstallDir(updater_scope_, app_id_);
   if (!app_install_dir)
     return Result(update_client::InstallError::NO_DIR_COMPONENT_USER);
   if (!base::CreateDirectory(*app_install_dir))
@@ -245,7 +248,8 @@
 absl::optional<base::FilePath> Installer::GetCurrentInstallDir() const {
   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                 base::BlockingType::WILL_BLOCK);
-  absl::optional<base::FilePath> path = GetAppInstallDir(app_id_);
+  const absl::optional<base::FilePath> path =
+      GetAppInstallDir(updater_scope_, app_id_);
   if (!path)
     return absl::nullopt;
   return path->AppendASCII(pv_.GetString());
diff --git a/chrome/updater/installer.h b/chrome/updater/installer.h
index 35c8be1..e32b708 100644
--- a/chrome/updater/installer.h
+++ b/chrome/updater/installer.h
@@ -20,6 +20,8 @@
 
 namespace updater {
 
+enum class UpdaterScope;
+
 // Manages the install of one application. Some of the functions of this
 // class are blocking and can't be invoked on the main sequence.
 //
@@ -98,6 +100,8 @@
 
   SEQUENCE_CHECKER(sequence_checker_);
 
+  UpdaterScope updater_scope_;
+
   const std::string app_id_;
   scoped_refptr<PersistedData> persisted_data_;
 
diff --git a/chrome/updater/mac/setup/setup.mm b/chrome/updater/mac/setup/setup.mm
index 1d77166..cfad2fe 100644
--- a/chrome/updater/mac/setup/setup.mm
+++ b/chrome/updater/mac/setup/setup.mm
@@ -316,8 +316,8 @@
   return DeleteFolder(GetVersionedUpdaterFolderPath(scope));
 }
 
-bool DeleteDataFolder() {
-  return DeleteFolder(GetBaseDirectory());
+bool DeleteDataFolder(UpdaterScope scope) {
+  return DeleteFolder(GetBaseDirectory(scope));
 }
 
 }  // namespace
@@ -434,7 +434,7 @@
 
   UninstallOtherVersions(scope);
 
-  if (!DeleteDataFolder())
+  if (!DeleteDataFolder(scope))
     return setup_exit_codes::kFailedToDeleteDataFolder;
 
   if (!DeleteInstallFolder(scope))
diff --git a/chrome/updater/prefs.cc b/chrome/updater/prefs.cc
index b28ef68..9a7d24f0e 100644
--- a/chrome/updater/prefs.cc
+++ b/chrome/updater/prefs.cc
@@ -12,6 +12,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "chrome/updater/prefs_impl.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 #include "components/prefs/json_pref_store.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -72,7 +73,8 @@
   if (!lock)
     return nullptr;
 
-  absl::optional<base::FilePath> global_prefs_dir = GetBaseDirectory();
+  const absl::optional<base::FilePath> global_prefs_dir =
+      GetBaseDirectory(GetUpdaterScope());
   if (!global_prefs_dir)
     return nullptr;
   VLOG(1) << "global_prefs_dir: " << global_prefs_dir;
@@ -92,7 +94,8 @@
 }
 
 std::unique_ptr<LocalPrefs> CreateLocalPrefs() {
-  absl::optional<base::FilePath> local_prefs_dir = GetVersionedDirectory();
+  const absl::optional<base::FilePath> local_prefs_dir =
+      GetVersionedDirectory(GetUpdaterScope());
   if (!local_prefs_dir)
     return nullptr;
 
diff --git a/chrome/updater/service_factory_mac.mm b/chrome/updater/service_factory_mac.mm
index 36ce5ad..9373245 100644
--- a/chrome/updater/service_factory_mac.mm
+++ b/chrome/updater/service_factory_mac.mm
@@ -10,11 +10,11 @@
 namespace updater {
 
 scoped_refptr<UpdateService> CreateUpdateService() {
-  return base::MakeRefCounted<UpdateServiceProxy>(GetProcessScope());
+  return base::MakeRefCounted<UpdateServiceProxy>(GetUpdaterScope());
 }
 
 scoped_refptr<UpdateServiceInternal> CreateUpdateServiceInternal() {
-  return base::MakeRefCounted<UpdateServiceInternalProxy>(GetProcessScope());
+  return base::MakeRefCounted<UpdateServiceInternalProxy>(GetUpdaterScope());
 }
 
 }  // namespace updater
diff --git a/chrome/updater/service_factory_win.cc b/chrome/updater/service_factory_win.cc
index d4a023f3..304dd85 100644
--- a/chrome/updater/service_factory_win.cc
+++ b/chrome/updater/service_factory_win.cc
@@ -31,12 +31,12 @@
 
 scoped_refptr<UpdateService> CreateUpdateService() {
   WRLModuleInitializer::Get();
-  return base::MakeRefCounted<UpdateServiceProxy>(GetProcessScope());
+  return base::MakeRefCounted<UpdateServiceProxy>(GetUpdaterScope());
 }
 
 scoped_refptr<UpdateServiceInternal> CreateUpdateServiceInternal() {
   WRLModuleInitializer::Get();
-  return base::MakeRefCounted<UpdateServiceInternalProxy>(GetProcessScope());
+  return base::MakeRefCounted<UpdateServiceInternalProxy>(GetUpdaterScope());
 }
 
 }  // namespace updater
diff --git a/chrome/updater/tag.h b/chrome/updater/tag.h
index 39d5b6f..0d6754a 100644
--- a/chrome/updater/tag.h
+++ b/chrome/updater/tag.h
@@ -13,7 +13,6 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace updater {
-
 namespace tagging {
 
 // This struct contains the attributes for a given app parsed from a part of the
@@ -223,7 +222,6 @@
                 TagArgs* args);
 
 }  // namespace tagging
-
 }  // namespace updater
 
 #endif  // CHROME_UPDATER_TAG_H_
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index 3a88c84..73337b4 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -309,7 +309,7 @@
     // releases the prefs lock before updater_internal_server tries to acquire
     // it to mode-check.
     Microsoft::WRL::ComPtr<IUnknown> updater_server;
-    EXPECT_HRESULT_SUCCEEDED(::CoCreateInstance(__uuidof(UpdaterClass), nullptr,
+    ASSERT_HRESULT_SUCCEEDED(::CoCreateInstance(__uuidof(UpdaterClass), nullptr,
                                                 CLSCTX_LOCAL_SERVER,
                                                 IID_PPV_ARGS(&updater_server)));
     Microsoft::WRL::ComPtr<IUpdater> updater;
diff --git a/chrome/updater/test/test_app/test_app.cc b/chrome/updater/test/test_app/test_app.cc
index 037aefc..e6f7de9 100644
--- a/chrome/updater/test/test_app/test_app.cc
+++ b/chrome/updater/test/test_app/test_app.cc
@@ -23,6 +23,7 @@
 #include "chrome/updater/app/app.h"
 #include "chrome/updater/test/test_app/constants.h"
 #include "chrome/updater/test/test_app/update_client.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 
 namespace updater {
@@ -139,7 +140,7 @@
   base::AtExitManager exit_manager;
 
   base::CommandLine::Init(argc, argv);
-  updater::InitLogging(FILE_PATH_LITERAL("test_app.log"));
+  updater::InitLogging(GetUpdaterScope(), FILE_PATH_LITERAL("test_app.log"));
 
   base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI);
   return MakeTestApp()->Run();
diff --git a/chrome/updater/test/test_app/test_app_mac.mm b/chrome/updater/test/test_app/test_app_mac.mm
index 6f5dc1f..7f6de33 100644
--- a/chrome/updater/test/test_app/test_app_mac.mm
+++ b/chrome/updater/test/test_app/test_app_mac.mm
@@ -23,7 +23,6 @@
 #include "chrome/updater/util.h"
 
 namespace updater {
-
 namespace {
 
 base::FilePath GetUpdaterAppName() {
@@ -67,7 +66,7 @@
 
   base::CommandLine command(updater_executable_path);
   command.AppendSwitch(kInstallSwitch);
-  if (GetProcessScope() == UpdaterScope::kSystem) {
+  if (GetUpdaterScope() == UpdaterScope::kSystem) {
     command.AppendSwitch(kSystemSwitch);
     command = MakeElevated(command);
   }
diff --git a/chrome/updater/test/test_app/test_app_win.cc b/chrome/updater/test/test_app/test_app_win.cc
index 7e0db07..a3656ba6 100644
--- a/chrome/updater/test/test_app/test_app_win.cc
+++ b/chrome/updater/test/test_app/test_app_win.cc
@@ -24,7 +24,7 @@
   base::CommandLine command_line(
       test_executable.DirName().AppendASCII("UpdaterSetup.exe"));
   command_line.AppendSwitch(kInstallSwitch);
-  if (GetProcessScope() == UpdaterScope::kSystem)
+  if (GetUpdaterScope() == UpdaterScope::kSystem)
     command_line.AppendSwitch(kSystemSwitch);
   command_line.AppendSwitch("enable-logging");
   command_line.AppendSwitchASCII("--vmodule", "*/updater/*=2");
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc
index 6e06a69..72c00da 100644
--- a/chrome/updater/updater.cc
+++ b/chrome/updater/updater.cc
@@ -20,6 +20,7 @@
 #include "chrome/updater/constants.h"
 #include "chrome/updater/crash_client.h"
 #include "chrome/updater/crash_reporter.h"
+#include "chrome/updater/updater_scope.h"
 #include "chrome/updater/updater_version.h"
 #include "chrome/updater/util.h"
 #include "components/crash/core/common/crash_key.h"
@@ -48,13 +49,14 @@
 //   arguments for --install.
 
 namespace updater {
-
 namespace {
 
 // The log file is created in DIR_LOCAL_APP_DATA or DIR_APP_DATA.
-void InitLogging(const base::CommandLine& command_line) {
+void InitLogging(UpdaterScope updater_scope,
+                 const base::CommandLine& command_line) {
   logging::LoggingSettings settings;
-  absl::optional<base::FilePath> log_dir = GetBaseDirectory();
+  const absl::optional<base::FilePath> log_dir =
+      GetBaseDirectory(updater_scope);
   if (!log_dir) {
     LOG(ERROR) << "Error getting base dir.";
     return;
@@ -71,12 +73,12 @@
           << settings.log_file_path;
 }
 
-void InitializeCrashReporting() {
+void InitializeCrashReporting(UpdaterScope updater_scope) {
   crash_reporter::InitializeCrashKeys();
   static crash_reporter::CrashKeyString<16> crash_key_process_type(
       "process_type");
   crash_key_process_type.Set("updater");
-  if (CrashClient::GetInstance()->InitializeCrashReporting())
+  if (CrashClient::GetInstance()->InitializeCrashReporting(updater_scope))
     VLOG(1) << "Crash reporting initialized.";
   else
     VLOG(1) << "Crash reporting is not available.";
@@ -135,17 +137,18 @@
   base::AtExitManager exit_manager;
 
   base::CommandLine::Init(argc, argv);
-  const auto* command_line = base::CommandLine::ForCurrentProcess();
+  const base::CommandLine* command_line =
+      base::CommandLine::ForCurrentProcess();
+  VLOG(1) << "Command line: " << command_line->GetCommandLineString();
+
   if (command_line->HasSwitch(kTestSwitch))
     return 0;
 
-  InitLogging(*command_line);
-
-  VLOG(1) << "Command line: " << command_line->GetCommandLineString();
+  const UpdaterScope updater_scope = GetUpdaterScope();
+  InitLogging(updater_scope, *command_line);
   if (command_line->HasSwitch(kCrashHandlerSwitch))
     return CrashReporterMain();
-
-  InitializeCrashReporting();
+  InitializeCrashReporting(updater_scope);
 
   const int retval = HandleUpdaterCommands(command_line);
   DVLOG(1) << __func__ << " returned " << retval << ".";
diff --git a/chrome/updater/updater_scope.cc b/chrome/updater/updater_scope.cc
new file mode 100644
index 0000000..af604d8
--- /dev/null
+++ b/chrome/updater/updater_scope.cc
@@ -0,0 +1,56 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/updater/updater_scope.h"
+
+#include "base/check_op.h"
+#include "base/command_line.h"
+#include "build/build_config.h"
+#include "chrome/updater/constants.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+#if defined(OS_WIN)
+#include "chrome/updater/tag.h"
+#include "chrome/updater/util.h"
+#include "chrome/updater/win/win_util.h"
+#endif
+
+namespace updater {
+namespace {
+
+bool IsSystemProcess() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(kSystemSwitch);
+}
+
+}  // namespace
+
+UpdaterScope GetUpdaterScope() {
+#if defined(OS_WIN)
+  if (IsSystemProcess()) {
+    return UpdaterScope::kSystem;
+  }
+
+  // TODO(crbug.com/1128631): support bundles. For now, assume one app.
+  const absl::optional<tagging::TagArgs> tag_args = GetTagArgs();
+  if (tag_args && !tag_args->apps.empty() &&
+      tag_args->apps.front().needs_admin) {
+    DCHECK_EQ(tag_args->apps.size(), size_t{1});
+    switch (*tag_args->apps.front().needs_admin) {
+      case tagging::AppArgs::NeedsAdmin::kYes:
+      case tagging::AppArgs::NeedsAdmin::kPrefers:
+        return UpdaterScope::kSystem;
+      case tagging::AppArgs::NeedsAdmin::kNo:
+        return UpdaterScope::kUser;
+    }
+  }
+
+  // crbug.com(1214058): consider handling the elevation case by
+  // calling IsRunningElevated().
+  return UpdaterScope::kUser;
+#else
+  return IsSystemProcess() ? UpdaterScope::kSystem : UpdaterScope::kUser;
+#endif
+}
+
+}  // namespace updater
diff --git a/chrome/updater/updater_scope.h b/chrome/updater/updater_scope.h
index ebb33f55..bbda4d0 100644
--- a/chrome/updater/updater_scope.h
+++ b/chrome/updater/updater_scope.h
@@ -7,9 +7,6 @@
 
 #include <ostream>
 
-#include "base/command_line.h"
-#include "chrome/updater/constants.h"
-
 namespace updater {
 
 // Scope of the service invocation.
@@ -21,12 +18,6 @@
   kSystem = 2,
 };
 
-inline UpdaterScope GetProcessScope() {
-  return base::CommandLine::ForCurrentProcess()->HasSwitch(kSystemSwitch)
-             ? UpdaterScope::kSystem
-             : UpdaterScope::kUser;
-}
-
 inline std::ostream& operator<<(std::ostream& os, UpdaterScope scope) {
   switch (scope) {
     case UpdaterScope::kUser:
@@ -36,6 +27,12 @@
   }
 }
 
+// Returns the scope of the updater, which is either per-system or per-user.
+// The updater scope is determined from command line arguments of the process,
+// the presence and content of the --tag argument, and the integrity level
+// of the process, where applicable.
+UpdaterScope GetUpdaterScope();
+
 }  // namespace updater
 
 #endif  // CHROME_UPDATER_UPDATER_SCOPE_H_
diff --git a/chrome/updater/updater_scope_unittest.cc b/chrome/updater/updater_scope_unittest.cc
index cbe3c0a..c85d3ee 100644
--- a/chrome/updater/updater_scope_unittest.cc
+++ b/chrome/updater/updater_scope_unittest.cc
@@ -11,14 +11,14 @@
 
 namespace updater {
 
-TEST(UpdaterScope, GetProcessScope) {
+TEST(UpdaterScope, GetUpdaterScope) {
   base::test::ScopedCommandLine original_command_line;
   {
     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
     command_line->RemoveSwitch(kSystemSwitch);
-    DCHECK_EQ(GetProcessScope(), UpdaterScope::kUser);
+    DCHECK_EQ(GetUpdaterScope(), UpdaterScope::kUser);
     command_line->AppendSwitch(kSystemSwitch);
-    DCHECK_EQ(GetProcessScope(), UpdaterScope::kSystem);
+    DCHECK_EQ(GetUpdaterScope(), UpdaterScope::kSystem);
   }
 }
 
diff --git a/chrome/updater/util.cc b/chrome/updater/util.cc
index 192b59e..134a67cc 100644
--- a/chrome/updater/util.cc
+++ b/chrome/updater/util.cc
@@ -11,6 +11,8 @@
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
+#include "chrome/updater/constants.h"
+#include "chrome/updater/tag.h"
 #include "chrome/updater/updater_branding.h"
 #include "chrome/updater/updater_scope.h"
 #include "chrome/updater/updater_version.h"
@@ -22,7 +24,6 @@
 #endif
 
 namespace updater {
-
 namespace {
 
 const char kHexString[] = "0123456789ABCDEF";
@@ -85,8 +86,7 @@
 
 }  // namespace
 
-absl::optional<base::FilePath> GetBaseDirectory() {
-  UpdaterScope scope = GetProcessScope();
+absl::optional<base::FilePath> GetBaseDirectory(UpdaterScope scope) {
   absl::optional<base::FilePath> app_data_dir;
 #if defined(OS_WIN)
   base::FilePath path;
@@ -115,8 +115,8 @@
   return product_data_dir;
 }
 
-absl::optional<base::FilePath> GetVersionedDirectory() {
-  absl::optional<base::FilePath> product_dir = GetBaseDirectory();
+absl::optional<base::FilePath> GetVersionedDirectory(UpdaterScope scope) {
+  const absl::optional<base::FilePath> product_dir = GetBaseDirectory(scope);
   if (!product_dir) {
     LOG(ERROR) << "Failed to get the base directory.";
     return absl::nullopt;
@@ -131,6 +131,25 @@
   return versioned_dir;
 }
 
+absl::optional<tagging::TagArgs> GetTagArgs() {
+  static const absl::optional<tagging::TagArgs> tag_args =
+      []() -> absl::optional<tagging::TagArgs> {
+    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+    const std::string tag = command_line->GetSwitchValueASCII(kTagSwitch);
+    if (tag.empty())
+      return absl::nullopt;
+    tagging::TagArgs tag_args;
+    const tagging::ErrorCode error =
+        tagging::Parse(tag, absl::nullopt, &tag_args);
+    VLOG_IF(1, error != tagging::ErrorCode::kSuccess)
+        << "Tag parsing returned " << error << ".";
+    return error == tagging::ErrorCode::kSuccess ? absl::make_optional(tag_args)
+                                                 : absl::nullopt;
+  }();
+
+  return tag_args;
+}
+
 base::CommandLine MakeElevated(base::CommandLine command_line) {
 #if defined(OS_MAC)
   command_line.PrependWrapper("/usr/bin/sudo");
@@ -139,9 +158,11 @@
 }
 
 // The log file is created in DIR_LOCAL_APP_DATA or DIR_APP_DATA.
-void InitLogging(const base::FilePath::StringType& filename) {
+void InitLogging(UpdaterScope updater_scope,
+                 const base::FilePath::StringType& filename) {
   logging::LoggingSettings settings;
-  absl::optional<base::FilePath> log_dir = GetBaseDirectory();
+  const absl::optional<base::FilePath> log_dir =
+      GetBaseDirectory(updater_scope);
   if (!log_dir) {
     LOG(ERROR) << "Error getting base dir.";
     return;
diff --git a/chrome/updater/util.h b/chrome/updater/util.h
index 0b22948..e49767e 100644
--- a/chrome/updater/util.h
+++ b/chrome/updater/util.h
@@ -30,28 +30,40 @@
 
 namespace updater {
 
+namespace tagging {
+struct TagArgs;
+}
+
+enum class UpdaterScope;
+
 // Returns the base directory common to all versions of the updater. For
 // instance, this function may return %localappdata%\Chromium\ChromiumUpdater
-// for a User install.
-absl::optional<base::FilePath> GetBaseDirectory();
+// for a user install.
+absl::optional<base::FilePath> GetBaseDirectory(UpdaterScope scope);
 
 // Returns a versioned directory under which the running version of the updater
 // stores its files and data. For instance, this function may return
-// %localappdata%\Chromium\ChromiumUpdater\1.2.3.4 for a User install.
-absl::optional<base::FilePath> GetVersionedDirectory();
+// %localappdata%\Chromium\ChromiumUpdater\1.2.3.4 for a user install.
+absl::optional<base::FilePath> GetVersionedDirectory(UpdaterScope scope);
 
-// Returns true if the user running the updater also owns the |path|.
+// Returns the parsed values from --tag command line argument. The function
+// implementation uses lazy initialization and caching to avoid reparsing
+// the tag.
+absl::optional<tagging::TagArgs> GetTagArgs();
+
+// Returns true if the user running the updater also owns the `path`.
 bool PathOwnedByUser(const base::FilePath& path);
 
 // Initializes logging for an executable.
-void InitLogging(const base::FilePath::StringType& filename);
+void InitLogging(UpdaterScope updater_scope,
+                 const base::FilePath::StringType& filename);
 
 // Wraps the 'command_line' to be executed in an elevated context.
 // On macOS this is done with 'sudo'.
 base::CommandLine MakeElevated(base::CommandLine command_line);
 
 // Functor used by associative containers of strings as a case-insensitive ASCII
-// compare. |StringT| could be either UTF-8 or UTF-16.
+// compare. `StringT` could be either UTF-8 or UTF-16.
 struct CaseInsensitiveASCIICompare {
  public:
   template <typename StringT>
diff --git a/chrome/updater/win/setup/setup.cc b/chrome/updater/win/setup/setup.cc
index 6da7ca7..da0348f2 100644
--- a/chrome/updater/win/setup/setup.cc
+++ b/chrome/updater/win/setup/setup.cc
@@ -122,7 +122,8 @@
     LOG(ERROR) << "GetTempDir failed.";
     return -1;
   }
-  absl::optional<base::FilePath> versioned_dir = GetVersionedDirectory();
+  const absl::optional<base::FilePath> versioned_dir =
+      GetVersionedDirectory(scope);
   if (!versioned_dir) {
     LOG(ERROR) << "GetVersionedDirectory failed.";
     return -1;
diff --git a/chrome/updater/win/setup/uninstall.cc b/chrome/updater/win/setup/uninstall.cc
index 30c44a7..a94368d 100644
--- a/chrome/updater/win/setup/uninstall.cc
+++ b/chrome/updater/win/setup/uninstall.cc
@@ -77,7 +77,8 @@
 }
 
 int RunUninstallScript(bool uninstall_all) {
-  absl::optional<base::FilePath> versioned_dir = GetVersionedDirectory();
+  const absl::optional<base::FilePath> versioned_dir =
+      GetVersionedDirectory(UpdaterScope());
   if (!versioned_dir) {
     LOG(ERROR) << "GetVersionedDirectory failed.";
     return -1;
@@ -89,7 +90,8 @@
   if (!size || size >= MAX_PATH)
     return -1;
 
-  base::FilePath script_path = versioned_dir->AppendASCII(kUninstallScript);
+  const base::FilePath script_path =
+      versioned_dir->AppendASCII(kUninstallScript);
 
   std::wstring cmdline = cmd_path;
   base::StringAppendF(&cmdline, L" /Q /C \"%ls\" %ls",
diff --git a/chrome/updater/win/update_service_proxy.cc b/chrome/updater/win/update_service_proxy.cc
index 48e02d4..799cf45 100644
--- a/chrome/updater/win/update_service_proxy.cc
+++ b/chrome/updater/win/update_service_proxy.cc
@@ -436,9 +436,7 @@
 UpdateServiceProxy::UpdateServiceProxy(UpdaterScope updater_scope)
     : main_task_runner_(base::SequencedTaskRunnerHandle::Get()),
       com_task_runner_(
-          base::ThreadPool::CreateCOMSTATaskRunner(kComClientTraits)) {
-  DCHECK_EQ(updater_scope, UpdaterScope::kUser);
-}
+          base::ThreadPool::CreateCOMSTATaskRunner(kComClientTraits)) {}
 
 UpdateServiceProxy::~UpdateServiceProxy() = default;
 
diff --git a/chrome/updater/win/win_util.cc b/chrome/updater/win/win_util.cc
index 32cf650..a865cca7 100644
--- a/chrome/updater/win/win_util.cc
+++ b/chrome/updater/win/win_util.cc
@@ -358,8 +358,26 @@
 
 bool PathOwnedByUser(const base::FilePath& path) {
   // TODO(crbug.com/1147094): Implement for Win.
-
   return true;
 }
 
+// TODO(crbug.com/1212187): maybe handle filtered tokens.
+bool IsRunningElevated() {
+  SID_IDENTIFIER_AUTHORITY nt_authority = SECURITY_NT_AUTHORITY;
+  PSID administrators_group = nullptr;
+  if (!::AllocateAndInitializeSid(&nt_authority, 2, SECURITY_BUILTIN_DOMAIN_RID,
+                                  DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
+                                  &administrators_group)) {
+    return false;
+  }
+
+  BOOL result = false;
+  if (!::CheckTokenMembership(NULL, administrators_group, &result)) {
+    result = false;
+  }
+  ::FreeSid(administrators_group);
+
+  return result;
+}
+
 }  // namespace updater
diff --git a/chrome/updater/win/win_util.h b/chrome/updater/win/win_util.h
index 21699f1..626b8efd 100644
--- a/chrome/updater/win/win_util.h
+++ b/chrome/updater/win/win_util.h
@@ -108,6 +108,10 @@
 // Returns a logged on user token handle from the current session.
 base::win::ScopedHandle GetUserTokenFromCurrentSessionId();
 
+// Returns true if the process is running with elevated privileges of a
+// user in the an administrator group.
+bool IsRunningElevated();
+
 }  // namespace updater
 
 #endif  // CHROME_UPDATER_WIN_WIN_UTIL_H_
diff --git a/chromeos/components/diagnostics_ui/backend/diagnostics_manager.cc b/chromeos/components/diagnostics_ui/backend/diagnostics_manager.cc
index 42217b5a..4409157 100644
--- a/chromeos/components/diagnostics_ui/backend/diagnostics_manager.cc
+++ b/chromeos/components/diagnostics_ui/backend/diagnostics_manager.cc
@@ -6,6 +6,7 @@
 
 #include "ash/constants/ash_features.h"
 #include "chromeos/components/diagnostics_ui/backend/input_data_provider.h"
+#include "chromeos/components/diagnostics_ui/backend/network_health_provider.h"
 #include "chromeos/components/diagnostics_ui/backend/session_log_handler.h"
 #include "chromeos/components/diagnostics_ui/backend/system_data_provider.h"
 #include "chromeos/components/diagnostics_ui/backend/system_routine_controller.h"
@@ -18,6 +19,10 @@
           session_log_handler->GetTelemetryLog())),
       system_routine_controller_(std::make_unique<SystemRoutineController>(
           session_log_handler->GetRoutineLog())) {
+  if (features::IsNetworkingInDiagnosticsAppEnabled()) {
+    network_health_provider_ = std::make_unique<NetworkHealthProvider>();
+  }
+
   if (features::IsInputInDiagnosticsAppEnabled()) {
     input_data_provider_ = std::make_unique<InputDataProvider>();
   }
@@ -25,6 +30,11 @@
 
 DiagnosticsManager::~DiagnosticsManager() = default;
 
+NetworkHealthProvider* DiagnosticsManager::GetNetworkHealthProvider() const {
+  DCHECK(features::IsNetworkingInDiagnosticsAppEnabled());
+  return network_health_provider_.get();
+}
+
 SystemDataProvider* DiagnosticsManager::GetSystemDataProvider() const {
   return system_data_provider_.get();
 }
diff --git a/chromeos/components/diagnostics_ui/backend/diagnostics_manager.h b/chromeos/components/diagnostics_ui/backend/diagnostics_manager.h
index b1f8a03..ce742c9 100644
--- a/chromeos/components/diagnostics_ui/backend/diagnostics_manager.h
+++ b/chromeos/components/diagnostics_ui/backend/diagnostics_manager.h
@@ -10,6 +10,7 @@
 namespace chromeos {
 namespace diagnostics {
 
+class NetworkHealthProvider;
 class SessionLogHandler;
 class SystemDataProvider;
 class SystemRoutineController;
@@ -25,11 +26,13 @@
   DiagnosticsManager(const DiagnosticsManager&) = delete;
   DiagnosticsManager& operator=(const DiagnosticsManager&) = delete;
 
+  NetworkHealthProvider* GetNetworkHealthProvider() const;
   SystemDataProvider* GetSystemDataProvider() const;
   SystemRoutineController* GetSystemRoutineController() const;
   InputDataProvider* GetInputDataProvider() const;
 
  private:
+  std::unique_ptr<NetworkHealthProvider> network_health_provider_;
   std::unique_ptr<SystemDataProvider> system_data_provider_;
   std::unique_ptr<SystemRoutineController> system_routine_controller_;
   std::unique_ptr<InputDataProvider> input_data_provider_;
diff --git a/chromeos/components/diagnostics_ui/backend/network_health_provider.cc b/chromeos/components/diagnostics_ui/backend/network_health_provider.cc
index 9ff761f6..c305c61 100644
--- a/chromeos/components/diagnostics_ui/backend/network_health_provider.cc
+++ b/chromeos/components/diagnostics_ui/backend/network_health_provider.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <utility>
 
+#include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/containers/contains.h"
 #include "chromeos/services/network_config/in_process_instance.h"
@@ -317,6 +318,12 @@
   NotifyNetworkStateObserver(network_properties);
 }
 
+void NetworkHealthProvider::BindInterface(
+    mojo::PendingReceiver<mojom::NetworkHealthProvider> pending_receiver) {
+  DCHECK(features::IsNetworkingInDiagnosticsAppEnabled());
+  receiver_.Bind(std::move(pending_receiver));
+}
+
 void NetworkHealthProvider::NotifyNetworkListObservers() {
   auto network_guid_list = GetNetworkGuidList();
   for (auto& observer : network_list_observers_) {
diff --git a/chromeos/components/diagnostics_ui/backend/network_health_provider.h b/chromeos/components/diagnostics_ui/backend/network_health_provider.h
index cfa6748..417dd2c 100644
--- a/chromeos/components/diagnostics_ui/backend/network_health_provider.h
+++ b/chromeos/components/diagnostics_ui/backend/network_health_provider.h
@@ -51,6 +51,9 @@
   void ObserveNetwork(mojo::PendingRemote<mojom::NetworkStateObserver> observer,
                       const std::string& guid) override;
 
+  void BindInterface(
+      mojo::PendingReceiver<mojom::NetworkHealthProvider> pending_receiver);
+
   // CrosNetworkConfigObserver
   void OnNetworkStateListChanged() override;
   void OnDeviceStateListChanged() override;
@@ -128,6 +131,8 @@
   // Remotes for tracking observers that will be notified of changes to the
   // list of active networks.
   mojo::RemoteSet<mojom::NetworkListObserver> network_list_observers_;
+
+  mojo::Receiver<mojom::NetworkHealthProvider> receiver_{this};
 };
 
 }  // namespace diagnostics
diff --git a/chromeos/components/diagnostics_ui/diagnostics_ui.cc b/chromeos/components/diagnostics_ui/diagnostics_ui.cc
index 261ca80be..b33f607 100644
--- a/chromeos/components/diagnostics_ui/diagnostics_ui.cc
+++ b/chromeos/components/diagnostics_ui/diagnostics_ui.cc
@@ -13,9 +13,11 @@
 #include "chromeos/components/diagnostics_ui/backend/diagnostics_manager.h"
 #include "chromeos/components/diagnostics_ui/backend/histogram_util.h"
 #include "chromeos/components/diagnostics_ui/backend/input_data_provider.h"
+#include "chromeos/components/diagnostics_ui/backend/network_health_provider.h"
 #include "chromeos/components/diagnostics_ui/backend/session_log_handler.h"
 #include "chromeos/components/diagnostics_ui/backend/system_data_provider.h"
 #include "chromeos/components/diagnostics_ui/backend/system_routine_controller.h"
+#include "chromeos/components/diagnostics_ui/mojom/network_health_provider.mojom.h"
 #include "chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom.h"
 #include "chromeos/components/diagnostics_ui/url_constants.h"
 #include "chromeos/grit/chromeos_diagnostics_app_resources.h"
@@ -179,6 +181,16 @@
 }
 
 void DiagnosticsDialogUI::BindInterface(
+    mojo::PendingReceiver<diagnostics::mojom::NetworkHealthProvider> receiver) {
+  DCHECK(features::IsNetworkingInDiagnosticsAppEnabled());
+  diagnostics::NetworkHealthProvider* network_health_provider =
+      diagnostics_manager_->GetNetworkHealthProvider();
+  if (network_health_provider) {
+    network_health_provider->BindInterface(std::move(receiver));
+  }
+}
+
+void DiagnosticsDialogUI::BindInterface(
     mojo::PendingReceiver<diagnostics::mojom::SystemDataProvider> receiver) {
   diagnostics::SystemDataProvider* system_data_provider =
       diagnostics_manager_->GetSystemDataProvider();
diff --git a/chromeos/components/diagnostics_ui/diagnostics_ui.h b/chromeos/components/diagnostics_ui/diagnostics_ui.h
index c7b3b14b..65b1799 100644
--- a/chromeos/components/diagnostics_ui/diagnostics_ui.h
+++ b/chromeos/components/diagnostics_ui/diagnostics_ui.h
@@ -9,6 +9,7 @@
 #include "base/time/time.h"
 #include "chromeos/components/diagnostics_ui/backend/session_log_handler.h"
 #include "chromeos/components/diagnostics_ui/mojom/input_data_provider.mojom-forward.h"
+#include "chromeos/components/diagnostics_ui/mojom/network_health_provider.mojom-forward.h"
 #include "chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom-forward.h"
 #include "chromeos/components/diagnostics_ui/mojom/system_routine_controller.mojom-forward.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -34,6 +35,10 @@
   DiagnosticsDialogUI& operator=(const DiagnosticsDialogUI&) = delete;
 
   void BindInterface(
+      mojo::PendingReceiver<diagnostics::mojom::NetworkHealthProvider>
+          receiver);
+
+  void BindInterface(
       mojo::PendingReceiver<diagnostics::mojom::SystemDataProvider> receiver);
 
   void BindInterface(
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_app_resources.grd b/chromeos/components/diagnostics_ui/resources/diagnostics_app_resources.grd
index b1dad8b1..692ac104 100644
--- a/chromeos/components/diagnostics_ui/resources/diagnostics_app_resources.grd
+++ b/chromeos/components/diagnostics_ui/resources/diagnostics_app_resources.grd
@@ -37,6 +37,7 @@
       <include name="IDR_DIAGNOSTICS_MOJO_INTERFACE_PROVIDER_JS" file="mojo_interface_provider.js" type="BINDATA"/>
       <include name="IDR_DIAGNOSTICS_MOJO_UTILS_JS" file="mojo_utils.js" type="BINDATA"/>
       <include name="IDR_DIAGNOSTICS_NETWORK_CARD_JS" file="${root_gen_dir}/chromeos/components/diagnostics_ui/resources/network_card.js" resource_path="network_card.js" use_base_dir="false" type="BINDATA"/>
+      <include name="IDR_DIAGNOSTICS_NETWORK_HEALTH_PROVIDER_MOJO_LITE_JS" file="${root_gen_dir}/chromeos/components/diagnostics_ui/mojom/network_health_provider.mojom-lite.js" resource_path="network_health_provider.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_DIAGNOSTICS_NETWORK_INFO_JS" file="${root_gen_dir}/chromeos/components/diagnostics_ui/resources/network_info.js" resource_path="network_info.js" use_base_dir="false" type="BINDATA"/>
       <include name="IDR_DIAGNOSTICS_NETWORK_LIST_JS" file="${root_gen_dir}/chromeos/components/diagnostics_ui/resources/network_list.js" resource_path="network_list.js" use_base_dir="false" type="BINDATA"/>
       <include name="IDR_DIAGNOSTICS_OVERVIEW_CARD_JS" file="${root_gen_dir}/chromeos/components/diagnostics_ui/resources/overview_card.js" resource_path="overview_card.js" use_base_dir="false" type="BINDATA"/>
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_types.js b/chromeos/components/diagnostics_ui/resources/diagnostics_types.js
index 65510be..557701b 100644
--- a/chromeos/components/diagnostics_ui/resources/diagnostics_types.js
+++ b/chromeos/components/diagnostics_ui/resources/diagnostics_types.js
@@ -11,6 +11,7 @@
 import 'chrome://resources/mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js';
 import 'chrome://resources/mojo/mojo/public/mojom/base/string16.mojom-lite.js';
 import './input_data_provider.mojom-lite.js';
+import './network_health_provider.mojom-lite.js'
 import './system_data_provider.mojom-lite.js';
 import './system_routine_controller.mojom-lite.js';
 
@@ -263,126 +264,88 @@
     chromeos.diagnostics.mojom.SystemRoutineControllerInterface;
 
 /**
- * TODO(michaelcheco): Add Cellular properties.
- * @typedef {!Object}
+ * Type alias for NetworkListObserver.
+ * @typedef {chromeos.diagnostics.mojom.NetworkListObserverRemote}
  */
-export let CellularStateProperties;
+export let NetworkListObserverRemote =
+    chromeos.diagnostics.mojom.NetworkListObserverRemote;
 
 /**
- * TODO(michaelcheco): Add Ethernet properties.
- * @typedef {!Object}
+ * Type alias for NetworkStateObserver.
+ * @typedef {chromeos.diagnostics.mojom.NetworkStateObserverRemote}
  */
-export let EthernetStateProperties;
+export let NetworkStateObserverRemote =
+    chromeos.diagnostics.mojom.NetworkStateObserverRemote;
 
 /**
- * @typedef {{
- *   signalStrength: number,
- *   frequency: number,
- *   ssid: string,
- *   bssid: string,
- * }}
+ * Type alias for Network.
+ * @typedef {chromeos.diagnostics.mojom.Network}
  */
-export let WiFiStateProperties;
+export let Network = chromeos.diagnostics.mojom.Network;
 
 /**
- * @typedef {{
- *   ipAddress: ?string,
- *   nameServers: ?Array<string>,
- *   subnetMask: ?string,
- *   gateway: ?string,
- * }}
+ * Type alias for NetworkHealthProvider.
+ * @typedef {chromeos.diagnostics.mojom.NetworkHealthProvider}
  */
-export let IPConfigProperties;
+export let NetworkHealthProvider =
+    chromeos.diagnostics.mojom.NetworkHealthProvider;
 
 /**
- * @typedef {(
- * !CellularStateProperties|!EthernetStateProperties|!WiFiStateProperties)}
+ * Type alias for NetworkHealthProviderInterface.
+ * @typedef {chromeos.diagnostics.mojom.NetworkHealthProviderInterface}
  */
-export let NetworkProperties;
+export let NetworkHealthProviderInterface =
+    chromeos.diagnostics.mojom.NetworkHealthProviderInterface;
 
 /**
- * @typedef {{
- *   state: number,
- *   type: number,
- *   networkProperties: !NetworkProperties,
- *   guid: string,
- *   name: string,
- *   macAddress: string,
- *   ipConfigProperties: ?IPConfigProperties,
- * }}
+ * Type alias for NetworkState.
+ * @typedef {chromeos.diagnostics.mojom.NetworkState}
  */
-export let Network;
+export let NetworkState = chromeos.diagnostics.mojom.NetworkState;
+
+/**
+ * Type alias for NetworkType
+ * @typedef {chromeos.diagnostics.mojom.NetworkType}
+ */
+export let NetworkType = chromeos.diagnostics.mojom.NetworkType;
+
+/**
+ * Type alias for NetworkListObserverReceiver.
+ * @typedef {chromeos.diagnostics.mojom.NetworkListObserverReceiver}
+ */
+export let NetworkListObserverReceiver =
+    chromeos.diagnostics.mojom.NetworkListObserverReceiver;
+
+/**
+ * Type alias for NetworkListObserverInterface.
+ * @typedef {chromeos.diagnostics.mojom.NetworkListObserverInterface}
+ */
+export let NetworkListObserverInterface =
+    chromeos.diagnostics.mojom.NetworkListObserverInterface;
+
+/**
+ * Type alias for NetworkStateObserverInterface.
+ * @typedef {chromeos.diagnostics.mojom.NetworkStateObserverInterface}
+ */
+export let NetworkStateObserverInterface =
+    chromeos.diagnostics.mojom.NetworkStateObserverInterface;
+
+/**
+ * Type alias for NetworkStateObserverReceiver.
+ * @typedef {chromeos.diagnostics.mojom.NetworkStateObserverReceiver}
+ */
+export let NetworkStateObserverReceiver =
+    chromeos.diagnostics.mojom.NetworkStateObserverReceiver;
 
 /**
  * @typedef {{
  *   networkGuids: !Array<string>,
- *   activeGuid: ?string,
+ *   activeGuid: string,
  * }}
  */
 export let NetworkGuidInfo;
 
 /**
- * Type alias for NetworkListObserver.
- * @typedef {{
- *   onNetworkListChanged: !function(!NetworkGuidInfo)
- * }}
- */
-export let NetworkListObserver;
-
-/**
- * Type alias for NetworkStateObserver.
- * @typedef {{
- *   onNetworkStateChanged: !function(!Network)
- * }}
- */
-export let NetworkStateObserver;
-
-/**
- * Type of NetworkHealthProviderInterface.ObserveNetworkListFunction function.
- * @typedef {!function(!NetworkListObserver): !Promise}
- */
-export let ObserveNetworkListFunction;
-
-/**
- * Type of NetworkHealthProviderInterface.ObserveNetworkFunction function.
- * @typedef {!function(!NetworkStateObserver, !string): !Promise}
- */
-export let ObserveNetworkFunction;
-
-/**
- * Type alias for the NetworkHealthProviderInterface.
- * TODO(michaelcheco): Replace with a real mojo type when implemented.
- * @typedef {{
- *   observeNetworkList: !ObserveNetworkListFunction,
- *   observeNetwork: !ObserveNetworkFunction,
- * }}
- */
-export let NetworkHealthProviderInterface;
-
-/**
- * @enum {number}
- */
-export let NetworkState = {
-  kUninitialized: 0,
-  kDisabled: 1,
-  kProhibited: 2,
-  kNotConnected: 3,
-  kConnecting: 4,
-  kPortal: 5,
-  kConnected: 6,
-  kOnline: 7,
-};
-
-/**
- * @enum {number}
- */
-export let NetworkType = {
-  kCellular: 0,
-  kEthernet: 1,
-  kWiFi: 2,
-};
-
-/**
  * Type alias for ConnectionType.
  * @typedef {chromeos.diagnostics.mojom.ConnectionType}
  */
diff --git a/chromeos/components/diagnostics_ui/resources/fake_data.js b/chromeos/components/diagnostics_ui/resources/fake_data.js
index 67d6f3ef..ffda0a8 100644
--- a/chromeos/components/diagnostics_ui/resources/fake_data.js
+++ b/chromeos/components/diagnostics_ui/resources/fake_data.js
@@ -268,20 +268,22 @@
 export let fakeWifiNetwork = {
   state: NetworkState.kConnected,
   type: NetworkType.kWiFi,
-  networkProperties: {
-    signalStrength: 65,
-    frequency: 5745,
-    bssid: '44:07:0b:06:2d:85',
-    ssid: 'Dial Up',
+  typeProperties: {
+    wifi: {
+      signalStrength: 65,
+      frequency: 5745,
+      bssid: '44:07:0b:06:2d:85',
+      ssid: 'Dial Up',
+    },
   },
   guid: 'wifiGuid',
   name: 'Dial Up',
   macAddress: '84:C5:A6:30:3F:31',
-  ipConfigProperties: {
+  ipConfig: {
     ipAddress: '192.168.86.197',
     gateway: '192.168.86.1',
     nameServers: ['192.168.86.1'],
-    subnetMask: '255.255.255.0',
+    routingPrefix: 24,
   },
 };
 
@@ -290,22 +292,26 @@
 export let fakeEthernetNetwork = {
   state: NetworkState.kOnline,
   type: NetworkType.kEthernet,
-  networkProperties: {},
+  typeProperties: {
+    ethernet: {},
+  },
   guid: 'ethernetGuid',
   name: 'ethernetName',
   macAddress: '81:C5:A6:30:3F:31',
-  ipConfigProperties: null,
+  ipConfig: null,
 };
 
 /** @type {!Network} */
 export let fakeCellularNetwork = {
   state: NetworkState.kConnected,
   type: NetworkType.kCellular,
-  networkProperties: {},
+  typeProperties: {
+    cellular: {},
+  },
   guid: 'cellularGuid',
   name: 'cellularName',
   macAddress: '85:C5:A6:30:3F:31',
-  ipConfigProperties: null,
+  ipConfig: null,
 };
 
 /** @type {!Array<!KeyboardInfo>} */
diff --git a/chromeos/components/diagnostics_ui/resources/fake_network_health_provider.js b/chromeos/components/diagnostics_ui/resources/fake_network_health_provider.js
index 50034adf..a47465e 100644
--- a/chromeos/components/diagnostics_ui/resources/fake_network_health_provider.js
+++ b/chromeos/components/diagnostics_ui/resources/fake_network_health_provider.js
@@ -23,6 +23,12 @@
   constructor() {
     this.observables_ = new FakeObservables();
 
+    /** @private {?Promise} */
+    this.observeNetworkListPromise_ = null;
+
+    /** @private {?Promise} */
+    this.observeNetworkStatePromise_ = null;
+
     this.registerObservables();
   }
 
@@ -32,10 +38,11 @@
    * @return {!Promise}
    */
   observeNetworkList(remote) {
-    return this.observe_(ON_NETWORK_LIST_CHANGED_METHOD_NAME, (networkGuid) => {
-      remote.onNetworkListChanged(
-          /** @type {!NetworkGuidInfo} */ (networkGuid));
-    });
+    this.observeNetworkListPromise_ = this.observe_(
+        ON_NETWORK_LIST_CHANGED_METHOD_NAME, (networkGuidInfo) => {
+          remote.onNetworkListChanged(
+              networkGuidInfo.networkGuids, networkGuidInfo.activeGuid);
+        });
   }
 
   /*
@@ -47,7 +54,7 @@
    * @return {!Promise}
    */
   observeNetwork(remote, guid) {
-    return this.observeWithArg_(
+    this.observeNetworkStatePromise_ = this.observeWithArg_(
         ON_NETWORK_STATE_CHANGED_METHOD_NAME, guid, (network) => {
           remote.onNetworkStateChanged(
               /** @type {!Network} */ (network));
@@ -73,6 +80,22 @@
   }
 
   /**
+   * Returns the promise for the most recent network list observation.
+   * @return {?Promise}
+   */
+  getObserveNetworkListPromiseForTesting() {
+    return this.observeNetworkListPromise_;
+  }
+
+  /**
+   * Returns the promise for the most recent network state observation.
+   * @return {?Promise}
+   */
+  getObserveNetworkStatePromiseForTesting() {
+    return this.observeNetworkStatePromise_;
+  }
+
+  /**
    * Causes the network list observer to fire.
    */
   triggerNetworkListObserver() {
@@ -110,7 +133,7 @@
     this.registerObservables();
   }
 
-  /*
+  /**
    * Sets up an observer for methodName.
    * @template T
    * @param {string} methodName
diff --git a/chromeos/components/diagnostics_ui/resources/mojo_interface_provider.js b/chromeos/components/diagnostics_ui/resources/mojo_interface_provider.js
index ab91347..f040148d 100644
--- a/chromeos/components/diagnostics_ui/resources/mojo_interface_provider.js
+++ b/chromeos/components/diagnostics_ui/resources/mojo_interface_provider.js
@@ -4,7 +4,7 @@
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 
-import {InputDataProviderInterface, NetworkHealthProviderInterface, PowerRoutineResult, RoutineType, StandardRoutineResult, SystemDataProvider, SystemDataProviderInterface, SystemInfo, SystemRoutineController, SystemRoutineControllerInterface} from './diagnostics_types.js';
+import {InputDataProviderInterface, NetworkHealthProvider, NetworkHealthProviderInterface, PowerRoutineResult, RoutineType, StandardRoutineResult, SystemDataProvider, SystemDataProviderInterface, SystemInfo, SystemRoutineController, SystemRoutineControllerInterface} from './diagnostics_types.js';
 import {fakeAllNetworksAvailable, fakeBatteryChargeStatus, fakeBatteryHealth, fakeBatteryInfo, fakeCellularNetwork, fakeCpuUsage, fakeEthernetNetwork, fakeMemoryUsage, fakePowerRoutineResults, fakeRoutineResults, fakeSystemInfo, fakeWifiNetwork} from './fake_data.js';
 import {FakeNetworkHealthProvider} from './fake_network_health_provider.js';
 import {FakeSystemDataProvider} from './fake_system_data_provider.js';
@@ -123,7 +123,7 @@
 /**
  * Create a FakeNetworkHealthProvider with reasonable fake data.
  */
-function setupFakeNetworkHealthProvider_() {
+function setupFakeNetworkHealthProvider() {
   const provider = new FakeNetworkHealthProvider();
   // The fake provides a stable state with all networks connected.
   provider.setFakeNetworkGuidInfo([fakeAllNetworksAvailable]);
@@ -139,8 +139,11 @@
  */
 export function getNetworkHealthProvider() {
   if (!networkHealthProvider) {
-    // TODO(michaelcheco): Instantiate a real mojo interface here.
-    setupFakeNetworkHealthProvider_();
+    if (useFakeProviders) {
+      setupFakeNetworkHealthProvider();
+    } else {
+      networkHealthProvider = NetworkHealthProvider.getRemote();
+    }
   }
 
   assert(!!networkHealthProvider);
diff --git a/chromeos/components/diagnostics_ui/resources/network_info.html b/chromeos/components/diagnostics_ui/resources/network_info.html
index b5c43fd..c4bc97e 100644
--- a/chromeos/components/diagnostics_ui/resources/network_info.html
+++ b/chromeos/components/diagnostics_ui/resources/network_info.html
@@ -2,13 +2,19 @@
 </style>
 
 <div id="infoElementContainer">
-  <wifi-info id="wifiInfo" network="[[network_]]"
-    hidden$="[[!isWifiNetwork_(network_.type)]]">
-  </wifi-info>
-  <ethernet-info id="ethernetInfo" network="[[network_]]"
-    hidden$="[[!isEthernetNetwork_(network_.type)]]">
-  </ethernet-info>
-  <cellular-info id="cellularInfo" network="[[network_]]"
-    hidden$="[[!isCellularNetwork_(network_.type)]]">
-  </cellular-info>
+  <template is="dom-if"
+      if="[[isWifiNetwork_(network_.type)]]">
+    <wifi-info id="wifiInfo" network="[[network_]]">
+    </wifi-info>
+  </template>
+  <template is="dom-if"
+      if="[[isEthernetNetwork_(network_.type)]]">
+    <ethernet-info id="ethernetInfo" network="[[network_]]">
+    </ethernet-info>
+  </template>
+  <template is="dom-if"
+      if="[[isCellularNetwork_(network_.type)]]">
+    <cellular-info id="cellularInfo" network="[[network_]]">
+    </cellular-info>
+  </template>
 </div>
\ No newline at end of file
diff --git a/chromeos/components/diagnostics_ui/resources/network_info.js b/chromeos/components/diagnostics_ui/resources/network_info.js
index 38ecbe8..d9d1cee 100644
--- a/chromeos/components/diagnostics_ui/resources/network_info.js
+++ b/chromeos/components/diagnostics_ui/resources/network_info.js
@@ -10,7 +10,7 @@
 
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {Network, NetworkHealthProviderInterface, NetworkType} from './diagnostics_types.js';
+import {Network, NetworkHealthProviderInterface, NetworkStateObserverInterface, NetworkStateObserverReceiver, NetworkType} from './diagnostics_types.js';
 import {getNetworkHealthProvider} from './mojo_interface_provider.js';
 
 /**
@@ -29,6 +29,12 @@
    */
   networkHealthProvider_: null,
 
+  /**
+   * Receiver responsible for observing a single active network connection.
+   * @private {?NetworkStateObserverReceiver}
+   */
+  networkStateObserverReceiver_: null,
+
   properties: {
     /** @type {string} */
     guid: {
@@ -54,11 +60,21 @@
     if (!this.guid) {
       return;
     }
-    // TODO(michaelcheco): Reset observer when the real
-    // observeNetwork implementation is added.
 
-    // Calling observeNetwork will trigger onNetworkStateChanged.
-    this.networkHealthProvider_.observeNetwork(this, this.guid);
+    if (this.networkStateObserverReceiver_) {
+      this.networkStateObserverReceiver_.$.close();
+      this.networkStateObserverReceiver_ = null;
+    }
+
+    this.networkStateObserverReceiver_ = new NetworkStateObserverReceiver(
+        /**
+         * @type {!NetworkStateObserverInterface}
+         */
+        (this));
+
+    this.networkHealthProvider_.observeNetwork(
+        this.networkStateObserverReceiver_.$.bindNewPipeAndPassRemote(),
+        this.guid);
   },
 
   /**
diff --git a/chromeos/components/diagnostics_ui/resources/network_list.js b/chromeos/components/diagnostics_ui/resources/network_list.js
index 61bf01b..3b66dcd 100644
--- a/chromeos/components/diagnostics_ui/resources/network_list.js
+++ b/chromeos/components/diagnostics_ui/resources/network_list.js
@@ -9,7 +9,7 @@
 
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {NetworkGuidInfo, NetworkHealthProviderInterface} from './diagnostics_types.js'
+import {NetworkHealthProviderInterface, NetworkListObserverInterface, NetworkListObserverReceiver} from './diagnostics_types.js'
 import {getNetworkHealthProvider} from './mojo_interface_provider.js';
 
 /**
@@ -27,6 +27,12 @@
    */
   networkHealthProvider_: null,
 
+  /**
+   * Receiver responsible for observing active network guids.
+   * @private {?NetworkListObserverReceiver}
+   */
+  networkListObserverReceiver_: null,
+
   properties: {
     /** @type {boolean} */
     isTestRunning: {
@@ -60,23 +66,35 @@
     this.observeNetworkList_();
   },
 
+  /** @override */
+  detached() {
+    this.networkListObserverReceiver_.$.close();
+  },
+
   /** @private */
   observeNetworkList_() {
     // Calling observeNetworkList will trigger onNetworkListChanged.
-    this.networkHealthProvider_.observeNetworkList(this);
+    this.networkListObserverReceiver_ = new NetworkListObserverReceiver(
+        /**
+         * @type {!NetworkListObserverInterface}
+         */
+        (this));
+
+    this.networkHealthProvider_.observeNetworkList(
+        this.networkListObserverReceiver_.$.bindNewPipeAndPassRemote());
   },
 
   /**
    * Implements NetworkListObserver.onNetworkListChanged
-   * @param {!NetworkGuidInfo} networkGuidInfo
+   * @param {!Array<string>} networkGuids
+   * @param {string} activeGuid
    */
-  onNetworkListChanged(networkGuidInfo) {
+  onNetworkListChanged(networkGuids, activeGuid) {
     // The connectivity-card is responsible for displaying the active network
     // so we need to filter out the activeGuid to avoid displaying a
     // a network-card for it.
-    this.otherNetworkGuids_ = networkGuidInfo.networkGuids.filter(
-        guid => guid !== networkGuidInfo.activeGuid);
-    this.activeGuid_ = networkGuidInfo.activeGuid || '';
+    this.otherNetworkGuids_ = networkGuids.filter(guid => guid !== activeGuid);
+    this.activeGuid_ = activeGuid;
   },
 
   /**
diff --git a/chromeos/components/diagnostics_ui/resources/wifi_info.html b/chromeos/components/diagnostics_ui/resources/wifi_info.html
index 27fe8e56..1282379 100644
--- a/chromeos/components/diagnostics_ui/resources/wifi_info.html
+++ b/chromeos/components/diagnostics_ui/resources/wifi_info.html
@@ -6,16 +6,16 @@
     value="[[network.state]]">
   </data-point>
   <data-point id="signalStrength" header="Signal strength"
-    value="[[network.networkProperties.signalStrength]]">
+    value="[[network.typeProperties.wifi.signalStrength]]">
   </data-point>
   <data-point id="frequency" header="Frequency"
-    value="[[network.networkProperties.frequency]]">
+    value="[[network.typeProperties.wifi.frequency]]">
   </data-point>
   <data-point id="bssid" header="bssid"
-    value="[[network.networkProperties.bssid]]">
+    value="[[network.typeProperties.wifi.bssid]]">
   </data-point>
   <data-point id="ssid" header="ssid"
-    value="[[network.networkProperties.ssid]]">
+    value="[[network.typeProperties.wifi.ssid]]">
   </data-point>
   <data-point id="guid" header="Guid"
     value="[[network.guid]]">
@@ -24,15 +24,16 @@
     value="[[network.macAddress]]">
   </data-point>
   <data-point id="ipAddress" header="IP Address"
-    value="[[network.ipConfigProperties.ipAddress]]">
+    value="[[network.ipConfig.ipAddress]]">
   </data-point>
   <data-point id="gateway" header="Gateway"
-    value="[[network.ipConfigProperties.gateway]]">
+    value="[[network.ipConfig.gateway]]">
   </data-point>
   <data-point id="nameServers" header="Name Servers"
-    value="[[network.ipConfigProperties.gateway]]">
+    value="[[network.ipConfig.gateway]]">
   </data-point>
+  <!-- TODO(michaelcheco): Use routing prefix to get value for subnet mask. -->
   <data-point id="subnetMask" header="Subnet Mask"
-    value="[[network.ipConfigProperties.subnetMask]]">
+    value="[[network.ipConfig.routingPrefix]]">
   </data-point>
 </div>
\ No newline at end of file
diff --git a/chromeos/components/feature_usage/feature_usage_metrics.cc b/chromeos/components/feature_usage/feature_usage_metrics.cc
index b6d619d..a3bed15c 100644
--- a/chromeos/components/feature_usage/feature_usage_metrics.cc
+++ b/chromeos/components/feature_usage/feature_usage_metrics.cc
@@ -68,10 +68,7 @@
 
 void FeatureUsageMetrics::RecordUsage(bool success) {
   DCHECK(delegate_->IsEligible());
-  // TODO(https://crbug.com/1208743) Remove this case when unit tests are fixed.
-  if (histogram_name_ != "ChromeOS.FeatureUsage.ESim") {
-    DCHECK(delegate_->IsEnabled());
-  }
+  DCHECK(delegate_->IsEnabled());
   DCHECK(start_usage_.is_null());
 #if DCHECK_IS_ON()
   last_record_usage_outcome_ = success;
diff --git a/chromeos/components/personalization_app/DEPS b/chromeos/components/personalization_app/DEPS
index ea50353..c291b1e 100644
--- a/chromeos/components/personalization_app/DEPS
+++ b/chromeos/components/personalization_app/DEPS
@@ -5,5 +5,6 @@
   "+content/public/browser",
   "+content/public/common",
   "+ui/resources/grit/webui_generated_resources.h",
+  "+ui/resources/grit/webui_generated_resources_map.h",
   "+ui/webui",
 ]
diff --git a/chromeos/components/personalization_app/resources/trusted/BUILD.gn b/chromeos/components/personalization_app/resources/trusted/BUILD.gn
index c7939ce4..703f083d 100644
--- a/chromeos/components/personalization_app/resources/trusted/BUILD.gn
+++ b/chromeos/components/personalization_app/resources/trusted/BUILD.gn
@@ -61,6 +61,9 @@
 }
 
 js_library("styles") {
+  deps = [
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+  ]
 }
 
 js_library("wallpaper_collections_element") {
diff --git a/chromeos/components/personalization_app/resources/trusted/wallpaper_images_element.js b/chromeos/components/personalization_app/resources/trusted/wallpaper_images_element.js
index 7c59e40..46581737 100644
--- a/chromeos/components/personalization_app/resources/trusted/wallpaper_images_element.js
+++ b/chromeos/components/personalization_app/resources/trusted/wallpaper_images_element.js
@@ -9,7 +9,6 @@
  * wallpaper collection id to avoid refetching data unnecessarily.
  */
 
-import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
 import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js';
 import './styles.js';
 import {assert} from '/assert.m.js';
diff --git a/chromeos/components/personalization_app/resources/untrusted/BUILD.gn b/chromeos/components/personalization_app/resources/untrusted/BUILD.gn
index bc7fede4..60cda24 100644
--- a/chromeos/components/personalization_app/resources/untrusted/BUILD.gn
+++ b/chromeos/components/personalization_app/resources/untrusted/BUILD.gn
@@ -4,36 +4,78 @@
 
 import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/grit/preprocess_if_expr.gni")
+import("//tools/polymer/html_to_js.gni")
 
-js_library("collections") {
+js_library("collections_grid") {
   deps = [
+    ":styles",
     "../../mojom:mojom_js_library_for_compile",
     "../common:constants",
+    "../common:iframe_api",
+    "//third_party/polymer/v3_0/components-chromium/iron-list:iron-list",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
   ]
 }
 
-js_library("images") {
+js_library("images_grid") {
   deps = [
+    ":styles",
     "../../mojom:mojom_js_library_for_compile",
     "../common:constants",
+    "../common:iframe_api",
+    "//third_party/polymer/v3_0/components-chromium/iron-list:iron-list",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+  ]
+}
+
+js_library("styles") {
+  deps = [
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
   ]
 }
 
 js_type_check("closure_compile") {
+  is_polymer3 = true
+  closure_flags = default_closure_args + [
+                    "browser_resolver_prefix_replacements=\"chrome-untrusted://personalization/polymer/v3_0/=../../third_party/polymer/v3_0/components-chromium/\"",
+                    "browser_resolver_prefix_replacements=\"chrome-untrusted://personalization/polymer/v3_0/polymer/polymer_bundled.min.js=../../third_party/polymer/v3_0/components-chromium/polymer/polymer_bundled.js\"",
+                  ]
   deps = [
-    ":collections",
-    ":images",
+    ":collections_grid",
+    ":images_grid",
+    ":styles",
   ]
 }
 
+html_to_js("web_components") {
+  js_files = [
+    "collections_grid.js",
+    "images_grid.js",
+  ]
+}
+
+copy("copy_static") {
+  sources = [
+    "collections.html",
+    "images.html",
+    "styles.js",
+  ]
+  outputs = [ "$target_gen_dir/{{source_file_part}}" ]
+}
+
 preprocess_if_expr("preprocess") {
-  in_folder = ".."
+  deps = [
+    ":copy_static",
+    ":web_components",
+  ]
+  in_folder = "$target_gen_dir/.."
   out_folder = "$target_gen_dir/processed"
   out_manifest = "$target_gen_dir/manifest.json"
   in_files = [
     "untrusted/collections.html",
+    "untrusted/collections_grid.js",
     "untrusted/images.html",
-    "untrusted/images.js",
-    "untrusted/collections.js",
+    "untrusted/images_grid.js",
+    "untrusted/styles.js",
   ]
 }
diff --git a/chromeos/components/personalization_app/resources/untrusted/collections.html b/chromeos/components/personalization_app/resources/untrusted/collections.html
index 0982171..4f66f6e1 100644
--- a/chromeos/components/personalization_app/resources/untrusted/collections.html
+++ b/chromeos/components/personalization_app/resources/untrusted/collections.html
@@ -2,8 +2,9 @@
 <html dir="$i18n{textdirection}" lang="$i18n{language}">
 <head>
   <meta charset="utf-8">
-  <script type="module" src="collections.js" defer></script>
+  <script type="module" src="collections_grid.js" defer></script>
 </head>
 <body>
+  <collections-grid></collections-grid>
 </body>
 </html>
diff --git a/chromeos/components/personalization_app/resources/untrusted/collections.js b/chromeos/components/personalization_app/resources/untrusted/collections.js
deleted file mode 100644
index cb51071..0000000
--- a/chromeos/components/personalization_app/resources/untrusted/collections.js
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {EventType} from '../common/constants.js';
-import {selectCollection, validateReceivedData} from '../common/iframe_api.js';
-
-/**
- * @fileoverview Responds to |SendCollectionsEvent| messages from trusted.
- * Handles user input and replies with |SelectCollectionEvent| back to trusted.
- */
-
-/** @param {Event} event */
-function onClickCollection(event) {
-  selectCollection(window.parent, event.currentTarget.dataset.id);
-}
-
-/**
- * @param {!chromeos.personalizationApp.mojom.WallpaperCollection} collection
- * @return {!HTMLDivElement}
- */
-function collectionToHtmlElement(collection) {
-  const div = /** @type {!HTMLDivElement} */ (document.createElement('div'));
-  div.setAttribute('data-id', collection.id);
-  div.onclick = onClickCollection;
-  if (collection.preview && collection.preview.url) {
-    const img = document.createElement('img');
-    img.src = collection.preview.url;
-    div.appendChild(img);
-  }
-  const p = document.createElement('p');
-  p.innerText = collection.name;
-  div.appendChild(p);
-  return div;
-}
-
-/**
- * @param {!Array<!chromeos.personalizationApp.mojom.WallpaperCollection>}
- *     collections
- */
-function onCollectionsReceived(collections) {
-  while (document.body.firstChild) {
-    document.body.removeChild(document.body.firstChild);
-  }
-  for (const collection of collections) {
-    document.body.appendChild(collectionToHtmlElement(collection));
-  }
-}
-
-/**
- * Handler for messages from trusted code. Expects only SendCollectionsEvent and
- * will error on any other event.
- * @param {!Event} message
- */
-function onMessageReceived(message) {
-  const collections = validateReceivedData(message, EventType.SEND_COLLECTIONS);
-  onCollectionsReceived(collections);
-}
-
-window.addEventListener('message', onMessageReceived);
diff --git a/chromeos/components/personalization_app/resources/untrusted/collections_grid.html b/chromeos/components/personalization_app/resources/untrusted/collections_grid.html
new file mode 100644
index 0000000..dd46394
--- /dev/null
+++ b/chromeos/components/personalization_app/resources/untrusted/collections_grid.html
@@ -0,0 +1,17 @@
+<style include="untrusted-style">
+  .collection-name {
+    bottom: 0;
+    position: absolute;
+    text-align: center;
+    width: 100%;
+  }
+</style>
+<iron-list items="[[collections_]]" grid>
+  <template>
+    <div class="photo-container" data-id$="[[item.id]]"
+        on-click="onCollectionClicked_">
+      <img src="[[item.preview.url]]">
+      <p class="collection-name">[[item.name]]</p>
+    </div>
+  </template>
+</iron-list>
diff --git a/chromeos/components/personalization_app/resources/untrusted/collections_grid.js b/chromeos/components/personalization_app/resources/untrusted/collections_grid.js
new file mode 100644
index 0000000..9d1da6d
--- /dev/null
+++ b/chromeos/components/personalization_app/resources/untrusted/collections_grid.js
@@ -0,0 +1,81 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import '//personalization/polymer/v3_0/iron-list/iron-list.js';
+import './styles.js';
+import {html, PolymerElement} from 'chrome-untrusted://personalization/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {EventType} from '../common/constants.js';
+import {selectCollection, validateReceivedData} from '../common/iframe_api.js';
+
+/**
+ * @fileoverview Responds to |SendCollectionsEvent| from trusted. Handles user
+ * input and responds with |SelectCollectionEvent| when an image is selected.
+ */
+
+class CollectionsGrid extends PolymerElement {
+  static get is() {
+    return 'collections-grid';
+  }
+
+  static get template() {
+    return html`{__html_template__}`;
+  }
+
+  static get properties() {
+    return {
+      /**
+       * @type {!Array<!chromeos.personalizationApp.mojom.WallpaperCollection>}
+       * @private
+       */
+      collections_: {
+        type: Array,
+        value: [],
+      },
+    };
+  }
+
+  constructor() {
+    super();
+    this.onMessageReceived_ = this.onMessageReceived_.bind(this);
+  }
+
+  /** @override */
+  connectedCallback() {
+    super.connectedCallback();
+    window.addEventListener('message', this.onMessageReceived_);
+  }
+
+  /** @override */
+  disconnectedCallback() {
+    super.disconnectedCallback();
+    window.removeEventListener('message', this.onMessageReceived_);
+  }
+
+  /**
+   * Handler for messages from trusted code. Expects only SendImagesEvent and
+   * will error on any other event.
+   * @param {!Event} message
+   * @private
+   */
+  onMessageReceived_(message) {
+    try {
+      this.collections_ =
+          validateReceivedData(message, EventType.SEND_COLLECTIONS);
+    } catch (e) {
+      console.warn('Invalid collections received', e);
+      this.collections_ = [];
+    }
+  }
+
+  /**
+   * Notify trusted code that a user clicked on a collection.
+   * @private
+   * @param {!Event} e
+   */
+  onCollectionClicked_(e) {
+    selectCollection(window.parent, e.currentTarget.dataset.id);
+  }
+}
+
+customElements.define(CollectionsGrid.is, CollectionsGrid);
diff --git a/chromeos/components/personalization_app/resources/untrusted/images.html b/chromeos/components/personalization_app/resources/untrusted/images.html
index 53673d73..9362aad 100644
--- a/chromeos/components/personalization_app/resources/untrusted/images.html
+++ b/chromeos/components/personalization_app/resources/untrusted/images.html
@@ -2,8 +2,9 @@
 <html dir="$i18n{textdirection}" lang="$i18n{language}">
 <head>
   <meta charset="utf-8">
-  <script type="module" src="images.js" defer></script>
+  <script type="module" src="images_grid.js" defer></script>
 </head>
 <body>
+  <images-grid></images-grid>
 </body>
 </html>
diff --git a/chromeos/components/personalization_app/resources/untrusted/images.js b/chromeos/components/personalization_app/resources/untrusted/images.js
deleted file mode 100644
index 28abe45..0000000
--- a/chromeos/components/personalization_app/resources/untrusted/images.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {EventType} from '../common/constants.js';
-import {selectImage, validateReceivedData} from '../common/iframe_api.js';
-
-/**
- * @fileoverview Responds to |SendImagesEvent| from trusted. Handles user input
- * and responds with |SelectImageEvent| when an image is selected.
- */
-
-/** @param {Event} event */
-function onClickImage(event) {
-  // This throws if assetId is not a valid BigInt.
-  const assetId = BigInt(event.currentTarget.dataset.assetId);
-  selectImage(window.parent, assetId);
-}
-
-/**
- * @param {!chromeos.personalizationApp.mojom.WallpaperImage} image
- * @returns {!HTMLImageElement}
- */
-function imageToHtml(image) {
-  const img = /** @type {!HTMLImageElement} */ (document.createElement('img'));
-  img.src = image.url.url;
-  img.dataset.assetId = image.assetId;
-  img.onclick = onClickImage;
-  return img;
-}
-
-/** @param {!Array<!chromeos.personalizationApp.mojom.WallpaperImage>} images */
-function onImagesReceived(images) {
-  while (document.body.firstChild) {
-    document.body.removeChild(document.body.firstChild);
-  }
-  for (const image of images) {
-    document.body.appendChild(imageToHtml(image));
-  }
-}
-
-/**
- * Handler for messages from trusted code. Expects only SendImagesEvent and will
- * error on any other event.
- * @param {!Event} message
- */
-function onMessageReceived(message) {
-  const images = validateReceivedData(message, EventType.SEND_IMAGES);
-  onImagesReceived(images);
-}
-
-window.addEventListener('message', onMessageReceived);
diff --git a/chromeos/components/personalization_app/resources/untrusted/images_grid.html b/chromeos/components/personalization_app/resources/untrusted/images_grid.html
new file mode 100644
index 0000000..a40b0b7
--- /dev/null
+++ b/chromeos/components/personalization_app/resources/untrusted/images_grid.html
@@ -0,0 +1,10 @@
+<style include="untrusted-style">
+</style>
+<iron-list grid items="[[images_]]">
+  <template>
+    <div class="photo-container">
+      <img data-id$="[[item.assetId]]" src="[[item.url.url]]"
+        on-click="onImageClicked_">
+    </div>
+  </template>
+</iron-list>
diff --git a/chromeos/components/personalization_app/resources/untrusted/images_grid.js b/chromeos/components/personalization_app/resources/untrusted/images_grid.js
new file mode 100644
index 0000000..4cf02732
--- /dev/null
+++ b/chromeos/components/personalization_app/resources/untrusted/images_grid.js
@@ -0,0 +1,81 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome-untrusted://personalization/polymer/v3_0/iron-list/iron-list.js';
+import './styles.js';
+import {html, PolymerElement} from 'chrome-untrusted://personalization/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {EventType} from '../common/constants.js';
+import {selectImage, validateReceivedData} from '../common/iframe_api.js';
+
+/**
+ * @fileoverview Responds to |SendImagesEvent| from trusted. Handles user input
+ * and responds with |SelectImageEvent| when an image is selected.
+ */
+
+class ImagesGrid extends PolymerElement {
+  static get is() {
+    return 'images-grid';
+  }
+
+  static get template() {
+    return html`{__html_template__}`;
+  }
+
+  static get properties() {
+    return {
+      /**
+       * @type {!Array<!chromeos.personalizationApp.mojom.WallpaperImage>}
+       * @private
+       */
+      images_: {
+        type: Array,
+        value: [],
+      },
+    };
+  }
+
+  constructor() {
+    super();
+    this.onMessageReceived_ = this.onMessageReceived_.bind(this);
+  }
+
+  /** @override */
+  connectedCallback() {
+    super.connectedCallback();
+    window.addEventListener('message', this.onMessageReceived_);
+  }
+
+  /** @override */
+  disconnectedCallback() {
+    super.disconnectedCallback();
+    window.removeEventListener('message', this.onMessageReceived_);
+  }
+
+  /**
+   * Handler for messages from trusted code. Expects only SendImagesEvent and
+   * will error on any other event.
+   * @param {!Event} message
+   * @private
+   */
+  onMessageReceived_(message) {
+    try {
+      this.images_ = validateReceivedData(message, EventType.SEND_IMAGES);
+    } catch (e) {
+      console.warn('Invalid images received', e);
+      this.images_ = [];
+    }
+  }
+
+  /**
+   * Notify trusted code that a user clicked on an image.
+   * @private
+   * @param {!Event} e
+   */
+  onImageClicked_(e) {
+    const img = e.currentTarget;
+    selectImage(window.parent, BigInt(img.dataset.id));
+  }
+}
+
+customElements.define(ImagesGrid.is, ImagesGrid);
diff --git a/chromeos/components/personalization_app/resources/untrusted/styles.js b/chromeos/components/personalization_app/resources/untrusted/styles.js
new file mode 100644
index 0000000..443db54
--- /dev/null
+++ b/chromeos/components/personalization_app/resources/untrusted/styles.js
@@ -0,0 +1,23 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import '//personalization/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+const styles = document.createElement('dom-module');
+
+styles.innerHTML = `<template>
+    <style>
+        .photo-container {
+            height: 128px;
+            width: 128px;
+        }
+        .photo-container > img {
+            height: 100%;
+            object-fit: contain;
+            width: 100%;
+        }
+    </style>
+  </template>`;
+
+styles.register('untrusted-style');
diff --git a/chromeos/components/personalization_app/untrusted_personalization_app_ui_config.cc b/chromeos/components/personalization_app/untrusted_personalization_app_ui_config.cc
index c726515a..b95f461b 100644
--- a/chromeos/components/personalization_app/untrusted_personalization_app_ui_config.cc
+++ b/chromeos/components/personalization_app/untrusted_personalization_app_ui_config.cc
@@ -16,6 +16,7 @@
 #include "content/public/common/url_constants.h"
 #include "services/network/public/mojom/content_security_policy.mojom-shared.h"
 #include "ui/resources/grit/webui_generated_resources.h"
+#include "ui/resources/grit/webui_generated_resources_map.h"
 #include "url/gurl.h"
 
 namespace chromeos {
@@ -43,6 +44,11 @@
     // trusted and untrusted context.
     source->AddResourcePath("assert.m.js", IDR_WEBUI_JS_ASSERT_M_JS);
 
+    // Add WebUI resources like polymer and iron-list so that it is accessible
+    // inside untrusted iframe.
+    source->AddResourcePaths(base::make_span(kWebuiGeneratedResources,
+                                             kWebuiGeneratedResourcesSize));
+
     source->AddFrameAncestor(GURL(kChromeUIPersonalizationAppURL));
 
     // Allow images only from this url.
@@ -53,6 +59,10 @@
     source->OverrideContentSecurityPolicy(
         network::mojom::CSPDirectiveName::ScriptSrc, "script-src 'self';");
 
+    source->OverrideContentSecurityPolicy(
+        network::mojom::CSPDirectiveName::StyleSrc,
+        "style-src 'self' 'unsafe-inline';");
+
 #if !DCHECK_IS_ON()
     // When DCHECKs are off and a user goes to an invalid url serve a default
     // page to avoid crashing. We crash when DCHECKs are on to make it clearer
@@ -61,6 +71,10 @@
         IDR_CHROMEOS_PERSONALIZATION_APP_UNTRUSTED_COLLECTIONS_HTML);
 #endif  // !DCHECK_IS_ON()
 
+    // TODO(crbug/1169829) set up trusted types properly to allow Polymer to
+    // write html.
+    source->DisableTrustedTypesCSP();
+
     auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
     content::WebUIDataSource::Add(browser_context, source.release());
   }
diff --git a/chromeos/network/cellular_metrics_logger.cc b/chromeos/network/cellular_metrics_logger.cc
index bb9c9c8..00a00398 100644
--- a/chromeos/network/cellular_metrics_logger.cc
+++ b/chromeos/network/cellular_metrics_logger.cc
@@ -788,7 +788,12 @@
                                  usage_duration);
         esim_feature_usage_metrics_->StopUsage();
       }
-      if (usage != CellularUsage::kNotConnected)
+
+      bool was_disconnected =
+          !last_esim_cellular_usage_.has_value() ||
+          last_esim_cellular_usage_ == CellularUsage::kNotConnected;
+
+      if (was_disconnected && usage != CellularUsage::kNotConnected)
         esim_feature_usage_metrics_->RecordUsage(/*success=*/true);
 
       if (usage == CellularUsage::kConnectedAndOnlyNetwork)
diff --git a/chromeos/network/cellular_metrics_logger_unittest.cc b/chromeos/network/cellular_metrics_logger_unittest.cc
index 9dae7ed..11824dc 100644
--- a/chromeos/network/cellular_metrics_logger_unittest.cc
+++ b/chromeos/network/cellular_metrics_logger_unittest.cc
@@ -212,37 +212,6 @@
   DISALLOW_COPY_AND_ASSIGN(CellularMetricsLoggerTest);
 };
 
-TEST_F(CellularMetricsLoggerTest, DuplicateCellularServiceGuids) {
-  InitCellular("guid", "guid");
-
-  SetUpMetricsLogger();
-  const base::Value kFailure(shill::kStateFailure);
-  const base::Value kAssocStateValue(shill::kStateAssociation);
-
-  // Set cellular networks to connecting state.
-  service_client_test()->SetServiceProperty(
-      kTestPSimCellularServicePath, shill::kStateProperty, kAssocStateValue);
-  service_client_test()->SetServiceProperty(
-      kTestESimCellularServicePath, shill::kStateProperty, kAssocStateValue);
-  base::RunLoop().RunUntilIdle();
-
-  // Set cellular networks to connected state.
-  service_client_test()->SetServiceProperty(kTestPSimCellularServicePath,
-                                            shill::kStateProperty,
-                                            base::Value(shill::kStateOnline));
-  service_client_test()->SetServiceProperty(kTestESimCellularServicePath,
-                                            shill::kStateProperty,
-                                            base::Value(shill::kStateOnline));
-  base::RunLoop().RunUntilIdle();
-
-  // Only the PSim histogram is logged to because it was the first to be
-  // connected to.
-  histogram_tester_->ExpectTotalCount(
-      CellularMetricsLogger::kPSimAllConnectionResultHistogram, 1);
-  histogram_tester_->ExpectTotalCount(
-      CellularMetricsLogger::kESimAllConnectionResultHistogram, 0);
-}
-
 TEST_F(CellularMetricsLoggerTest, ActiveProfileExists) {
   AddESimProfile(hermes::profile::State::kActive, kTestESimCellularServicePath);
   SetUpMetricsLogger();
@@ -296,6 +265,8 @@
   static const base::Value kTestOnlineStateValue(shill::kStateOnline);
   static const base::Value kTestIdleStateValue(shill::kStateIdle);
 
+  AddESimProfile(hermes::profile::State::kActive, kTestESimCellularServicePath);
+
   // Should not log state until after timeout.
   service_client_test()->SetServiceProperty(
       kTestEthServicePath, shill::kStateProperty, kTestOnlineStateValue);
@@ -323,6 +294,12 @@
       kESimUsageCountHistogram,
       CellularMetricsLogger::CellularUsage::kConnectedWithOtherNetwork, 0);
 
+  histogram_tester_->ExpectBucketCount(
+      kESimFeatureUsageMetric,
+      static_cast<int>(
+          feature_usage::FeatureUsageMetrics::Event::kUsedWithSuccess),
+      0);
+
   // PSim Cellular connected as only network.
   service_client_test()->SetServiceProperty(
       kTestEthServicePath, shill::kStateProperty, kTestIdleStateValue);
@@ -334,6 +311,12 @@
       kESimUsageCountHistogram,
       CellularMetricsLogger::CellularUsage::kConnectedAndOnlyNetwork, 0);
 
+  histogram_tester_->ExpectBucketCount(
+      kESimFeatureUsageMetric,
+      static_cast<int>(
+          feature_usage::FeatureUsageMetrics::Event::kUsedWithSuccess),
+      0);
+
   // After |kTimeSpentOnlinePSim|, PSim Cellular becomes not connected.
   const base::TimeDelta kTimeSpentOnlinePSim =
       base::TimeDelta::FromSeconds(123);
@@ -560,6 +543,8 @@
   const base::Value kAssocStateValue(shill::kStateAssociation);
   ResetHistogramTester();
 
+  AddESimProfile(hermes::profile::State::kActive, kTestESimCellularServicePath);
+
   // Set cellular networks to connecting state.
   service_client_test()->SetServiceProperty(
       kTestPSimCellularServicePath, shill::kStateProperty, kAssocStateValue);
@@ -682,6 +667,8 @@
   ResetHistogramTester();
   base::RunLoop().RunUntilIdle();
 
+  AddESimProfile(hermes::profile::State::kActive, kTestESimCellularServicePath);
+
   // Set cellular networks to connecting state.
   service_client_test()->SetServiceProperty(
       kTestPSimCellularServicePath, shill::kStateProperty,
@@ -782,6 +769,8 @@
   const base::Value kOnlineStateValue(shill::kStateOnline);
   const base::Value kAssocStateValue(shill::kStateAssociation);
 
+  AddESimProfile(hermes::profile::State::kActive, kTestESimCellularServicePath);
+
   // Should not log connection time when not activated.
   service_client_test()->SetServiceProperty(
       kTestPSimCellularServicePath, shill::kStateProperty, kAssocStateValue);
@@ -829,6 +818,8 @@
   base::Value kOnlineStateValue(shill::kStateOnline);
   base::Value kIdleStateValue(shill::kStateIdle);
 
+  AddESimProfile(hermes::profile::State::kActive, kTestESimCellularServicePath);
+
   // Should log connected state.
   service_client_test()->SetServiceProperty(
       kTestPSimCellularServicePath, shill::kStateProperty, kOnlineStateValue);
diff --git a/chromeos/network/network_connection_handler.cc b/chromeos/network/network_connection_handler.cc
index e29753fa..073e7c672 100644
--- a/chromeos/network/network_connection_handler.cc
+++ b/chromeos/network/network_connection_handler.cc
@@ -70,6 +70,9 @@
 const char NetworkConnectionHandler::kErrorESimProfileIssue[] =
     "esim-profile-issue";
 const char NetworkConnectionHandler::kErrorSimLocked[] = "sim-locked";
+const char NetworkConnectionHandler::kErrorCellularDeviceBusy[] =
+    "cellular-device-busy";
+const char NetworkConnectionHandler::kErrorConnectTimeout[] = "connect-timeout";
 
 NetworkConnectionHandler::NetworkConnectionHandler()
     : tether_delegate_(nullptr) {}
diff --git a/chromeos/network/network_connection_handler.h b/chromeos/network/network_connection_handler.h
index 810b03a..ac99fb2 100644
--- a/chromeos/network/network_connection_handler.h
+++ b/chromeos/network/network_connection_handler.h
@@ -123,6 +123,12 @@
   // The SIM must be unlocked before a connection can succeed.
   static const char kErrorSimLocked[];
 
+  // Connect failed because cellular device is busy.
+  static const char kErrorCellularDeviceBusy[];
+
+  // Connect failed because connect request timed out.
+  static const char kErrorConnectTimeout[];
+
   class COMPONENT_EXPORT(CHROMEOS_NETWORK) TetherDelegate {
    public:
     using StringErrorCallback =
diff --git a/chromeos/network/network_connection_handler_impl.cc b/chromeos/network/network_connection_handler_impl.cc
index 0502dbb..6d06848 100644
--- a/chromeos/network/network_connection_handler_impl.cc
+++ b/chromeos/network/network_connection_handler_impl.cc
@@ -48,6 +48,10 @@
 constexpr base::TimeDelta kMaxCertLoadTimeSeconds =
     base::TimeDelta::FromSeconds(15);
 
+// Timeout after which a pending cellular connect request is considered failed.
+constexpr base::TimeDelta kCellularConnectTimeout =
+    base::TimeDelta::FromSeconds(150);
+
 bool IsAuthenticationError(const std::string& error) {
   return (error == shill::kErrorBadWEPKey ||
           error == shill::kErrorPppAuthFailed ||
@@ -326,6 +330,15 @@
         return;
       }
 
+      // Reject request if a cellular connect request is already in progress.
+      // This prevents complexity with switching slots when one is already in
+      // progress.
+      if (HasPendingCellularRequest()) {
+        InvokeConnectErrorCallback(service_path, std::move(error_callback),
+                                   kErrorCellularDeviceBusy);
+        return;
+      }
+
       const DeviceState* cellular_device =
           network_state_handler_->GetDeviceState(network->device_path());
 
@@ -365,10 +378,10 @@
   }
 
   // All synchronous checks passed, add |service_path| to connecting list.
-  pending_requests_.emplace(
-      service_path,
-      ConnectRequest(mode, service_path, profile_path,
-                     std::move(success_callback), std::move(error_callback)));
+  pending_requests_.emplace(service_path, std::make_unique<ConnectRequest>(
+                                              mode, service_path, profile_path,
+                                              std::move(success_callback),
+                                              std::move(error_callback)));
 
   // Indicate that a connect was requested. This will be updated by
   // NetworkStateHandler when the connection state changes, or cleared if
@@ -376,6 +389,8 @@
   network_state_handler_->SetNetworkConnectRequested(service_path, true);
 
   if (cellular_connection_handler_ && !cellular_network_iccid.empty()) {
+    StartConnectTimer(service_path, kCellularConnectTimeout);
+
     // Cellular networks require special handling before Shill can initiate a
     // connection. Prepare the network for connection before proceeding.
     cellular_connection_handler_->PrepareExistingCellularNetworkForConnection(
@@ -479,9 +494,9 @@
 
   // Remove the old map entry from the previous service path and add a new
   // mapping with the updated service path.
-  ConnectRequest request = std::move(it->second);
-  request.service_path = new_service_path;
-  request.profile_path = profile_path;
+  std::unique_ptr<ConnectRequest> request = std::move(it->second);
+  request->service_path = new_service_path;
+  request->profile_path = profile_path;
   pending_requests_.erase(it);
   pending_requests_.emplace(new_service_path, std::move(request));
 
@@ -497,9 +512,21 @@
 NetworkConnectionHandlerImpl::ConnectRequest*
 NetworkConnectionHandlerImpl::GetPendingRequest(
     const std::string& service_path) {
-  std::map<std::string, ConnectRequest>::iterator iter =
+  std::map<std::string, std::unique_ptr<ConnectRequest>>::iterator iter =
       pending_requests_.find(service_path);
-  return iter != pending_requests_.end() ? &(iter->second) : nullptr;
+  return iter != pending_requests_.end() ? iter->second.get() : nullptr;
+}
+
+bool NetworkConnectionHandlerImpl::HasPendingCellularRequest() const {
+  auto iter = std::find_if(
+      pending_requests_.begin(), pending_requests_.end(),
+      [&](const std::pair<const std::string, std::unique_ptr<ConnectRequest>>&
+              pair) {
+        const NetworkState* network =
+            network_state_handler_->GetNetworkState(pair.first);
+        return network && network->Matches(NetworkTypePattern::Cellular());
+      });
+  return iter != pending_requests_.end();
 }
 
 void NetworkConnectionHandlerImpl::OnPrepareCellularNetworkForConnectionFailure(
@@ -519,6 +546,29 @@
                              error_name);
 }
 
+void NetworkConnectionHandlerImpl::StartConnectTimer(
+    const std::string& service_path,
+    base::TimeDelta timeout) {
+  ConnectRequest* request = GetPendingRequest(service_path);
+  if (!request)
+    return;
+
+  request->timer = std::make_unique<base::OneShotTimer>();
+  request->timer->Start(
+      FROM_HERE, timeout,
+      base::BindOnce(&NetworkConnectionHandlerImpl::OnConnectTimeout,
+                     AsWeakPtr(), request));
+}
+
+void NetworkConnectionHandlerImpl::OnConnectTimeout(ConnectRequest* request) {
+  // Copy service path since request will be deleted in ClearPendingRequest.
+  std::string service_path = request->service_path;
+  NET_LOG(EVENT) << "Connect request timed out for path=" << service_path;
+  InvokeConnectErrorCallback(service_path, std::move(request->error_callback),
+                             kErrorConnectTimeout);
+  ClearPendingRequest(service_path);
+}
+
 // ConnectToNetwork implementation
 
 void NetworkConnectionHandlerImpl::VerifyConfiguredAndConnect(
@@ -969,7 +1019,7 @@
 }
 
 void NetworkConnectionHandlerImpl::CheckAllPendingRequests() {
-  for (std::map<std::string, ConnectRequest>::iterator iter =
+  for (std::map<std::string, std::unique_ptr<ConnectRequest>>::iterator iter =
            pending_requests_.begin();
        iter != pending_requests_.end(); ++iter) {
     CheckPendingRequest(iter->first);
diff --git a/chromeos/network/network_connection_handler_impl.h b/chromeos/network/network_connection_handler_impl.h
index baad8884..31ba6feb 100644
--- a/chromeos/network/network_connection_handler_impl.h
+++ b/chromeos/network/network_connection_handler_impl.h
@@ -6,6 +6,7 @@
 #define CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_IMPL_H_
 
 #include "base/component_export.h"
+#include "base/timer/timer.h"
 #include "chromeos/dbus/dbus_method_call_status.h"
 #include "chromeos/network/network_cert_loader.h"
 #include "chromeos/network/network_connection_handler.h"
@@ -73,16 +74,22 @@
     ConnectState connect_state;
     base::OnceClosure success_callback;
     network_handler::ErrorCallback error_callback;
+    std::unique_ptr<base::OneShotTimer> timer;
   };
 
   bool HasConnectingNetwork(const std::string& service_path);
 
   ConnectRequest* GetPendingRequest(const std::string& service_path);
+  bool HasPendingCellularRequest() const;
 
   void OnPrepareCellularNetworkForConnectionFailure(
       const std::string& service_path,
       const std::string& error_name);
 
+  void StartConnectTimer(const std::string& service_path,
+                         base::TimeDelta timeout);
+  void OnConnectTimeout(ConnectRequest* service_path);
+
   // Callback from Shill.Service.GetProperties. Parses |properties| to verify
   // whether or not the network appears to be configured. If configured,
   // attempts a connection, otherwise invokes error_callback from
@@ -152,7 +159,7 @@
 
   // Map of pending connect requests, used to prevent repeated attempts while
   // waiting for Shill and to trigger callbacks on eventual success or failure.
-  std::map<std::string, ConnectRequest> pending_requests_;
+  std::map<std::string, std::unique_ptr<ConnectRequest>> pending_requests_;
   std::unique_ptr<ConnectRequest> queued_connect_;
 
   // Track certificate loading state.
diff --git a/chromeos/network/network_connection_handler_impl_unittest.cc b/chromeos/network/network_connection_handler_impl_unittest.cc
index 5d14a7d..d56cd34 100644
--- a/chromeos/network/network_connection_handler_impl_unittest.cc
+++ b/chromeos/network/network_connection_handler_impl_unittest.cc
@@ -62,6 +62,9 @@
 const char kTestEuiccPath[] = "/org/chromium/Hermes/Euicc/1";
 const char kTestEid[] = "123456789012345678901234567890123";
 
+const char kTestCellularServicePath2[] = "cellular_service_path_2";
+const char kTestIccid2[] = "9876543210987654321";
+
 class TestNetworkConnectionObserver : public NetworkConnectionObserver {
  public:
   TestNetworkConnectionObserver() = default;
@@ -83,6 +86,7 @@
 
   void DisconnectRequested(const std::string& service_path) override {
     requests_.insert(service_path);
+    disconnect_requests_.insert(service_path);
   }
 
   bool GetRequested(const std::string& service_path) {
@@ -96,7 +100,12 @@
     return iter->second;
   }
 
+  const std::set<std::string>& disconnect_requests() {
+    return disconnect_requests_;
+  }
+
  private:
+  std::set<std::string> disconnect_requests_;
   std::set<std::string> requests_;
   std::map<std::string, std::string> results_;
 
@@ -219,6 +228,10 @@
   }
 
   void TearDown() override {
+    helper_.hermes_euicc_test()->SetInteractiveDelay(
+        base::TimeDelta::FromSeconds(0));
+    helper_.manager_test()->SetInteractiveDelay(
+        base::TimeDelta::FromSeconds(0));
     managed_config_handler_.reset();
     network_profile_handler_.reset();
     network_connection_handler_->RemoveObserver(
@@ -361,10 +374,10 @@
         HermesResponseStatus::kErrorUnknown);
   }
 
-  void SetCellularServiceConnectable() {
-    helper_.service_test()->SetServiceProperty(kTestCellularServicePath,
-                                               shill::kConnectableProperty,
-                                               base::Value(true));
+  void SetCellularServiceConnectable(
+      const std::string& service_path = kTestCellularServicePath) {
+    helper_.service_test()->SetServiceProperty(
+        service_path, shill::kConnectableProperty, base::Value(true));
     base::RunLoop().RunUntilIdle();
   }
 
@@ -436,6 +449,25 @@
     base::RunLoop().RunUntilIdle();
   }
 
+  void AddCellularService(
+      bool has_eid,
+      const std::string& service_path = kTestCellularServicePath,
+      const std::string& iccid = kTestIccid) {
+    // Add idle, non-connectable network.
+    helper_.service_test()->AddService(service_path, kTestCellularGuid,
+                                       kTestCellularName, shill::kTypeCellular,
+                                       shill::kStateIdle, /*visible=*/true);
+
+    if (has_eid) {
+      helper_.service_test()->SetServiceProperty(
+          service_path, shill::kEidProperty, base::Value(kTestEid));
+    }
+
+    helper_.service_test()->SetServiceProperty(
+        service_path, shill::kIccidProperty, base::Value(iccid));
+    base::RunLoop().RunUntilIdle();
+  }
+
   // Used when testing a code that accesses NetworkHandler::Get() directly (e.g.
   // when checking if VPN is disabled by policy when attempting to connect to a
   // VPN network). NetworkStateTestHelper can not be used here. That's because
@@ -479,23 +511,6 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  void AddCellularService(bool has_eid) {
-    // Add idle, non-connectable network.
-    helper_.service_test()->AddService(
-        kTestCellularServicePath, kTestCellularGuid, kTestCellularName,
-        shill::kTypeCellular, shill::kStateIdle, /*visible=*/true);
-
-    if (has_eid) {
-      helper_.service_test()->SetServiceProperty(
-          kTestCellularServicePath, shill::kEidProperty, base::Value(kTestEid));
-    }
-
-    helper_.service_test()->SetServiceProperty(kTestCellularServicePath,
-                                               shill::kIccidProperty,
-                                               base::Value(kTestIccid));
-    base::RunLoop().RunUntilIdle();
-  }
-
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
   NetworkStateTestHelper helper_{false /* use_default_devices_and_services */};
@@ -1171,4 +1186,61 @@
             GetResultAndReset());
 }
 
+TEST_F(NetworkConnectionHandlerImplTest, MultipleCellularConnect) {
+  Init();
+  AddCellularServiceWithESimProfile();
+  AddCellularService(/*has_eid=*/false, kTestCellularServicePath2, kTestIccid2);
+
+  // Delay hermes operation so that first connect will be waiting in
+  // CellularConnectionHandler.
+  HermesEuiccClient::Get()->GetTestInterface()->SetInteractiveDelay(
+      base::TimeDelta::FromSeconds(10));
+  Connect(kTestCellularServicePath);
+  Connect(kTestCellularServicePath2);
+
+  // Verify that second connect request fails with device busy.
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(NetworkConnectionHandler::kErrorCellularDeviceBusy,
+            GetResultAndReset());
+}
+
+TEST_F(NetworkConnectionHandlerImplTest, CellularConnectTimeout) {
+  const base::TimeDelta kCellularConnectTimeout =
+      base::TimeDelta::FromSeconds(150);
+  Init();
+  AddNonConnectablePSimService();
+  SetCellularServiceConnectable(kTestCellularServicePath);
+
+  ShillManagerClient::Get()->GetTestInterface()->SetInteractiveDelay(
+      base::TimeDelta::FromSeconds(200));
+  Connect(kTestCellularServicePath);
+  AdvanceClock(kCellularConnectTimeout);
+  EXPECT_EQ(NetworkConnectionHandler::kErrorConnectTimeout,
+            GetResultAndReset());
+}
+
+TEST_F(NetworkConnectionHandlerImplTest,
+       CellularConnectTimeout_StubToShillBacked) {
+  const base::TimeDelta kCellularConnectTimeout =
+      base::TimeDelta::FromSeconds(150);
+  Init();
+  AddCellularServiceWithESimProfile(/*is_stub=*/true);
+
+  // Connect to a stub path. Internally, this should wait until a connectable
+  // Shill-backed service is created.
+  Connect(GenerateStubCellularServicePath(kTestIccid));
+
+  // Now, Create a shill backed service for the same network.
+  ShillManagerClient::Get()->GetTestInterface()->SetInteractiveDelay(
+      base::TimeDelta::FromSeconds(200));
+  AddNonConnectableESimService();
+  SetCellularServiceConnectable();
+
+  // Verify that connection timesout properly even when network path
+  // transitioned.
+  AdvanceClock(kCellularConnectTimeout);
+  EXPECT_EQ(NetworkConnectionHandler::kErrorConnectTimeout,
+            GetResultAndReset());
+}
+
 }  // namespace chromeos
diff --git a/components/autofill/core/browser/autofill_browser_util.cc b/components/autofill/core/browser/autofill_browser_util.cc
index eafd2cc..02eadaa 100644
--- a/components/autofill/core/browser/autofill_browser_util.cc
+++ b/components/autofill/core/browser/autofill_browser_util.cc
@@ -5,6 +5,7 @@
 #include "components/autofill/core/browser/autofill_browser_util.h"
 
 #include "components/autofill/core/browser/autofill_client.h"
+#include "components/autofill/core/browser/form_structure.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
 
 namespace {
@@ -44,4 +45,20 @@
   return !IsFormOrClientNonSecure(client, form);
 }
 
+bool IsCompleteCreditCardFormIncludingCvcField(
+    const FormStructure& form_structure) {
+  // If card number field or expiration date field is not detected, return
+  // false.
+  if (!form_structure.IsCompleteCreditCardForm())
+    return false;
+
+  // If CVC field is detected, then all requirements are met, otherwise return
+  // false.
+  for (auto& field : form_structure) {
+    if (field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE)
+      return true;
+  }
+  return false;
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_browser_util.h b/components/autofill/core/browser/autofill_browser_util.h
index e03b144..aaea3c7 100644
--- a/components/autofill/core/browser/autofill_browser_util.h
+++ b/components/autofill/core/browser/autofill_browser_util.h
@@ -12,6 +12,7 @@
 namespace autofill {
 
 class AutofillClient;
+class FormStructure;
 
 // Checks whether a given form is considered insecure (by origin or action).
 bool IsFormOrClientNonSecure(const AutofillClient* client,
@@ -26,6 +27,11 @@
 bool ShouldAllowCreditCardFallbacks(const AutofillClient* client,
                                     const FormData& form);
 
+// Returns whether the form is a complete credit card form with card number
+// field, card expiration date field and card CVC field detected.
+bool IsCompleteCreditCardFormIncludingCvcField(
+    const FormStructure& form_structure);
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_BROWSER_UTIL_H_
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index 0590f5d4..3fdd060 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -282,6 +282,8 @@
 #else
     NOTREACHED();
 #endif
+  } else if (identifier == POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY) {
+    // TODO(crbug.com/1196021): Add handling logic.
   } else {
     if (identifier > 0) {  // Denotes an Autofill suggestion.
       AutofillMetrics::LogAutofillSuggestionAcceptedIndex(
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc
index 5f5ad07..f8df0f64 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator.cc
+++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -7,9 +7,11 @@
 #include "components/autofill/core/browser/autofill_suggestion_generator.h"
 
 #include "build/build_config.h"
+#include "components/autofill/core/browser/autofill_browser_util.h"
 #include "components/autofill/core/browser/autofill_client.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
 #include "components/autofill/core/browser/data_model/credit_card.h"
+#include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/payments/autofill_offer_manager.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/ui/suggestion.h"
@@ -50,6 +52,7 @@
 
 std::vector<Suggestion>
 AutofillSuggestionGenerator::GetSuggestionsForCreditCards(
+    const FormStructure& form_structure,
     const FormFieldData& field,
     const AutofillType& type,
     const std::string& app_locale) {
@@ -86,73 +89,23 @@
             base::i18n::ToLower(creditcard_field_value), field_contents_lower,
             type, credit_card->record_type() == CreditCard::MASKED_SERVER_CARD,
             &prefix_matched_suggestion)) {
-      // Make a new suggestion.
-      suggestions.emplace_back(Suggestion());
-      Suggestion* suggestion = &suggestions.back();
-
-      suggestion->value = credit_card->GetInfo(type, app_locale);
-      suggestion->icon = credit_card->CardIconStringForAutofillSuggestion();
-      suggestion->backend_id = credit_card->guid();
-      suggestion->match = prefix_matched_suggestion
-                              ? Suggestion::PREFIX_MATCH
-                              : Suggestion::SUBSTRING_MATCH;
-
-      // Get the nickname for the card suggestion, which may not be the same as
-      // the card's nickname if there are duplicates of the card on file.
-      std::u16string suggestion_nickname =
-          GetDisplayNicknameForCreditCard(*credit_card);
-
-      // If the value is the card number, the label is the expiration date.
-      // Otherwise the label is the card number, or if that is empty the
-      // cardholder name. The label should never repeat the value.
-      if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
-        suggestion->value = credit_card->CardIdentifierStringForAutofillDisplay(
-            suggestion_nickname);
-
-#if defined(OS_ANDROID) || defined(OS_IOS)
-        suggestion->label = credit_card->GetInfo(
-            AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale);
-#else
-        suggestion->label = credit_card->DescriptiveExpiration(app_locale);
-#endif  // defined(OS_ANDROID) || defined(OS_IOS)
-
-      } else if (credit_card->number().empty()) {
-        DCHECK_EQ(credit_card->record_type(), CreditCard::LOCAL_CARD);
-        if (credit_card->HasNonEmptyValidNickname()) {
-          suggestion->label = credit_card->nickname();
-        } else if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) {
-          suggestion->label = credit_card->GetInfo(
-              AutofillType(CREDIT_CARD_NAME_FULL), app_locale);
-        }
-      } else {
-#if defined(OS_ANDROID)
-        // On Android devices, the label is formatted as
-        // "Nickname/Network  ••••1234" when the keyboard accessory experiment
-        // is disabled and as "••••1234" when it's enabled.
-        suggestion->label =
-            base::FeatureList::IsEnabled(features::kAutofillKeyboardAccessory)
-                ? credit_card->ObfuscatedLastFourDigits()
-                : credit_card->CardIdentifierStringForAutofillDisplay(
-                      suggestion_nickname);
-#elif defined(OS_IOS)
-        // E.g. "••••1234"".
-        suggestion->label = credit_card->ObfuscatedLastFourDigits();
-#else
-        // E.g. "Nickname/Network  ••••1234, expires on 01/25".
-        suggestion->label =
-            credit_card->CardIdentifierStringAndDescriptiveExpiration(
-                app_locale);
-#endif
+      // If the card is enrolled in virtual card, add a new suggestion option
+      // for it above its original suggestion.
+      if (base::FeatureList::IsEnabled(
+              features::kAutofillEnableMerchantBoundVirtualCards) &&
+          credit_card->virtual_card_enrollment_state() ==
+              CreditCard::ENROLLED &&
+          (!base::FeatureList::IsEnabled(
+               features::kAutofillSuggestVirtualCardsOnlyOnFullFormDetection) ||
+           IsCompleteCreditCardFormIncludingCvcField(form_structure))) {
+        suggestions.push_back(CreateCreditCardSuggestion(
+            *credit_card, type, prefix_matched_suggestion,
+            /*virtual_card_option=*/true, app_locale));
       }
-#if defined(OS_ANDROID)
-      // Set the IPH feature in order to show the IPH bubble when the virtual
-      // card is presented in the keyboard accessory.
-      if (credit_card->record_type() == CreditCard::VIRTUAL_CARD) {
-        suggestion->feature_for_iph =
-            feature_engagement::kIPHKeyboardAccessoryPaymentVirtualCardFeature
-                .name;
-      }
-#endif  // OS_ANDROID
+
+      suggestions.push_back(CreateCreditCardSuggestion(
+          *credit_card, type, prefix_matched_suggestion,
+          /*virtual_card_option=*/false, app_locale));
     }
   }
 
@@ -217,4 +170,81 @@
   return card.nickname();
 }
 
+Suggestion AutofillSuggestionGenerator::CreateCreditCardSuggestion(
+    const CreditCard& credit_card,
+    const AutofillType& type,
+    bool prefix_matched_suggestion,
+    bool virtual_card_option,
+    const std::string& app_locale) const {
+  Suggestion suggestion;
+
+  suggestion.value = credit_card.GetInfo(type, app_locale);
+  suggestion.icon = credit_card.CardIconStringForAutofillSuggestion();
+  suggestion.backend_id = credit_card.guid();
+  suggestion.match = prefix_matched_suggestion ? Suggestion::PREFIX_MATCH
+                                               : Suggestion::SUBSTRING_MATCH;
+
+  // Get the nickname for the card suggestion, which may not be the same as
+  // the card's nickname if there are duplicates of the card on file.
+  std::u16string suggestion_nickname =
+      GetDisplayNicknameForCreditCard(credit_card);
+
+  // If the value is the card number, the label is the expiration date.
+  // Otherwise the label is the card number, or if that is empty the
+  // cardholder name. The label should never repeat the value.
+  if (type.GetStorableType() == CREDIT_CARD_NUMBER) {
+    suggestion.value =
+        credit_card.CardIdentifierStringForAutofillDisplay(suggestion_nickname);
+
+#if defined(OS_ANDROID) || defined(OS_IOS)
+    suggestion.label = credit_card.GetInfo(
+        AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale);
+#else
+    suggestion.label = credit_card.DescriptiveExpiration(app_locale);
+#endif  // defined(OS_ANDROID) || defined(OS_IOS)
+
+  } else if (credit_card.number().empty()) {
+    DCHECK_EQ(credit_card.record_type(), CreditCard::LOCAL_CARD);
+    if (credit_card.HasNonEmptyValidNickname()) {
+      suggestion.label = credit_card.nickname();
+    } else if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) {
+      suggestion.label =
+          credit_card.GetInfo(AutofillType(CREDIT_CARD_NAME_FULL), app_locale);
+    }
+  } else {
+#if defined(OS_ANDROID)
+    // On Android devices, the label is formatted as
+    // "Nickname/Network  ••••1234" when the keyboard accessory experiment
+    // is disabled and as "••••1234" when it's enabled.
+    suggestion.label =
+        base::FeatureList::IsEnabled(features::kAutofillKeyboardAccessory)
+            ? credit_card.ObfuscatedLastFourDigits()
+            : credit_card.CardIdentifierStringForAutofillDisplay(
+                  suggestion_nickname);
+#elif defined(OS_IOS)
+    // E.g. "••••1234"".
+    suggestion.label = credit_card.ObfuscatedLastFourDigits();
+#else
+    // E.g. "Nickname/Network  ••••1234, expires on 01/25".
+    suggestion.label =
+        credit_card.CardIdentifierStringAndDescriptiveExpiration(app_locale);
+#endif
+  }
+
+  if (virtual_card_option) {
+#if defined(OS_ANDROID)
+    // Set the IPH feature in order to show the IPH bubble when the virtual
+    // card is presented in the keyboard accessory.
+    suggestion.feature_for_iph =
+        feature_engagement::kIPHKeyboardAccessoryPaymentVirtualCardFeature.name;
+#endif  // OS_ANDROID
+
+    // TODO(crbug.com/1196021): Populate custom_icon with card art if available.
+    suggestion.frontend_id = POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY;
+    suggestion.is_value_secondary = true;
+  }
+
+  return suggestion;
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.h b/components/autofill/core/browser/autofill_suggestion_generator.h
index 1ac32eca..e93062aa 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator.h
+++ b/components/autofill/core/browser/autofill_suggestion_generator.h
@@ -17,6 +17,7 @@
 class AutofillType;
 class CreditCard;
 struct FormFieldData;
+class FormStructure;
 class PersonalDataManager;
 struct Suggestion;
 
@@ -33,6 +34,7 @@
 
   // Generates suggestions for all available credit cards.
   std::vector<Suggestion> GetSuggestionsForCreditCards(
+      const FormStructure& form_structure,
       const FormFieldData& field,
       const AutofillType& type,
       const std::string& app_locale);
@@ -52,6 +54,17 @@
   std::u16string GetDisplayNicknameForCreditCard(const CreditCard& card) const;
 
  private:
+  // Creates a suggestion for the given |credit_card|. |type| denotes the
+  // AutofillType of the field that is focused when the query is triggered.
+  // |prefix_matched_suggestion| indicates whether the suggestion has content
+  // that prefix-matches the field content. |virtual_card_option| suggests
+  // whether the suggestion is a virtual card option.
+  Suggestion CreateCreditCardSuggestion(const CreditCard& credit_card,
+                                        const AutofillType& type,
+                                        bool prefix_matched_suggestion,
+                                        bool virtual_card_option,
+                                        const std::string& app_locale) const;
+
   // autofill_client_ and the generator are both one per tab, and have the same
   // lifecycle.
   AutofillClient* autofill_client_;
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index cc34587..c7dca16e 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -599,8 +599,8 @@
   DCHECK_EQ(FieldTypeGroup::kCreditCard, type.group());
 
   bool should_display_gpay_logo;
-  auto cards =
-      GetCreditCardSuggestions(field_data, type, &should_display_gpay_logo);
+  auto cards = GetCreditCardSuggestions(FormStructure(form), field_data, type,
+                                        &should_display_gpay_logo);
 
   DCHECK(!cards.empty());
 
@@ -1932,6 +1932,7 @@
 }
 
 std::vector<Suggestion> BrowserAutofillManager::GetCreditCardSuggestions(
+    const FormStructure& form_structure,
     const FormFieldData& field,
     const AutofillType& type,
     bool* should_display_gpay_logo) const {
@@ -1943,12 +1944,16 @@
   std::vector<Suggestion> suggestions;
   if (!IsInAutofillSuggestionsDisabledExperiment()) {
     suggestions = suggestion_generator_->GetSuggestionsForCreditCards(
-        field, type, app_locale_);
+        form_structure, field, type, app_locale_);
   }
 
+  // TODO(crbug.com/1196021): Once the profile suggestion creation is moved to
+  // AutofillSuggestionGenerator, move this part as well.
   for (Suggestion& suggestion : suggestions) {
-    suggestion.frontend_id =
-        MakeFrontendID(suggestion.backend_id, std::string());
+    if (suggestion.frontend_id == 0) {
+      suggestion.frontend_id =
+          MakeFrontendID(suggestion.backend_id, std::string());
+    }
   }
 
   credit_card_form_event_logger_->set_suggestions(suggestions);
@@ -2578,9 +2583,9 @@
   context->is_autofill_available = true;
 
   if (context->is_filling_credit_card) {
-    *suggestions =
-        GetCreditCardSuggestions(field, context->focused_field->Type(),
-                                 &context->should_display_gpay_logo);
+    *suggestions = GetCreditCardSuggestions(*context->form_structure, field,
+                                            context->focused_field->Type(),
+                                            &context->should_display_gpay_logo);
   } else {
     *suggestions = GetProfileSuggestions(*context->form_structure, field,
                                          *context->focused_field);
@@ -2682,18 +2687,12 @@
   if (GetVirtualCardCandidates(personal_data_).empty())
     return false;
 
-  // If card number field or expiration date field is not detected, return
-  // false.
-  if (!form_structure->IsCompleteCreditCardForm())
+  // If not all of card number field, expiration date field and CVC field are
+  // detected, return false.
+  if (!IsCompleteCreditCardFormIncludingCvcField(*form_structure))
     return false;
 
-  // If CVC field is detected, then all requirements are met, otherwise return
-  // false.
-  for (auto& field : *form_structure) {
-    if (field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE)
-      return true;
-  }
-  return false;
+  return true;
 }
 #endif
 
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
index 7c94124..da68d58 100644
--- a/components/autofill/core/browser/browser_autofill_manager.h
+++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -542,6 +542,7 @@
   // |should_display_gpay_logo| will be set to true if there is no credit card
   // suggestions or all suggestions come from Payments server.
   std::vector<Suggestion> GetCreditCardSuggestions(
+      const FormStructure& form_structure,
       const FormFieldData& field,
       const AutofillType& type,
       bool* should_display_gpay_logo) const;
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index 7b2478a..a7fb641 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -20,6 +20,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/metrics_hashes.h"
+#include "base/stl_util.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -2395,6 +2396,7 @@
                                       test::ObfuscatedCardDigitsAsUTF8("0005") +
                                       std::string(", expires on 04/99");
 #endif
+
   CheckSuggestions(
       kDefaultPageID,
       Suggestion("John Dillinger", "", kGenericCard,
@@ -8378,6 +8380,86 @@
 }
 
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
+       GetCreditCardSuggestions_VirtualCard) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitWithFeatures(
+      {features::kAutofillSuggestVirtualCardsOnlyOnFullFormDetection,
+       features::kAutofillEnableMerchantBoundVirtualCards},
+      {});
+
+  personal_data_.ClearCreditCards();
+  CreditCard masked_server_card(CreditCard::MASKED_SERVER_CARD,
+                                /*server_id=*/"a123");
+  test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
+                          "4234567890123456",  // Visa
+                          "04", "2999", "1");
+  masked_server_card.SetNetworkForMaskedCard(kVisaCard);
+  masked_server_card.set_guid("00000000-0000-0000-0000-000000000007");
+  masked_server_card.set_virtual_card_enrollment_state(CreditCard::ENROLLED);
+  masked_server_card.SetNickname(u"nickname");
+  personal_data_.AddServerCreditCard(masked_server_card);
+
+  // Set up our form data.
+  FormData form;
+  CreateTestCreditCardFormData(&form, true, false);
+  std::vector<FormData> forms(1, form);
+  FormsSeen(forms);
+
+  // Card number field.
+  FormFieldData field = form.fields[1];
+  GetAutofillSuggestions(form, field);
+
+#if defined(OS_ANDROID) || defined(OS_IOS)
+  std::string label = std::string("04/99");
+#else
+  std::string label = std::string("Expires on 04/99");
+#endif
+
+  Suggestion virtual_card_suggestion = Suggestion(
+      std::string("nickname  ") + test::ObfuscatedCardDigitsAsUTF8("3456"),
+      label, kVisaCard, autofill::POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY);
+
+  CheckSuggestions(
+      kDefaultPageID, virtual_card_suggestion,
+      Suggestion(
+          std::string("nickname  ") + test::ObfuscatedCardDigitsAsUTF8("3456"),
+          label, kVisaCard,
+          browser_autofill_manager_->GetPackedCreditCardID(7)));
+
+  // Non card number field (cardholder name field).
+  field = form.fields[0];
+  GetAutofillSuggestions(form, field);
+
+#if defined(OS_ANDROID)
+  label = std::string("nickname  ") + test::ObfuscatedCardDigitsAsUTF8("3456");
+#elif defined(OS_IOS)
+  label = test::ObfuscatedCardDigitsAsUTF8("3456");
+#else
+  label = std::string("nickname  ") + test::ObfuscatedCardDigitsAsUTF8("3456") +
+          std::string(", expires on 04/99");
+#endif
+
+  virtual_card_suggestion =
+      Suggestion(std::string("Elvis Presley"), label, kVisaCard,
+                 autofill::POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY);
+
+  CheckSuggestions(
+      kDefaultPageID, virtual_card_suggestion,
+      Suggestion("Elvis Presley", label, kVisaCard,
+                 browser_autofill_manager_->GetPackedCreditCardID(7)));
+
+  // Incomplete form.
+  field = form.fields[0];
+  form.fields.pop_back();
+  GetAutofillSuggestions(form, field);
+
+  CheckSuggestions(
+      kDefaultPageID,
+      Suggestion("Elvis Presley", label, kVisaCard,
+                 browser_autofill_manager_->GetPackedCreditCardID(7)));
+}
+
+TEST_P(BrowserAutofillManagerStructuredProfileTest,
        DidShowSuggestions_LogAutocompleteShownMetric) {
   FormData form;
   form.name = u"NothingSpecial";
diff --git a/components/autofill/core/browser/ui/popup_item_ids.h b/components/autofill/core/browser/ui/popup_item_ids.h
index ff44f02..1c1c945 100644
--- a/components/autofill/core/browser/ui/popup_item_ids.h
+++ b/components/autofill/core/browser/ui/popup_item_ids.h
@@ -34,7 +34,8 @@
   POPUP_ITEM_ID_ACCOUNT_STORAGE_USERNAME_ENTRY = -23,
   POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_RE_SIGNIN = -24,
   POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_EMPTY = -25,
-  POPUP_ITEM_ID_MIXED_FORM_MESSAGE = -26
+  POPUP_ITEM_ID_MIXED_FORM_MESSAGE = -26,
+  POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY = -27
 };
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/ui/suggestion.h b/components/autofill/core/browser/ui/suggestion.h
index c706a3a..5ec2825f 100644
--- a/components/autofill/core/browser/ui/suggestion.h
+++ b/components/autofill/core/browser/ui/suggestion.h
@@ -47,7 +47,11 @@
   // (see popup_item_ids.h) have special built-in meanings.
   int frontend_id = 0;
 
+  // The text that will be filled in to the focused field and is displayed as
+  // the main text in the suggestion. Its style depends on |is_value_secondary|.
   std::u16string value;
+
+  // The text displayed on the second line in a suggestion.
   std::u16string label;
   // A label to be shown beneath |label| that will display information about any
   // credit card offers or rewards.
@@ -65,7 +69,7 @@
   // account store. If it's empty, no store indication should be shown.
   std::string store_indicator_icon;
   MatchMode match = PREFIX_MATCH;
-  // |value| should be displayed as secondary text.
+  // Whether |value| should be displayed as secondary text.
   bool is_value_secondary = false;
   // Whether suggestion was interacted with and is now in a loading state.
   IsLoading is_loading = IsLoading(false);
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp
index 1684adc..360c243 100644
--- a/components/autofill_payments_strings.grdp
+++ b/components/autofill_payments_strings.grdp
@@ -512,6 +512,9 @@
       View virtual card details
     </message>
   </if>
+  <message name="IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE" desc="The text shown in the virtual card option in the credit card suggestion list. It is shown as the value of the suggestion.">
+    Virtual card
+  </message>
 
   <message name="IDS_AUTOFILL_SAVE_UPI_PROMPT_TITLE" desc="Title text for the prompt to save a UPI ID locally, which the user used in a page. UPI is an online payment method. A UPI ID is an email-like string.">
     Remember your UPI ID?
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE.png.sha1
new file mode 100644
index 0000000..5f99066
--- /dev/null
+++ b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE.png.sha1
@@ -0,0 +1 @@
+dda4426cf1759615adfa3aeb5b0564c91ad81f64
\ No newline at end of file
diff --git a/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc b/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc
index 73ad1cff..17e799b 100644
--- a/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc
+++ b/components/bookmarks/managed/managed_bookmarks_tracker_unittest.cc
@@ -205,8 +205,10 @@
 
   // Swap the Google bookmark with the Folder.
   std::unique_ptr<base::ListValue> updated(CreateTestTree());
-  std::unique_ptr<base::Value> removed;
-  ASSERT_TRUE(updated->Remove(0, &removed));
+  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));
 
   // These two nodes should just be swapped.
@@ -228,7 +230,7 @@
 
   // Remove the Folder.
   std::unique_ptr<base::ListValue> updated(CreateTestTree());
-  ASSERT_TRUE(updated->Remove(1, nullptr));
+  ASSERT_TRUE(updated->EraseListIter(updated->GetList().begin() + 1));
 
   const BookmarkNode* parent = managed_node();
   EXPECT_CALL(observer_, BookmarkNodeRemoved(model_.get(), parent, 1, _, _));
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 1885bf6f..590ca72 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
@@ -64,13 +64,14 @@
 // front, or appending "0"'s to the back.
 void MaintainContentLengthPrefsWindow(base::ListValue* list, size_t length) {
   // Remove data for old days from the front.
-  while (list->GetSize() > length)
-    list->Remove(0, nullptr);
+  base::Value::ListView list_view = list->GetList();
+  while (list_view.size() > length)
+    list->EraseListIter(list_view.begin());
   // Newly added lists are empty. Add entries to back to fill the window,
   // each initialized to zero.
-  while (list->GetSize() < length)
-    list->AppendString(base::NumberToString(0));
-  DCHECK_EQ(length, list->GetSize());
+  while (list_view.size() < length)
+    list->Append(base::NumberToString(0));
+  DCHECK_EQ(length, list_view.size());
 }
 
 // Increments an int64_t, stored as a string, in a ListPref at the specified
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
index 3b4c8ff..7c74d15 100644
--- a/components/omnibox/browser/autocomplete_result.cc
+++ b/components/omnibox/browser/autocomplete_result.cc
@@ -274,17 +274,7 @@
 #else
   if (matches_.size() > 2) {
 #endif
-    // Skip over default match.
-    auto next = std::next(matches_.begin());
-    if (AutocompleteMatch::ShouldBeSkippedForGroupBySearchVsUrl(
-            matches_.front().type)) {
-      while (next != matches_.end() &&
-             (AutocompleteMatch::ShouldBeSkippedForGroupBySearchVsUrl(
-                 next->type))) {
-        next = std::next(next);
-      }
-    }
-    GroupSuggestionsBySearchVsURL(next, matches_.end());
+    GroupSuggestionsBySearchVsURL(std::next(matches_.begin()), matches_.end());
   }
 
   // Grouping and Demoting Matches with Headers needs to be done only after
@@ -1059,6 +1049,14 @@
 // static
 void AutocompleteResult::GroupSuggestionsBySearchVsURL(iterator begin,
                                                        iterator end) {
+  while (begin != end &&
+         AutocompleteMatch::ShouldBeSkippedForGroupBySearchVsUrl(begin->type)) {
+    ++begin;
+  }
+
+  if (begin == end)
+    return;
+
   std::stable_partition(begin, end, [](const AutocompleteMatch& match) {
     return AutocompleteMatch::IsSearchType(match.type);
   });
diff --git a/components/omnibox/browser/autocomplete_result.h b/components/omnibox/browser/autocomplete_result.h
index 06b5ba1..34e77c2 100644
--- a/components/omnibox/browser/autocomplete_result.h
+++ b/components/omnibox/browser/autocomplete_result.h
@@ -244,6 +244,9 @@
  private:
   FRIEND_TEST_ALL_PREFIXES(AutocompleteResultTest,
                            DemoteOnDeviceSearchSuggestions);
+  FRIEND_TEST_ALL_PREFIXES(
+      AutocompleteResultTest,
+      GroupSuggestionsBySearchVsURLHonorsProtectedSuggestions);
   friend class HistoryURLProviderTest;
 
   typedef std::map<AutocompleteProvider*, ACMatches> ProviderToMatches;
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc
index 576a862..55006c92 100644
--- a/components/omnibox/browser/autocomplete_result_unittest.cc
+++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -1744,6 +1744,47 @@
                       AutocompleteResult::GetMaxMatches());
 }
 
+TEST_F(AutocompleteResultTest,
+       GroupSuggestionsBySearchVsURLHonorsProtectedSuggestions) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeaturesAndParameters(
+      {{omnibox::kUIExperimentMaxAutocompleteMatches,
+        {{OmniboxFieldTrial::kUIMaxAutocompleteMatchesParam, "7"}}}},
+      {/* nothing disabled */});
+  TestData data[] = {
+      {0, 2, 400, true, {}, AutocompleteMatchType::HISTORY_TITLE},
+      {1, 1, 800, false, {}, AutocompleteMatchType::CLIPBOARD_URL},
+      {2, 1, 700, false, {}, AutocompleteMatchType::TILE_NAVSUGGEST},
+      {3, 1, 600, false, {}, AutocompleteMatchType::TILE_SUGGESTION},
+      {4, 1, 1000, false, {}, AutocompleteMatchType::HISTORY_URL},
+      {5, 1, 900, false, {}, AutocompleteMatchType::SEARCH_SUGGEST},
+      {6, 1, 800, false, {}, AutocompleteMatchType::SEARCH_SUGGEST},
+  };
+
+  ACMatches matches;
+  PopulateAutocompleteMatches(data, base::size(data), &matches);
+
+  AutocompleteInput input(u"a", metrics::OmniboxEventProto::OTHER,
+                          TestSchemeClassifier());
+  AutocompleteResult result;
+  result.AppendMatches(input, matches);
+  result.GroupSuggestionsBySearchVsURL(std::next(result.matches_.begin()),
+                                       result.matches_.end());
+
+  TestData expected_data[] = {
+      {0, 2, 400, true, {}, AutocompleteMatchType::HISTORY_TITLE},
+      {1, 1, 800, false, {}, AutocompleteMatchType::CLIPBOARD_URL},
+      {2, 1, 700, false, {}, AutocompleteMatchType::TILE_NAVSUGGEST},
+      {3, 1, 600, false, {}, AutocompleteMatchType::TILE_SUGGESTION},
+      {5, 1, 900, false, {}, AutocompleteMatchType::SEARCH_SUGGEST},
+      {6, 1, 800, false, {}, AutocompleteMatchType::SEARCH_SUGGEST},
+      {4, 1, 1000, false, {}, AutocompleteMatchType::HISTORY_URL},
+  };
+
+  AssertResultMatches(result, expected_data,
+                      AutocompleteResult::GetMaxMatches());
+}
+
 TEST_F(AutocompleteResultTest, SortAndCullMaxURLMatches) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitWithFeaturesAndParameters(
diff --git a/components/password_manager/core/browser/password_reuse_detector.cc b/components/password_manager/core/browser/password_reuse_detector.cc
index 6cc4f9a4..35291c9 100644
--- a/components/password_manager/core/browser/password_reuse_detector.cc
+++ b/components/password_manager/core/browser/password_reuse_detector.cc
@@ -98,6 +98,8 @@
     if (change.type() == PasswordStoreChange::ADD ||
         change.type() == PasswordStoreChange::UPDATE)
       AddPassword(change.form());
+    if (change.type() == PasswordStoreChange::REMOVE)
+      RemovePassword(change.form());
   }
 }
 
@@ -298,6 +300,19 @@
   }
 }
 
+void PasswordReuseDetector::RemovePassword(const PasswordForm& form) {
+  if (form.password_value.size() < kMinPasswordLengthToCheck)
+    return;
+
+  const auto result =
+      passwords_with_matching_reused_credentials_.find(form.password_value);
+  if (!(result == passwords_with_matching_reused_credentials_.end()) ||
+      !result->second.empty()) {
+    passwords_with_matching_reused_credentials_.erase(form.password_value);
+    saved_passwords_--;
+  }
+}
+
 PasswordReuseDetector::passwords_iterator
 PasswordReuseDetector::FindFirstSavedPassword(const std::u16string& input) {
   // Keys in |passwords_with_matching_reused_credentials_| are ordered by
diff --git a/components/password_manager/core/browser/password_reuse_detector.h b/components/password_manager/core/browser/password_reuse_detector.h
index b12f3f5..8ea93d9e 100644
--- a/components/password_manager/core/browser/password_reuse_detector.h
+++ b/components/password_manager/core/browser/password_reuse_detector.h
@@ -100,6 +100,11 @@
   // |passwords_with_matching_reused_credentials_|.
   void AddPassword(const PasswordForm& form);
 
+  // Remove password of |form| from
+  // |passwords_with_matching_reused_credentials_| and lower the counter of
+  // |saved_passwords_|.
+  void RemovePassword(const PasswordForm& form);
+
   // If Gaia password reuse is found, return the PasswordHashData of the reused
   // password. If no reuse is found, return |absl::nullopt|.
   absl::optional<PasswordHashData> CheckGaiaPasswordReuse(
diff --git a/components/password_manager/core/browser/password_reuse_detector_unittest.cc b/components/password_manager/core/browser/password_reuse_detector_unittest.cc
index ecc85dd..a8487cf 100644
--- a/components/password_manager/core/browser/password_reuse_detector_unittest.cc
+++ b/components/password_manager/core/browser/password_reuse_detector_unittest.cc
@@ -231,6 +231,47 @@
   }
 }
 
+TEST(PasswordReuseDetectorTest, AddAndRemoveSameLogin) {
+  PasswordReuseDetector reuse_detector;
+  std::vector<std::unique_ptr<PasswordForm>> login_credentials =
+      GetForms(GetTestDomainsPasswords());
+  // Add the test domain passwords into the saved passwords map.
+  PasswordStoreChangeList add_changes =
+      GetChangeList(PasswordStoreChange::ADD, login_credentials);
+  reuse_detector.OnLoginsChanged(add_changes);
+
+  const std::vector<MatchingReusedCredential>
+      expected_matching_reused_credentials = {
+          {"https://accounts.google.com", u"gUsername"}};
+  MockPasswordReuseDetectorConsumer mockConsumer;
+  // One of the passwords in |login_credentials| has less than the minimum
+  // requirement of characters in a password so it will not be stored.
+  int valid_passwords = login_credentials.size() - 1;
+  EXPECT_CALL(
+      mockConsumer,
+      OnReuseCheckDone(
+          /*is_reuse_found=*/true, strlen("saved_password"),
+          Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
+          UnorderedElementsAreArray(expected_matching_reused_credentials),
+          valid_passwords));
+
+  // "saved_password" is a substring of "123saved_password" so it should trigger
+  // a reuse and get the matching credentials.
+  reuse_detector.CheckReuse(u"123saved_password", "https://evil.com",
+                            &mockConsumer);
+  testing::Mock::VerifyAndClearExpectations(&mockConsumer);
+
+  // Remove the test domain passwords from the saved passwords map.
+  PasswordStoreChangeList remove_changes =
+      GetChangeList(PasswordStoreChange::REMOVE, login_credentials);
+  reuse_detector.OnLoginsChanged(remove_changes);
+  EXPECT_CALL(mockConsumer,
+              OnReuseCheckDone(/*is_reuse_found=*/false, _, _, _, _));
+  // The stored credentials were removed so no reuse should be found.
+  reuse_detector.CheckReuse(u"123saved_password", "https://evil.com",
+                            &mockConsumer);
+}
+
 TEST(PasswordReuseDetectorTest, MatchMultiplePasswords) {
   // These all have different length passwods so we can check the
   // returned length.
diff --git a/components/policy/core/common/schema_unittest.cc b/components/policy/core/common/schema_unittest.cc
index 6132e79..7f4a17b585 100644
--- a/components/policy/core/common/schema_unittest.cc
+++ b/components/policy/core/common/schema_unittest.cc
@@ -832,29 +832,29 @@
     Schema subschema = schema.GetProperty("ArrayOfObjects");
     ASSERT_TRUE(subschema.valid());
     base::ListValue root;
+    base::Value::ListView root_view = root.GetList();
 
     // Unknown property.
-    std::unique_ptr<base::DictionaryValue> dict_value(
-        new base::DictionaryValue());
-    dict_value->SetBoolean("three", true);
+    base::Value dict_value(base::Value::Type::DICTIONARY);
+    dict_value.SetBoolKey("three", true);
     root.Append(std::move(dict_value));
     TestSchemaValidation(subschema, root, SCHEMA_STRICT, false);
     TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, true);
     TestSchemaValidation(subschema, root,
                          SCHEMA_ALLOW_UNKNOWN_AND_INVALID_LIST_ENTRY, true);
     TestSchemaValidationWithPath(subschema, root, "items[0]");
-    root.Remove(root.GetSize() - 1, nullptr);
+    root.EraseListIter(root_view.begin() + (root_view.size() - 1));
 
     // Invalid property.
-    dict_value = std::make_unique<base::DictionaryValue>();
-    dict_value->SetBoolean("two", true);
+    dict_value = base::Value(base::Value::Type::DICTIONARY);
+    dict_value.SetBoolKey("two", true);
     root.Append(std::move(dict_value));
     TestSchemaValidation(subschema, root, SCHEMA_STRICT, false);
     TestSchemaValidation(subschema, root, SCHEMA_ALLOW_UNKNOWN, false);
     TestSchemaValidation(subschema, root,
                          SCHEMA_ALLOW_UNKNOWN_AND_INVALID_LIST_ENTRY, true);
     TestSchemaValidationWithPath(subschema, root, "items[0].two");
-    root.Remove(root.GetSize() - 1, nullptr);
+    root.EraseListIter(root_view.begin() + (root_view.size() - 1));
   }
 
   // Tests on ObjectOfArray.
diff --git a/components/sessions/core/tab_restore_service_helper.cc b/components/sessions/core/tab_restore_service_helper.cc
index 6ef8757..10f1d8d 100644
--- a/components/sessions/core/tab_restore_service_helper.cc
+++ b/components/sessions/core/tab_restore_service_helper.cc
@@ -426,22 +426,6 @@
       LiveTabContext* current_context = context;
       auto& window = static_cast<Window&>(entry);
 
-      // Relabel group IDs to prevent duplicating groups, e.g. if the same
-      // window is restored twice or a tab of the same ID is restored
-      // elsewhere. See crbug.com/1202102.
-      base::flat_map<tab_groups::TabGroupId, tab_groups::TabGroupId>
-          new_group_ids;
-      new_group_ids.reserve(window.tab_groups.size());
-      for (const auto& tab_group : window.tab_groups) {
-        auto new_id = tab_groups::TabGroupId::GenerateNew();
-        new_group_ids.emplace(tab_group.first, new_id);
-        // Ensure the new ID does not collide with an existing group, failing
-        // silently if it does. This is extremely unlikely, given group IDs are
-        // 128 bit randomly generated numbers.
-        if (client_->FindLiveTabContextWithGroup(new_id))
-          return std::vector<LiveTab*>();
-      }
-
       // When restoring a window, either the entire window can be restored, or a
       // single tab within it. If the entry's ID matches the one to restore,
       // then the entire window will be restored.
@@ -449,17 +433,11 @@
         context = client_->CreateLiveTabContext(
             window.app_name, window.bounds, window.show_state, window.workspace,
             window.user_title);
-
         for (size_t tab_i = 0; tab_i < window.tabs.size(); ++tab_i) {
           const Tab& tab = *window.tabs[tab_i];
-
-          absl::optional<tab_groups::TabGroupId> new_group;
-          if (tab.group)
-            new_group = new_group_ids.at(*tab.group);
-
           LiveTab* restored_tab = context->AddRestoredTab(
               tab.navigations, context->GetTabCount(),
-              tab.current_navigation_index, tab.extension_app_id, new_group,
+              tab.current_navigation_index, tab.extension_app_id, tab.group,
               tab.group_visual_data.value_or(tab_groups::TabGroupVisualData()),
               static_cast<int>(tab_i) == window.selected_tab_index, tab.pinned,
               tab.platform_data.get(), tab.user_agent_override, nullptr);
@@ -471,8 +449,7 @@
         }
 
         for (const auto& tab_group : window.tab_groups) {
-          context->SetVisualDataForGroup(new_group_ids.at(tab_group.first),
-                                         tab_group.second);
+          context->SetVisualDataForGroup(tab_group.first, tab_group.second);
         }
 
         // All the window's tabs had the same former browser_id.
diff --git a/components/spellcheck/browser/pref_names.cc b/components/spellcheck/browser/pref_names.cc
index 9d29b78..2631f006 100644
--- a/components/spellcheck/browser/pref_names.cc
+++ b/components/spellcheck/browser/pref_names.cc
@@ -21,14 +21,6 @@
 // force-enabled in our spell-checker due to the SpellcheckLanguage policy.
 const char kSpellCheckForcedDictionaries[] = "spellcheck.forced_dictionaries";
 
-// DEPRECATED, replaced by kSpellCheckBlocklistedDictionaries below.
-// TODO(crbug/1161062): Remove after M91.
-// List of strings representing the dictionary names for languages that are
-// force-disabled in our spell-checker due to the SpellcheckLanguageBlocklist
-// policy.
-const char kSpellCheckBlacklistedDictionaries[] =
-    "spellcheck.blacklisted_dictionaries";
-
 // List of strings representing the dictionary names for languages that are
 // force-disabled in our spell-checker due to the SpellcheckLanguageBlocklist
 // policy.
diff --git a/components/spellcheck/browser/pref_names.h b/components/spellcheck/browser/pref_names.h
index 43aadae..bc7f4b3b 100644
--- a/components/spellcheck/browser/pref_names.h
+++ b/components/spellcheck/browser/pref_names.h
@@ -11,7 +11,6 @@
 extern const char kSpellCheckEnable[];
 extern const char kSpellCheckDictionaries[];
 extern const char kSpellCheckForcedDictionaries[];
-extern const char kSpellCheckBlacklistedDictionaries[];
 extern const char kSpellCheckBlocklistedDictionaries[];
 extern const char kSpellCheckDictionary[];
 extern const char kSpellCheckUseSpellingService[];
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
index 6959e2f9..6859d4b 100644
--- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
+++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -36,7 +36,6 @@
 #include "net/base/net_errors.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
-#include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom.h"
 #include "third_party/blink/public/mojom/devtools/console_message.mojom.h"
 
 namespace subresource_filter {
@@ -712,21 +711,15 @@
   if (is_ad_subframe == base::Contains(ad_frames_, frame_tree_node_id))
     return;
 
-  blink::mojom::AdFrameType ad_frame_type = blink::mojom::AdFrameType::kNonAd;
   if (is_ad_subframe) {
     ad_frames_.insert(frame_tree_node_id);
-
-    bool parent_is_ad = base::Contains(
-        ad_frames_, render_frame_host->GetParent()->GetFrameTreeNodeId());
-    ad_frame_type = parent_is_ad ? blink::mojom::AdFrameType::kChildAd
-                                 : blink::mojom::AdFrameType::kRootAd;
   } else {
     ad_frames_.erase(frame_tree_node_id);
   }
 
-  // Replicate ad frame type to this frame's proxies, so that it can be looked
-  // up in any process involved in rendering the current page.
-  render_frame_host->UpdateAdFrameType(ad_frame_type);
+  // Replicate `is_ad_subframe` to this frame's proxies, so that it can be
+  // looked up in any process involved in rendering the current page.
+  render_frame_host->UpdateIsAdSubframe(is_ad_subframe);
 
   SubresourceFilterObserverManager::FromWebContents(web_contents())
       ->NotifyIsAdSubframeChanged(render_frame_host, is_ad_subframe);
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc b/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
index 7840a81..64728f7 100644
--- a/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
+++ b/components/subresource_filter/content/renderer/subresource_filter_agent_unittest.cc
@@ -28,8 +28,6 @@
 
 namespace {
 
-using AdFrameType = blink::mojom::AdFrameType;
-
 // The SubresourceFilterAgent with its dependencies on Blink mocked out.
 //
 // This approach is somewhat rudimentary, but appears to be the best compromise
@@ -79,8 +77,7 @@
   }
 
   bool IsAdSubframe() override {
-    return ad_evidence_ && ad_evidence_->is_complete() &&
-           ad_evidence_->IndicatesAdSubframe();
+    return ad_evidence_ && ad_evidence_->IndicatesAdSubframe();
   }
 
   const absl::optional<blink::FrameAdEvidence>& AdEvidence() override {
@@ -216,31 +213,29 @@
     // No DidFinishLoad is called in this case.
   }
 
-  void StartLoadAndSetActivationState(
-      mojom::ActivationLevel level,
-      AdFrameType ad_type = AdFrameType::kNonAd) {
+  void StartLoadAndSetActivationState(mojom::ActivationLevel level,
+                                      bool is_ad_subframe = false) {
     mojom::ActivationState state;
     state.activation_level = level;
-    StartLoadAndSetActivationState(state, ad_type);
+    StartLoadAndSetActivationState(state, is_ad_subframe);
   }
 
-  void StartLoadAndSetActivationState(
-      mojom::ActivationState state,
-      AdFrameType ad_type = AdFrameType::kNonAd) {
+  void StartLoadAndSetActivationState(mojom::ActivationState state,
+                                      bool is_ad_subframe = false) {
     agent_as_rfo()->DidStartNavigation(GURL(), absl::nullopt);
     agent_as_rfo()->ReadyToCommitNavigation(nullptr);
 
     absl::optional<blink::FrameAdEvidence> ad_evidence;
     if (!agent()->IsMainFrame()) {
       // Generate an evidence object matching the `ad_type`.
-      ad_evidence = blink::FrameAdEvidence(ad_type == AdFrameType::kChildAd);
-      if (ad_type == AdFrameType::kRootAd) {
+      ad_evidence = blink::FrameAdEvidence(false /* parent_is_ad */);
+      if (is_ad_subframe) {
         ad_evidence->set_created_by_ad_script(
             blink::mojom::FrameCreationStackEvidence::kCreatedByAdScript);
       }
       ad_evidence->set_is_complete();
     } else {
-      ASSERT_EQ(ad_type, AdFrameType::kNonAd);
+      ASSERT_FALSE(is_ad_subframe);
     }
 
     agent()->ActivateForNextCommittedLoad(state.Clone(), ad_evidence);
@@ -348,16 +343,14 @@
       SetTestRulesetToDisallowURLsWithPathSuffix(kTestFirstURLPathSuffix));
   MemoryMappedRuleset::SetMemoryMapFailuresForTesting(true);
   ExpectNoSubresourceFilterGetsInjected();
-  StartLoadAndSetActivationState(
-      mojom::ActivationLevel::kEnabled,
-      AdFrameType::kNonAd /* is_associated_with_ad_subframe */);
+  StartLoadAndSetActivationState(mojom::ActivationLevel::kEnabled,
+                                 false /* is_ad_subframe */);
   ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(agent()));
 
   MemoryMappedRuleset::SetMemoryMapFailuresForTesting(false);
   ExpectSubresourceFilterGetsInjected();
-  StartLoadAndSetActivationState(
-      mojom::ActivationLevel::kEnabled,
-      AdFrameType::kNonAd /* is_associated_with_ad_subframe */);
+  StartLoadAndSetActivationState(mojom::ActivationLevel::kEnabled,
+                                 false /* is_ad_subframe */);
 }
 
 TEST_F(SubresourceFilterAgentTest, Disabled_NoFilterIsInjected) {
@@ -669,9 +662,8 @@
              /*is_subframe_created_by_ad_script=*/false);
 
   ExpectSubresourceFilterGetsInjected();
-  StartLoadAndSetActivationState(
-      mojom::ActivationLevel::kDryRun,
-      AdFrameType::kRootAd /* is_associated_with_ad_subframe */);
+  StartLoadAndSetActivationState(mojom::ActivationLevel::kDryRun,
+                                 true /* is_ad_subframe */);
   ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(agent()));
 
   // Test the ad subframe value that is set at the filter.
@@ -692,9 +684,8 @@
 
   // Browser tags the frame as an ad subframe.
   ExpectSubresourceFilterGetsInjected();
-  StartLoadAndSetActivationState(
-      mojom::ActivationLevel::kDryRun,
-      AdFrameType::kRootAd /* is_associated_with_ad_subframe */);
+  StartLoadAndSetActivationState(mojom::ActivationLevel::kDryRun,
+                                 true /* is_ad_subframe */);
   ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(agent()));
 
   EXPECT_TRUE(agent()->IsAdSubframe());
@@ -703,9 +694,8 @@
 
   // Browser then untags the frame as an ad subframe.
   ExpectSubresourceFilterGetsInjected();
-  StartLoadAndSetActivationState(
-      mojom::ActivationLevel::kDryRun,
-      AdFrameType::kNonAd /* is_associated_with_ad_subframe */);
+  StartLoadAndSetActivationState(mojom::ActivationLevel::kDryRun,
+                                 false /* is_ad_subframe */);
   ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(agent()));
 
   EXPECT_FALSE(agent()->IsAdSubframe());
diff --git a/components/sync_bookmarks/bookmark_model_merger.cc b/components/sync_bookmarks/bookmark_model_merger.cc
index 1fff90f..1bacc44 100644
--- a/components/sync_bookmarks/bookmark_model_merger.cc
+++ b/components/sync_bookmarks/bookmark_model_merger.cc
@@ -389,6 +389,19 @@
   return grouped_updates;
 }
 
+int GetNumUnsyncedEntities(const SyncedBookmarkTracker* tracker) {
+  DCHECK(tracker);
+
+  int num_unsynced_entities = 0;
+  for (const SyncedBookmarkTracker::Entity* entity :
+       tracker->GetAllEntities()) {
+    if (entity->IsUnsynced()) {
+      ++num_unsynced_entities;
+    }
+  }
+  return num_unsynced_entities;
+}
+
 }  // namespace
 
 BookmarkModelMerger::RemoteTreeNode::RemoteTreeNode() = default;
@@ -558,6 +571,10 @@
     // is used to disable reupload after initial merge.
     bookmark_tracker_->SetBookmarksFullTitleReuploaded();
   }
+
+  base::UmaHistogramCounts100000(
+      "Sync.BookmarkModelMerger.UnsyncedEntitiesUponCompletion",
+      GetNumUnsyncedEntities(bookmark_tracker_));
 }
 
 // static
diff --git a/components/sync_bookmarks/bookmark_model_merger_unittest.cc b/components/sync_bookmarks/bookmark_model_merger_unittest.cc
index 9610e1e..d083b7c 100644
--- a/components/sync_bookmarks/bookmark_model_merger_unittest.cc
+++ b/components/sync_bookmarks/bookmark_model_merger_unittest.cc
@@ -344,6 +344,8 @@
   //    |- url3(http://www.url3.com)
   //    |- url4(http://www.url4.com)
 
+  base::HistogramTester histogram_tester;
+
   std::unique_ptr<SyncedBookmarkTracker> tracker =
       Merge(std::move(updates), bookmark_model.get());
   ASSERT_THAT(bookmark_bar_node->children().size(), Eq(3u));
@@ -396,6 +398,10 @@
   EXPECT_THAT(bookmark_bar_node->children()[2]->children()[1]->url(),
               Eq(GURL(kUrl4)));
 
+  EXPECT_THAT(histogram_tester.GetTotalSum(
+                  "Sync.BookmarkModelMerger.UnsyncedEntitiesUponCompletion"),
+              Eq(4));
+
   // Verify the tracker contents.
   EXPECT_THAT(tracker->TrackedEntitiesCountForTest(), Eq(11U));
   std::vector<const SyncedBookmarkTracker::Entity*> local_changes =
@@ -2126,6 +2132,7 @@
       /*is_folder=*/true, /*unique_position=*/posFolder2,
       base::GUID::GenerateRandomV4()));
 
+  base::HistogramTester histogram_tester;
   std::unique_ptr<SyncedBookmarkTracker> tracker =
       Merge(std::move(updates), bookmark_model.get());
 
@@ -2134,6 +2141,10 @@
 
   EXPECT_TRUE(tracker->GetEntityForSyncId(kFolder1Id)->IsUnsynced());
   EXPECT_FALSE(tracker->GetEntityForSyncId(kFolder2Id)->IsUnsynced());
+
+  EXPECT_THAT(histogram_tester.GetTotalSum(
+                  "Sync.BookmarkModelMerger.UnsyncedEntitiesUponCompletion"),
+              Eq(1));
 }
 
 TEST(BookmarkModelMergerTest, ShouldRemoveDifferentTypeDuplicatesByGUID) {
diff --git a/components/viz/service/display_embedder/output_presenter_fuchsia.cc b/components/viz/service/display_embedder/output_presenter_fuchsia.cc
index 259b532a..7d47d7d 100644
--- a/components/viz/service/display_embedder/output_presenter_fuchsia.cc
+++ b/components/viz/service/display_embedder/output_presenter_fuchsia.cc
@@ -135,18 +135,6 @@
 
 }  // namespace
 
-OutputPresenterFuchsia::PendingOverlay::PendingOverlay(
-    OverlayCandidate candidate,
-    std::vector<gfx::GpuFence> release_fences)
-    : candidate(std::move(candidate)),
-      release_fences(std::move(release_fences)) {}
-OutputPresenterFuchsia::PendingOverlay::~PendingOverlay() = default;
-
-OutputPresenterFuchsia::PendingOverlay::PendingOverlay(PendingOverlay&&) =
-    default;
-OutputPresenterFuchsia::PendingOverlay&
-OutputPresenterFuchsia::PendingOverlay::operator=(PendingOverlay&&) = default;
-
 OutputPresenterFuchsia::PendingFrame::PendingFrame(uint32_t ordinal)
     : ordinal(ordinal) {}
 OutputPresenterFuchsia::PendingFrame::~PendingFrame() = default;
@@ -302,8 +290,9 @@
   }
 
   // Create PresenterImageFuchsia for each buffer in the collection.
-  uint32_t image_usage =
-      gpu::SHARED_IMAGE_USAGE_RASTER | gpu::SHARED_IMAGE_USAGE_SCANOUT;
+  uint32_t image_usage = gpu::SHARED_IMAGE_USAGE_DISPLAY |
+                         gpu::SHARED_IMAGE_USAGE_RASTER |
+                         gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   std::vector<std::unique_ptr<OutputPresenter::Image>> images;
   images.reserve(num_images);
@@ -419,25 +408,8 @@
   if (!next_frame_)
     next_frame_ = PendingFrame(next_frame_ordinal_++);
 
-  for (size_t i = 0; i < overlays.size(); ++i) {
-    auto semaphore = dependency_->GetSharedContextState()
-                         ->external_semaphore_pool()
-                         ->GetOrCreateSemaphore();
-    gfx::GpuFenceHandle fence_handle;
-    fence_handle.owned_event = semaphore.handle().TakeHandle();
-
-    accesses[i]->SetReleaseFence(fence_handle.Clone());
-    std::vector<gfx::GpuFence> release_fences;
-    release_fences.emplace_back(std::move(fence_handle));
-    next_frame_->overlays.emplace_back(std::move(overlays[i]),
-                                       std::move(release_fences));
-    // TODO(crbug.com/1144890): Enqueue overlay plane's acquire fences
-    // after |supports_commit_overlay_planes| is supported. Overlay plane might
-    // display the same Image more than once, which can create a fence
-    // dependency that can be broken by a later Image. However, primary plane
-    // implementation allows only one present at a time. In this scenario,
-    // merging fences might cause hangs, see crbug.com/1151042.
-  }
+  DCHECK(next_frame_->overlays.empty());
+  next_frame_->overlays = std::move(overlays);
 }
 
 void OutputPresenterFuchsia::PresentNextFrame() {
@@ -455,7 +427,7 @@
       "image_id", frame.image_id);
 
   for (size_t i = 0; i < frame.overlays.size(); ++i) {
-    auto& overlay = frame.overlays[i].candidate;
+    auto& overlay = frame.overlays[i];
     DCHECK(overlay.mailbox.IsSharedImage());
     auto pixmap =
         dependency_->GetSharedImageManager()->GetNativePixmap(overlay.mailbox);
@@ -468,7 +440,7 @@
                                  gfx::ToRoundedRect(overlay.display_rect),
                                  overlay.uv_rect, !overlay.is_opaque,
                                  ZxEventsToGpuFences(frame.acquire_fences),
-                                 std::move(frame.overlays[i].release_fences));
+                                 /*release_fences=*/{});
   }
 
   auto now = base::TimeTicks::Now();
diff --git a/components/viz/service/display_embedder/output_presenter_fuchsia.h b/components/viz/service/display_embedder/output_presenter_fuchsia.h
index fab24914..067a3d0c 100644
--- a/components/viz/service/display_embedder/output_presenter_fuchsia.h
+++ b/components/viz/service/display_embedder/output_presenter_fuchsia.h
@@ -63,18 +63,6 @@
                         std::vector<ScopedOverlayAccess*> accesses) final;
 
  private:
-  struct PendingOverlay {
-    PendingOverlay(OverlayCandidate candidate,
-                   std::vector<gfx::GpuFence> release_fences);
-    ~PendingOverlay();
-
-    PendingOverlay(PendingOverlay&&);
-    PendingOverlay& operator=(PendingOverlay&&);
-
-    OverlayCandidate candidate;
-    std::vector<gfx::GpuFence> release_fences;
-  };
-
   struct PendingFrame {
     explicit PendingFrame(uint32_t ordinal);
     ~PendingFrame();
@@ -98,7 +86,7 @@
     bool remove_buffer_collection = false;
 
     // Vector of overlays that are associated with this frame.
-    std::vector<PendingOverlay> overlays;
+    std::vector<OverlayCandidate> overlays;
   };
 
   struct PresentationState {
diff --git a/components/zucchini/address_translator.cc b/components/zucchini/address_translator.cc
index 20f19b2d..a329d1a 100644
--- a/components/zucchini/address_translator.cc
+++ b/components/zucchini/address_translator.cc
@@ -63,6 +63,8 @@
 
 AddressTranslator::AddressTranslator() = default;
 
+AddressTranslator::AddressTranslator(AddressTranslator&&) = default;
+
 AddressTranslator::~AddressTranslator() = default;
 
 AddressTranslator::Status AddressTranslator::Initialize(
diff --git a/components/zucchini/address_translator.h b/components/zucchini/address_translator.h
index 5666b99b..a517a2c5 100644
--- a/components/zucchini/address_translator.h
+++ b/components/zucchini/address_translator.h
@@ -10,7 +10,6 @@
 #include <tuple>
 #include <vector>
 
-#include "base/macros.h"
 #include "components/zucchini/algorithm.h"
 #include "components/zucchini/image_utils.h"
 
@@ -114,14 +113,14 @@
     // Embeds |translator| for use. Now object lifetime is tied to |translator|
     // lifetime.
     explicit OffsetToRvaCache(const AddressTranslator& translator);
+    OffsetToRvaCache(const OffsetToRvaCache&) = delete;
+    const OffsetToRvaCache& operator=(const OffsetToRvaCache&) = delete;
 
     rva_t Convert(offset_t offset) const;
 
    private:
     const AddressTranslator& translator_;
     mutable const AddressTranslator::Unit* cached_unit_ = nullptr;
-
-    DISALLOW_COPY_AND_ASSIGN(OffsetToRvaCache);
   };
 
   // An adaptor for AddressTranslator::RvaToOffset() that caches the last Unit
@@ -131,6 +130,8 @@
     // Embeds |translator| for use. Now object lifetime is tied to |translator|
     // lifetime.
     explicit RvaToOffsetCache(const AddressTranslator& translator);
+    RvaToOffsetCache(const RvaToOffsetCache&) = delete;
+    const RvaToOffsetCache& operator=(const RvaToOffsetCache&) = delete;
 
     bool IsValid(rva_t rva) const;
 
@@ -139,8 +140,6 @@
    private:
     const AddressTranslator& translator_;
     mutable const AddressTranslator::Unit* cached_unit_ = nullptr;
-
-    DISALLOW_COPY_AND_ASSIGN(RvaToOffsetCache);
   };
 
   enum Status {
@@ -152,6 +151,9 @@
   };
 
   AddressTranslator();
+  AddressTranslator(AddressTranslator&&);
+  AddressTranslator(const AddressTranslator&) = delete;
+  const AddressTranslator& operator=(const AddressTranslator&) = delete;
   ~AddressTranslator();
 
   // Consumes |units| to populate data in this class. Performs consistency
@@ -190,8 +192,6 @@
 
   // Conversion factor to translate between dangling RVAs and fake offsets.
   offset_t fake_offset_begin_;
-
-  DISALLOW_COPY_AND_ASSIGN(AddressTranslator);
 };
 
 }  // namespace zucchini
diff --git a/components/zucchini/disassembler_elf.cc b/components/zucchini/disassembler_elf.cc
index 4727d1c..37cff0b3 100644
--- a/components/zucchini/disassembler_elf.cc
+++ b/components/zucchini/disassembler_elf.cc
@@ -417,35 +417,31 @@
 template <class Traits>
 void DisassemblerElfIntel<Traits>::ParseExecSection(
     const typename Traits::Elf_Shdr& section) {
+  // |this->| is needed to access protected members of templated base class. To
+  // reduce noise, use local references for these.
   ConstBufferView& image_ = this->image_;
+  const AddressTranslator& translator_ = this->translator_;
   auto& abs32_locations_ = this->abs32_locations_;
 
-  std::ptrdiff_t from_offset_to_rva = section.sh_addr - section.sh_offset;
-
   // Range of values was ensured in ParseHeader().
   rva_t start_rva = base::checked_cast<rva_t>(section.sh_addr);
   rva_t end_rva = base::checked_cast<rva_t>(start_rva + section.sh_size);
 
-  AddressTranslator::RvaToOffsetCache target_rva_checker(this->translator_);
+  AddressTranslator::RvaToOffsetCache target_rva_checker(translator_);
 
   ConstBufferView region(image_.begin() + section.sh_offset, section.sh_size);
   Abs32GapFinder gap_finder(image_, region, abs32_locations_, 4);
-  typename Traits::Rel32FinderUse finder;
-  for (auto gap = gap_finder.GetNext(); gap.has_value();
-       gap = gap_finder.GetNext()) {
-    finder.SetRegion(gap.value());
-    for (auto rel32 = finder.GetNext(); rel32.has_value();
-         rel32 = finder.GetNext()) {
-      offset_t rel32_offset =
-          base::checked_cast<offset_t>(rel32->location - image_.begin());
-      rva_t rel32_rva = rva_t(rel32_offset + from_offset_to_rva);
-      DCHECK_NE(rel32_rva, kInvalidRva);
-      rva_t target_rva = rel32_rva + 4 + image_.read<uint32_t>(rel32_offset);
-      if (target_rva_checker.IsValid(target_rva) &&
-          (rel32->can_point_outside_section ||
-           (start_rva <= target_rva && target_rva < end_rva))) {
-        finder.Accept();
-        rel32_locations_.push_back(rel32_offset);
+  typename Traits::Rel32FinderUse rel_finder(image_, translator_);
+  // Iterate over gaps between abs32 references, to avoid collision.
+  while (gap_finder.FindNext()) {
+    rel_finder.SetRegion(gap_finder.GetGap());
+    while (rel_finder.FindNext()) {
+      auto rel32 = rel_finder.GetRel32();
+      if (target_rva_checker.IsValid(rel32.target_rva) &&
+          (rel32.can_point_outside_section ||
+           (start_rva <= rel32.target_rva && rel32.target_rva < end_rva))) {
+        rel_finder.Accept();
+        rel32_locations_.push_back(rel32.location);
       }
     }
   }
diff --git a/components/zucchini/disassembler_win32.cc b/components/zucchini/disassembler_win32.cc
index da830bf7..a23201b 100644
--- a/components/zucchini/disassembler_win32.cc
+++ b/components/zucchini/disassembler_win32.cc
@@ -363,7 +363,6 @@
 
   ParseAndStoreAbs32();
 
-  AddressTranslator::OffsetToRvaCache location_offset_to_rva(translator_);
   AddressTranslator::RvaToOffsetCache target_rva_checker(translator_);
 
   for (const pe::ImageSectionHeader& section : sections_) {
@@ -382,24 +381,18 @@
         image_[{section.file_offset_of_raw_data, size_to_use}];
     Abs32GapFinder gap_finder(image_, region, abs32_locations_,
                               Traits::kVAWidth);
-    typename Traits::RelFinder finder;
+    typename Traits::RelFinder rel_finder(image_, translator_);
     // Iterate over gaps between abs32 references, to avoid collision.
-    for (auto gap = gap_finder.GetNext(); gap.has_value();
-         gap = gap_finder.GetNext()) {
-      finder.SetRegion(gap.value());
-      // Iterate over heuristically detected rel32 references, validate, and add
-      // to |rel32_locations_|.
-      for (auto rel32 = finder.GetNext(); rel32.has_value();
-           rel32 = finder.GetNext()) {
-        offset_t rel32_offset = offset_t(rel32->location - image_.begin());
-        rva_t rel32_rva = location_offset_to_rva.Convert(rel32_offset);
-        DCHECK_NE(rel32_rva, kInvalidRva);
-        rva_t target_rva = rel32_rva + 4 + image_.read<uint32_t>(rel32_offset);
-        if (target_rva_checker.IsValid(target_rva) &&
-            (rel32->can_point_outside_section ||
-             (start_rva <= target_rva && target_rva < end_rva))) {
-          finder.Accept();
-          rel32_locations_.push_back(rel32_offset);
+    while (gap_finder.FindNext()) {
+      rel_finder.SetRegion(gap_finder.GetGap());
+      // Heuristically detect rel32 references, store if valid.
+      while (rel_finder.FindNext()) {
+        auto rel32 = rel_finder.GetRel32();
+        if (target_rva_checker.IsValid(rel32.target_rva) &&
+            (rel32.can_point_outside_section ||
+             (start_rva <= rel32.target_rva && rel32.target_rva < end_rva))) {
+          rel_finder.Accept();
+          rel32_locations_.push_back(rel32.location);
         }
       }
     }
diff --git a/components/zucchini/rel32_finder.cc b/components/zucchini/rel32_finder.cc
index 45810d6e..ccb26f47 100644
--- a/components/zucchini/rel32_finder.cc
+++ b/components/zucchini/rel32_finder.cc
@@ -26,44 +26,43 @@
 
   const offset_t begin_offset =
       base::checked_cast<offset_t>(region.begin() - image.begin());
-  // Find the first |abs32_current_| with |*abs32_current_ >= begin_offset|.
-  abs32_current_ = std::lower_bound(abs32_locations.begin(),
-                                    abs32_locations.end(), begin_offset);
+  // Find the first |abs32_cur_| with |*abs32_cur_ >= begin_offset|.
+  abs32_cur_ = std::lower_bound(abs32_locations.begin(), abs32_locations.end(),
+                                begin_offset);
 
-  // Find lower boundary, accounting for possibility that |abs32_current_[-1]|
+  // Find lower boundary, accounting for the possibility that |abs32_cur_[-1]|
   // may straddle across |region.begin()|.
-  current_lo_ = region.begin();
-  if (abs32_current_ > abs32_locations.begin()) {
-    current_lo_ = std::max(current_lo_,
-                           image.begin() + abs32_current_[-1] + abs32_width_);
-  }
+  cur_lo_ = region.begin();
+  if (abs32_cur_ > abs32_locations.begin())
+    cur_lo_ = std::max(cur_lo_, image.begin() + abs32_cur_[-1] + abs32_width_);
 }
 
 Abs32GapFinder::~Abs32GapFinder() = default;
 
-absl::optional<ConstBufferView> Abs32GapFinder::GetNext() {
-  // Iterate over |[abs32_current_, abs32_end_)| and emit segments.
-  while (abs32_current_ != abs32_end_ &&
-         base_ + *abs32_current_ < region_end_) {
-    ConstBufferView::const_iterator hi = base_ + *abs32_current_;
-    ConstBufferView gap = ConstBufferView::FromRange(current_lo_, hi);
-    current_lo_ = hi + abs32_width_;
-    ++abs32_current_;
-    if (!gap.empty())
-      return gap;
+bool Abs32GapFinder::FindNext() {
+  // Iterate over |[abs32_cur_, abs32_end_)| and emit segments.
+  while (abs32_cur_ != abs32_end_ && base_ + *abs32_cur_ < region_end_) {
+    ConstBufferView::const_iterator hi = base_ + *abs32_cur_;
+    gap_ = ConstBufferView::FromRange(cur_lo_, hi);
+    cur_lo_ = hi + abs32_width_;
+    ++abs32_cur_;
+    if (!gap_.empty())
+      return true;
   }
   // Emit final segment.
-  if (current_lo_ < region_end_) {
-    ConstBufferView gap = ConstBufferView::FromRange(current_lo_, region_end_);
-    current_lo_ = region_end_;
-    return gap;
+  if (cur_lo_ < region_end_) {
+    gap_ = ConstBufferView::FromRange(cur_lo_, region_end_);
+    cur_lo_ = region_end_;
+    return true;
   }
-  return absl::nullopt;
+  return false;
 }
 
 /******** Rel32Finder ********/
 
-Rel32Finder::Rel32Finder() {}
+Rel32Finder::Rel32Finder(ConstBufferView image,
+                         const AddressTranslator& translator)
+    : image_(image), offset_to_rva_(translator) {}
 
 Rel32Finder::~Rel32Finder() = default;
 
@@ -95,7 +94,12 @@
     ConstBufferView::const_iterator cursor,
     uint32_t opcode_size,
     bool can_point_outside_section) {
-  rel32_ = {cursor + opcode_size, can_point_outside_section};
+  offset_t location =
+      base::checked_cast<offset_t>((cursor + opcode_size) - image_.begin());
+  rva_t location_rva = offset_to_rva_.Convert(location);
+  DCHECK_NE(location_rva, kInvalidRva);
+  rva_t target_rva = location_rva + 4 + image_.read<uint32_t>(location);
+  rel32_ = {location, target_rva, can_point_outside_section};
   return {cursor + 1, cursor + (opcode_size + 4)};
 }
 
diff --git a/components/zucchini/rel32_finder.h b/components/zucchini/rel32_finder.h
index 5953755a..96a23b9 100644
--- a/components/zucchini/rel32_finder.h
+++ b/components/zucchini/rel32_finder.h
@@ -9,10 +9,9 @@
 
 #include <vector>
 
-#include "base/macros.h"
+#include "components/zucchini/address_translator.h"
 #include "components/zucchini/buffer_view.h"
 #include "components/zucchini/image_utils.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace zucchini {
 
@@ -49,34 +48,58 @@
                  ConstBufferView region,
                  const std::vector<offset_t>& abs32_locations,
                  size_t abs32_width);
+  Abs32GapFinder(const Abs32GapFinder&) = delete;
+  const Abs32GapFinder& operator=(const Abs32GapFinder&) = delete;
   ~Abs32GapFinder();
 
-  // Returns the next available gap, or nullopt if exhausted.
-  absl::optional<ConstBufferView> GetNext();
+  // Searches for the next available gap, and returns successfulness.
+  bool FindNext();
+
+  // Returns the cached result from the last successful FindNext().
+  ConstBufferView GetGap() const { return gap_; }
 
  private:
   const ConstBufferView::const_iterator base_;
   const ConstBufferView::const_iterator region_end_;
-  ConstBufferView::const_iterator current_lo_;
-  std::vector<offset_t>::const_iterator abs32_current_;
-  std::vector<offset_t>::const_iterator abs32_end_;
-  size_t abs32_width_;
-
-  DISALLOW_COPY_AND_ASSIGN(Abs32GapFinder);
+  ConstBufferView::const_iterator cur_lo_;
+  const std::vector<offset_t>::const_iterator abs32_end_;
+  std::vector<offset_t>::const_iterator abs32_cur_;
+  const size_t abs32_width_;
+  ConstBufferView gap_;
 };
 
 // A class to scan regions within an image to find successive rel32 references.
 // Architecture-specific parsing and result extraction are delegated to
-// inherited classes. This is typically used along with Abs32GapFinder to find
-// search regions.
+// inherited classes (say, Rel32Finder_Impl). Sample extraction loop, combined
+// with Abs32GapFinder usage:
+//
+//   Abs32GapFinder gap_finder(...);
+//   Rel32Finder_Impl finder(...);
+//   while (gap_finder.FindNext()) {
+//     rel_finder.SetRegion(gap_finder.GetGap());
+//     while (rel_finder.FindNext()) {
+//       auto rel32 = rel_finder.GetRel32();  // In Rel32Finder_Impl.
+//       if (architecture_specific_validation(rel32)) {
+//         rel_finder.Accept();
+//         // Store rel32.
+//       }
+//     }
+//   }
 class Rel32Finder {
  public:
-  Rel32Finder();
+  Rel32Finder(ConstBufferView image, const AddressTranslator& translator);
+  Rel32Finder(const Rel32Finder&) = delete;
+  const Rel32Finder& operator=(const Rel32Finder&) = delete;
   virtual ~Rel32Finder();
 
   // Assigns the scan |region| for rel32 references to enable FindNext() use.
   void SetRegion(ConstBufferView region);
 
+  // Scans for the next rel32 reference, and returns whether any is found, so a
+  // "while" loop can be used for iterative rel32 extraction. The results are
+  // cached in Rel32Finder_Impl and obtained by Rel32Finder_Impl::GetRel32().
+  bool FindNext();
+
   // When a rel32 reference is found, the caller needs to decide whether to keep
   // the result (perhaps following more validation). If it decides to keep the
   // result, then it must call Accept(), so the next call to FindNext() can skip
@@ -98,11 +121,6 @@
     ConstBufferView::const_iterator accept;
   };
 
-  // Scans for the next rel32 reference, and returns whether any is found, so a
-  // "while" loop can be used for iterative rel32 extraction. The results are
-  // cached in Rel32Finder_Impl and obtained by Rel32Finder_Impl::GetRel32().
-  bool FindNext();
-
   // Detects and extracts architecture-specific rel32 reference. For each one
   // found, the implementation should cache the necessary data to be retrieved
   // via accessors. Returns a NextIterators that stores alternatives for where
@@ -110,20 +128,25 @@
   // NextIterators are nulls.
   virtual NextIterators Scan(ConstBufferView region) = 0;
 
+  const ConstBufferView image_;
+  AddressTranslator::OffsetToRvaCache offset_to_rva_;
+
  private:
   ConstBufferView region_;
   ConstBufferView::const_iterator accept_it_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(Rel32Finder);
 };
 
 // Parsing for X86 or X64: we perform naive scan for opcodes that have rel32 as
 // an argument, and disregard instruction alignment.
 class Rel32FinderIntel : public Rel32Finder {
  public:
-  // Struct to store GetNext() results.
+  Rel32FinderIntel(const Rel32FinderIntel&) = delete;
+  const Rel32FinderIntel& operator=(const Rel32FinderIntel&) = delete;
+
+  // Struct to store GetRel32() results.
   struct Result {
-    ConstBufferView::const_iterator location;
+    offset_t location;
+    rva_t target_rva;
 
     // Some references must have their target in the same section as location,
     // which we use this to heuristically reject rel32 reference candidates.
@@ -133,12 +156,8 @@
 
   using Rel32Finder::Rel32Finder;
 
-  // Returns the next available Result, or nullopt if exhausted.
-  absl::optional<Result> GetNext() {
-    if (FindNext())
-      return rel32_;
-    return absl::nullopt;
-  }
+  // Returns the cached result from the last successful FindNext().
+  const Result& GetRel32() { return rel32_; }
 
  protected:
   // Helper for Scan() that also assigns |rel32_|.
@@ -151,9 +170,6 @@
 
   // Rel32Finder:
   NextIterators Scan(ConstBufferView region) override = 0;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Rel32FinderIntel);
 };
 
 // X86 instructions.
@@ -161,11 +177,12 @@
  public:
   using Rel32FinderIntel::Rel32FinderIntel;
 
+  Rel32FinderX86(const Rel32FinderX86&) = delete;
+  const Rel32FinderX86& operator=(const Rel32FinderX86&) = delete;
+
  private:
   // Rel32Finder:
   NextIterators Scan(ConstBufferView region) override;
-
-  DISALLOW_COPY_AND_ASSIGN(Rel32FinderX86);
 };
 
 // X64 instructions.
@@ -173,11 +190,12 @@
  public:
   using Rel32FinderIntel::Rel32FinderIntel;
 
+  Rel32FinderX64(const Rel32FinderX64&) = delete;
+  const Rel32FinderX64& operator=(const Rel32FinderX64&) = delete;
+
  private:
   // Rel32Finder:
   NextIterators Scan(ConstBufferView region) override;
-
-  DISALLOW_COPY_AND_ASSIGN(Rel32FinderX64);
 };
 
 }  // namespace zucchini
diff --git a/components/zucchini/rel32_finder_unittest.cc b/components/zucchini/rel32_finder_unittest.cc
index 42a442c..8f274d5 100644
--- a/components/zucchini/rel32_finder_unittest.cc
+++ b/components/zucchini/rel32_finder_unittest.cc
@@ -40,9 +40,10 @@
     Abs32GapFinder gap_finder(image, region, abs32_locations, abs32_width);
 
     std::string out_str;
-    for (auto gap = gap_finder.GetNext(); gap; gap = gap_finder.GetNext()) {
-      size_t lo = static_cast<size_t>(gap->begin() - image.begin());
-      size_t hi = static_cast<size_t>(gap->end() - image.begin());
+    while (gap_finder.FindNext()) {
+      ConstBufferView gap = gap_finder.GetGap();
+      size_t lo = static_cast<size_t>(gap.begin() - image.begin());
+      size_t hi = static_cast<size_t>(gap.end() - image.begin());
       out_str.append(base::StringPrintf("[%" PRIuS ",%" PRIuS ")", lo, hi));
     }
     return out_str;
@@ -125,19 +126,24 @@
   // Rel32Finder:
   NextIterators Scan(ConstBufferView region) override { return next_result; }
 
-  bool GetNext() { return FindNext(); }
-
   NextIterators next_result;
 };
 
+AddressTranslator GetTrivialTranslator(size_t size) {
+  AddressTranslator translator;
+  EXPECT_EQ(AddressTranslator::kSuccess,
+            translator.Initialize({{0, size, 0U, size}}));
+  return translator;
+}
+
 }  // namespace
 
 TEST(Rel32FinderTest, Scan) {
   const size_t kRegionTotal = 99;
   std::vector<uint8_t> buffer(kRegionTotal);
   ConstBufferView image(buffer.data(), buffer.size());
-
-  TestRel32Finder finder;
+  AddressTranslator translator(GetTrivialTranslator(image.size()));
+  TestRel32Finder finder(image, translator);
   finder.SetRegion(image);
 
   auto check_finder_state = [&](const TestRel32Finder& finder,
@@ -153,88 +159,135 @@
   check_finder_state(finder, 0, 0);
 
   finder.next_result = {image.begin() + 1, image.begin() + 1};
-  EXPECT_TRUE(finder.GetNext());
+  EXPECT_TRUE(finder.FindNext());
   check_finder_state(finder, 1, 1);
 
   finder.next_result = {image.begin() + 2, image.begin() + 2};
-  EXPECT_TRUE(finder.GetNext());
+  EXPECT_TRUE(finder.FindNext());
   check_finder_state(finder, 2, 2);
 
   finder.next_result = {image.begin() + 5, image.begin() + 6};
-  EXPECT_TRUE(finder.GetNext());
+  EXPECT_TRUE(finder.FindNext());
   check_finder_state(finder, 5, 6);
   finder.Accept();
   check_finder_state(finder, 6, 6);
 
   finder.next_result = {image.begin() + 7, image.begin() + 7};
-  EXPECT_TRUE(finder.GetNext());
+  EXPECT_TRUE(finder.FindNext());
   check_finder_state(finder, 7, 7);
 
   finder.next_result = {image.begin() + 8, image.begin() + 8};
-  EXPECT_TRUE(finder.GetNext());
+  EXPECT_TRUE(finder.FindNext());
   check_finder_state(finder, 8, 8);
 
   finder.next_result = {image.begin() + 99, image.begin() + 99};
-  EXPECT_TRUE(finder.GetNext());
+  EXPECT_TRUE(finder.FindNext());
   check_finder_state(finder, 99, 99);
 
   finder.next_result = {nullptr, nullptr};
-  EXPECT_FALSE(finder.GetNext());
+  EXPECT_FALSE(finder.FindNext());
   check_finder_state(finder, 99, 99);
 }
 
+namespace {
+
+// X86 test data. (x) and +x entries are covered by abs32 references, which have
+// width = 4.
+constexpr uint8_t kDataX86[] = {
+    0x55,                                // 00: push  ebp
+    0x8B,   0xEC,                        // 01: mov   ebp,esp
+    0xE8,   0,      0,   0,   0,         // 03: call  08
+    (0xE9), +0,     +0,  +0,  0,         // 08: jmp   0D
+    0x0F,   0x80,   0,   0,   0,   0,    // 0D: jo    13
+    0x0F,   0x81,   0,   0,   (0), +0,   // 13: jno   19
+    +0x0F,  +0x82,  0,   0,   0,   0,    // 19: jb    1F
+    0x0F,   0x83,   0,   0,   0,   0,    // 1F: jae   25
+    0x0F,   (0x84), +0,  +0,  +0,  (0),  // 25: je    2B
+    +0x0F,  +0x85,  +0,  0,   0,   0,    // 2B: jne   31
+    0x0F,   0x86,   0,   0,   0,   0,    // 31: jbe   37
+    0x0F,   0x87,   0,   0,   0,   0,    // 37: ja    3D
+    0x0F,   0x88,   0,   (0), +0,  +0,   // 3D: js    43
+    +0x0F,  0x89,   0,   0,   0,   0,    // 43: jns   49
+    0x0F,   0x8A,   0,   0,   0,   0,    // 49: jp    4F
+    0x0F,   0x8B,   (0), +0,  +0,  +0,   // 4F: jnp   55
+    0x0F,   0x8C,   0,   0,   0,   0,    // 55: jl    5B
+    0x0F,   0x8D,   0,   0,   (0), +0,   // 5B: jge   61
+    +0x0F,  +0x8E,  (0), +0,  +0,  +0,   // 61: jle   67
+    0x0F,   0x8F,   0,   0,   0,   0,    // 67: jg    6D
+    0x5D,                                // 6D: pop   ebp
+    0xC3,                                // C3: ret
+};
+
+// Abs32 locations corresponding to |kDataX86|, with width = 4.
+constexpr uint8_t kAbs32X86[] = {0x08, 0x17, 0x26, 0x2A,
+                                 0x40, 0x51, 0x5F, 0x63};
+
+}  // namespace
+
 TEST(Rel32FinderX86Test, FindNext) {
-  constexpr uint8_t data[] = {
-      0x55,                                // 00: push  ebp
-      0x8B, 0xEC,                          // 01: mov   ebp,esp
-      0xE8, 0x00, 0x00, 0x00, 0x00,        // 03: call  08
-      0xE9, 0x00, 0x00, 0x00, 0x00,        // 08: jmp   0D
-      0x0F, 0x80, 0x00, 0x00, 0x00, 0x00,  // 0D: jo    13
-      0x0F, 0x81, 0x00, 0x00, 0x00, 0x00,  // 13: jno   19
-      0x0F, 0x82, 0x00, 0x00, 0x00, 0x00,  // 19: jb    1F
-      0x0F, 0x83, 0x00, 0x00, 0x00, 0x00,  // 1F: jae   25
-      0x0F, 0x84, 0x00, 0x00, 0x00, 0x00,  // 25: je    2B
-      0x0F, 0x85, 0x00, 0x00, 0x00, 0x00,  // 2B: jne   31
-      0x0F, 0x86, 0x00, 0x00, 0x00, 0x00,  // 31: jbe   37
-      0x0F, 0x87, 0x00, 0x00, 0x00, 0x00,  // 37: ja    3D
-      0x0F, 0x88, 0x00, 0x00, 0x00, 0x00,  // 3D: js    43
-      0x0F, 0x89, 0x00, 0x00, 0x00, 0x00,  // 43: jns   49
-      0x0F, 0x8A, 0x00, 0x00, 0x00, 0x00,  // 49: jp    4F
-      0x0F, 0x8B, 0x00, 0x00, 0x00, 0x00,  // 4F: jnp   55
-      0x0F, 0x8C, 0x00, 0x00, 0x00, 0x00,  // 55: jl    5B
-      0x0F, 0x8D, 0x00, 0x00, 0x00, 0x00,  // 5B: jge   61
-      0x0F, 0x8E, 0x00, 0x00, 0x00, 0x00,  // 61: jle   67
-      0x0F, 0x8F, 0x00, 0x00, 0x00, 0x00,  // 67: jg    6D
-      0x5D,                                // 6D: pop   ebp
-      0xC3,                                // C3: ret
-  };
-
   ConstBufferView image =
-      ConstBufferView::FromRange(std::begin(data), std::end(data));
-
-  Rel32FinderX86 rel_finder;
+      ConstBufferView::FromRange(std::begin(kDataX86), std::end(kDataX86));
+  AddressTranslator translator(GetTrivialTranslator(image.size()));
+  Rel32FinderX86 rel_finder(image, translator);
   rel_finder.SetRegion(image);
 
-  // List of expected locations as pairs of {cursor offset, rel32 offset}.
+  // List of expected locations as pairs of {cursor offset, rel32 offset},
+  // ignoring |kAbs32X86|.
   std::vector<std::pair<size_t, size_t>> expected_locations = {
       {0x04, 0x04}, {0x09, 0x09}, {0x0E, 0x0F}, {0x14, 0x15}, {0x1A, 0x1B},
       {0x20, 0x21}, {0x26, 0x27}, {0x2C, 0x2D}, {0x32, 0x33}, {0x38, 0x39},
       {0x3E, 0x3F}, {0x44, 0x45}, {0x4A, 0x4B}, {0x50, 0x51}, {0x56, 0x57},
       {0x5C, 0x5D}, {0x62, 0x63}, {0x68, 0x69},
   };
-
   for (auto location : expected_locations) {
-    auto result = rel_finder.GetNext();
-    EXPECT_TRUE(result.has_value());
+    EXPECT_TRUE(rel_finder.FindNext());
+    auto rel32 = rel_finder.GetRel32();
 
     EXPECT_EQ(location.first,
               size_t(rel_finder.region().begin() - image.begin()));
-    EXPECT_EQ(location.second, size_t(result->location - image.begin()));
-    EXPECT_EQ(result->location + 4, rel_finder.accept_it());
-    EXPECT_FALSE(result->can_point_outside_section);
+    EXPECT_EQ(location.second, rel32.location);
+    EXPECT_EQ(image.begin() + (rel32.location + 4), rel_finder.accept_it());
+    EXPECT_FALSE(rel32.can_point_outside_section);
     rel_finder.Accept();
   }
-  EXPECT_EQ(absl::nullopt, rel_finder.GetNext());
+  EXPECT_FALSE(rel_finder.FindNext());
+}
+
+TEST(Rel32FinderX86Test, Integrated) {
+  // Truncated form of Rel32FinderIntel::Result.
+  typedef std::pair<offset_t, rva_t> TruncatedResults;
+
+  ConstBufferView image =
+      ConstBufferView::FromRange(std::begin(kDataX86), std::end(kDataX86));
+  std::vector<offset_t> abs32_locations(std::begin(kAbs32X86),
+                                        std::end(kAbs32X86));
+  std::vector<TruncatedResults> rel32_results;
+
+  Abs32GapFinder gap_finder(image, image, abs32_locations, 4U);
+  AddressTranslator translator(GetTrivialTranslator(image.size()));
+  Rel32FinderX86 rel_finder(image, translator);
+  while (gap_finder.FindNext()) {
+    auto gap = gap_finder.GetGap();
+    rel_finder.SetRegion(gap_finder.GetGap());
+    while (rel_finder.FindNext()) {
+      auto rel32 = rel_finder.GetRel32();
+      rel32_results.emplace_back(
+          TruncatedResults{rel32.location, rel32.target_rva});
+    }
+  }
+
+  std::vector<TruncatedResults> expected_rel32_results = {
+      {0x04, 0x08},
+      /* {0x09, 0x0D}, */ {0x0F, 0x13},
+      /* {0x15, 0x19}, */ /*{0x1B, 0x1F}, */
+      {0x21, 0x25},
+      /* {0x27, 0x2B}, */ /* {0x2D, 0x31}, */ {0x33, 0x37},
+      {0x39, 0x3D},
+      /* {0x3F, 0x43}, */ /* {0x45, 0x49}, */ {0x4B, 0x4F},
+      /* {0x51, 0x55}, */ {0x57, 0x5B},
+      /* {0x5D, 0x61}, */ /* {0x63, 0x67}, */ {0x69, 0x6D},
+  };
+  EXPECT_EQ(expected_rel32_results, rel32_results);
 }
 
 TEST(Rel32FinderX86Test, Accept) {
@@ -247,13 +300,14 @@
   ConstBufferView image =
       ConstBufferView::FromRange(std::begin(data), std::end(data));
 
-  auto next_location = [&](Rel32FinderX86& rel_finder) -> size_t {
-    auto result = rel_finder.GetNext();
-    EXPECT_TRUE(result.has_value());
-    return result->location - image.begin();
+  auto next_location = [](Rel32FinderX86& rel_finder) -> offset_t {
+    EXPECT_TRUE(rel_finder.FindNext());
+    auto rel32 = rel_finder.GetRel32();
+    return rel32.location;
   };
 
-  Rel32FinderX86 rel_finder;
+  AddressTranslator translator(GetTrivialTranslator(image.size()));
+  Rel32FinderX86 rel_finder(image, translator);
   rel_finder.SetRegion(image);
 
   EXPECT_EQ(0x05U, next_location(rel_finder));  // False positive.
@@ -264,57 +318,68 @@
   EXPECT_EQ(0x0BU, next_location(rel_finder));  // Found if 0x0A is discarded.
 }
 
+namespace {
+
+// X64 test data. (x) and +x entries are covered by abs32 references, which have
+// width = 8.
+constexpr uint8_t kDataX64[] = {
+    0x55,                                      // 00: push  ebp
+    0x8B,   0xEC,                              // 01: mov   ebp,esp
+    0xE8,   0,      0,     0,   0,             // 03: call  08
+    0xE9,   0,      0,     0,   (0),           // 08: jmp   0D
+    +0x0F,  +0x80,  +0,    +0,  +0,  +0,       // 0D: jo    13
+    +0x0F,  0x81,   0,     0,   0,   0,        // 13: jno   19
+    0x0F,   0x82,   0,     0,   0,   0,        // 19: jb    1F
+    (0x0F), +0x83,  +0,    +0,  +0,  +0,       // 1F: jae   25
+    +0x0F,  +0x84,  0,     0,   0,   0,        // 25: je    2B
+    0x0F,   0x85,   0,     0,   0,   0,        // 2B: jne   31
+    0x0F,   0x86,   (0),   +0,  +0,  +0,       // 31: jbe   37
+    +0x0F,  +0x87,  +0,    +0,  (0), +0,       // 37: ja    3D
+    +0x0F,  +0x88,  +0,    +0,  +0,  +0,       // 3D: js    43
+    0x0F,   0x89,   0,     0,   0,   0,        // 43: jns   49
+    (0x0F), +0x8A,  +0,    +0,  +0,  +0,       // 49: jp    4F
+    +0x0F,  +0x8B,  0,     0,   0,   0,        // 4F: jnp   55
+    0x0F,   0x8C,   0,     0,   0,   0,        // 55: jl    5B
+    0x0F,   0x8D,   0,     0,   0,   0,        // 5B: jge   61
+    0x0F,   0x8E,   0,     0,   0,   0,        // 61: jle   67
+    0x0F,   0x8F,   0,     (0), +0,  +0,       // 67: jg    6F
+    +0xFF,  +0x15,  +0,    +0,  +0,  0,        // 6D: call  [rip+00]      # 73
+    0xFF,   0x25,   0,     0,   0,   0,        // 73: jmp   [rip+00]      # 79
+    0x8B,   0x05,   0,     0,   0,   0,        // 79: mov   eax,[rip+00]  # 7F
+    0x8B,   0x3D,   0,     0,   0,   0,        // 7F: mov   edi,[rip+00]  # 85
+    0x8D,   0x05,   0,     0,   0,   0,        // 85: lea   eax,[rip+00]  # 8B
+    0x8D,   0x3D,   0,     0,   0,   0,        // 8B: lea   edi,[rip+00]  # 91
+    0x48,   0x8B,   0x05,  0,   0,   0,  0,    // 91: mov   rax,[rip+00]  # 98
+    0x48,   (0x8B), +0x3D, +0,  +0,  +0, +0,   // 98: mov   rdi,[rip+00]  # 9F
+    +0x48,  +0x8D,  0x05,  0,   0,   0,  0,    // 9F: lea   rax,[rip+00]  # A6
+    0x48,   0x8D,   0x3D,  0,   0,   0,  0,    // A6: lea   rdi,[rip+00]  # AD
+    0x4C,   0x8B,   0x05,  0,   0,   0,  (0),  // AD: mov   r8,[rip+00]   # B4
+    +0x4C,  +0x8B,  +0x3D, +0,  +0,  +0, +0,   // B4: mov   r15,[rip+00]  # BB
+    0x4C,   0x8D,   0x05,  0,   0,   0,  0,    // BB: lea   r8,[rip+00]   # C2
+    0x4C,   0x8D,   0x3D,  0,   0,   0,  0,    // C2: lea   r15,[rip+00]  # C9
+    0x66,   0x8B,   0x05,  (0), +0,  +0, +0,   // C9: mov   ax,[rip+00]   # D0
+    +0x66,  +0x8B,  +0x3D, +0,  0,   0,  0,    // D0: mov   di,[rip+00]   # D7
+    0x66,   0x8D,   0x05,  0,   0,   0,  0,    // D7: lea   ax,[rip+00]   # DE
+    0x66,   0x8D,   0x3D,  0,   0,   0,  0,    // DE: lea   di,[rip+00]   # E5
+    0x5D,                                      // E5: pop   ebp
+    0xC3,                                      // E6: ret
+};
+
+// Abs32 locations corresponding to |kDataX64|, with width = 8.
+constexpr uint8_t kAbs32X64[] = {0x0C, 0x1F, 0x33, 0x3B, 0x49,
+                                 0x6A, 0x99, 0xB3, 0xCC};
+
+}  // namespace
+
 TEST(Rel32FinderX64Test, FindNext) {
-  constexpr uint8_t data[] = {
-      0x55,                                      // 00: push  ebp
-      0x8B, 0xEC,                                // 01: mov   ebp,esp
-      0xE8, 0x00, 0x00, 0x00, 0x00,              // 03: call  08
-      0xE9, 0x00, 0x00, 0x00, 0x00,              // 08: jmp   0D
-      0x0F, 0x80, 0x00, 0x00, 0x00, 0x00,        // 0D: jo    13
-      0x0F, 0x81, 0x00, 0x00, 0x00, 0x00,        // 13: jno   19
-      0x0F, 0x82, 0x00, 0x00, 0x00, 0x00,        // 19: jb    1F
-      0x0F, 0x83, 0x00, 0x00, 0x00, 0x00,        // 1F: jae   25
-      0x0F, 0x84, 0x00, 0x00, 0x00, 0x00,        // 25: je    2B
-      0x0F, 0x85, 0x00, 0x00, 0x00, 0x00,        // 2B: jne   31
-      0x0F, 0x86, 0x00, 0x00, 0x00, 0x00,        // 31: jbe   37
-      0x0F, 0x87, 0x00, 0x00, 0x00, 0x00,        // 37: ja    3D
-      0x0F, 0x88, 0x00, 0x00, 0x00, 0x00,        // 3D: js    43
-      0x0F, 0x89, 0x00, 0x00, 0x00, 0x00,        // 43: jns   49
-      0x0F, 0x8A, 0x00, 0x00, 0x00, 0x00,        // 49: jp    4F
-      0x0F, 0x8B, 0x00, 0x00, 0x00, 0x00,        // 4F: jnp   55
-      0x0F, 0x8C, 0x00, 0x00, 0x00, 0x00,        // 55: jl    5B
-      0x0F, 0x8D, 0x00, 0x00, 0x00, 0x00,        // 5B: jge   61
-      0x0F, 0x8E, 0x00, 0x00, 0x00, 0x00,        // 61: jle   67
-      0x0F, 0x8F, 0x00, 0x00, 0x00, 0x00,        // 67: jg    6F
-      0xFF, 0x15, 0x00, 0x00, 0x00, 0x00,        // 6D: call  [rip+00]
-      0xFF, 0x25, 0x00, 0x00, 0x00, 0x00,        // 73: jmp   [rip+00]
-      0x8B, 0x05, 0x00, 0x00, 0x00, 0x00,        // 79: mov   eax,[rip+00]
-      0x8B, 0x3D, 0x00, 0x00, 0x00, 0x00,        // 7F: mov   edi,[rip+00]
-      0x8D, 0x05, 0x00, 0x00, 0x00, 0x00,        // 85: lea   eax,[rip+00]
-      0x8D, 0x3D, 0x00, 0x00, 0x00, 0x00,        // 8B: lea   edi,[rip+00]
-      0x48, 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00,  // 91: mov   rax,[rip+00]
-      0x48, 0x8B, 0x3D, 0x00, 0x00, 0x00, 0x00,  // 98: mov   rdi,[rip+00]
-      0x48, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x00,  // 9F: lea   rax,[rip+00]
-      0x48, 0x8D, 0x3D, 0x00, 0x00, 0x00, 0x00,  // A6: lea   rdi,[rip+00]
-      0x4C, 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00,  // AD: mov   r8,[rip+00]
-      0x4C, 0x8B, 0x3D, 0x00, 0x00, 0x00, 0x00,  // B4: mov   r15,[rip+00]
-      0x4C, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x00,  // BB: lea   r8,[rip+00]
-      0x4C, 0x8D, 0x3D, 0x00, 0x00, 0x00, 0x00,  // C2: lea   r15,[rip+00]
-      0x66, 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00,  // C9: mov   ax,[rip+00]
-      0x66, 0x8B, 0x3D, 0x00, 0x00, 0x00, 0x00,  // D0: mov   di,[rip+00]
-      0x66, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x00,  // D7: lea   ax,[rip+00]
-      0x66, 0x8D, 0x3D, 0x00, 0x00, 0x00, 0x00,  // DE: lea   di,[rip+00]
-      0x5D,                                      // E5: pop   ebp
-      0xC3,                                      // E6: ret
-  };
-
   ConstBufferView image =
-      ConstBufferView::FromRange(std::begin(data), std::end(data));
-
-  Rel32FinderX64 rel_finder;
+      ConstBufferView::FromRange(std::begin(kDataX64), std::end(kDataX64));
+  AddressTranslator translator(GetTrivialTranslator(image.size()));
+  Rel32FinderX64 rel_finder(image, translator);
   rel_finder.SetRegion(image);
 
-  // Lists of expected locations as pairs of {cursor offset, rel32 offset}.
+  // Lists of expected locations as pairs of {cursor offset, rel32 offset},
+  // ignoring |kAbs32X64|.
   std::vector<std::pair<size_t, size_t>> expected_locations = {
       {0x04, 0x04}, {0x09, 0x09}, {0x0E, 0x0F}, {0x14, 0x15}, {0x1A, 0x1B},
       {0x20, 0x21}, {0x26, 0x27}, {0x2C, 0x2D}, {0x32, 0x33}, {0x38, 0x39},
@@ -329,29 +394,76 @@
   };
   // Jump instructions, which cannot point outside section.
   for (auto location : expected_locations) {
-    auto result = rel_finder.GetNext();
-    EXPECT_TRUE(result.has_value());
+    EXPECT_TRUE(rel_finder.FindNext());
+    auto rel32 = rel_finder.GetRel32();
     EXPECT_EQ(location.first,
               size_t(rel_finder.region().begin() - image.begin()));
-    EXPECT_EQ(location.second, size_t(result->location - image.begin()));
-    EXPECT_EQ(result->location + 4, rel_finder.accept_it());
-    EXPECT_FALSE(result->can_point_outside_section);
+    EXPECT_EQ(location.second, rel32.location);
+    EXPECT_EQ(image.begin() + (rel32.location + 4), rel_finder.accept_it());
+    EXPECT_FALSE(rel32.can_point_outside_section);
     rel_finder.Accept();
   }
   // PC-relative data access instructions, which can point outside section.
   for (auto location : expected_locations_rip) {
-    auto result = rel_finder.GetNext();
-    EXPECT_TRUE(result.has_value());
+    EXPECT_TRUE(rel_finder.FindNext());
+    auto rel32 = rel_finder.GetRel32();
     EXPECT_EQ(location.first,
               size_t(rel_finder.region().begin() - image.begin()));
-    EXPECT_EQ(location.second, size_t(result->location - image.begin()));
-    EXPECT_EQ(result->location + 4, rel_finder.accept_it());
-    EXPECT_TRUE(result->can_point_outside_section);
+    EXPECT_EQ(location.second, rel32.location);
+    EXPECT_EQ(image.begin() + (rel32.location + 4), rel_finder.accept_it());
+    EXPECT_TRUE(rel32.can_point_outside_section);  // Different from before.
     rel_finder.Accept();
   }
-  EXPECT_EQ(absl::nullopt, rel_finder.GetNext());
+  EXPECT_FALSE(rel_finder.FindNext());
 }
 
-// TODO(huangs): Test that integrates Abs32GapFinder and Rel32Finder.
+TEST(Rel32FinderX64Test, Integrated) {
+  // Truncated form of Rel32FinderIntel::Result.
+  typedef std::pair<offset_t, rva_t> TruncatedResults;
+
+  ConstBufferView image =
+      ConstBufferView::FromRange(std::begin(kDataX64), std::end(kDataX64));
+  std::vector<offset_t> abs32_locations(std::begin(kAbs32X64),
+                                        std::end(kAbs32X64));
+  std::vector<TruncatedResults> rel32_results;
+
+  Abs32GapFinder gap_finder(image, image, abs32_locations, 8U);
+  AddressTranslator translator(GetTrivialTranslator(image.size()));
+  Rel32FinderX64 rel_finder(image, translator);
+  while (gap_finder.FindNext()) {
+    auto gap = gap_finder.GetGap();
+    rel_finder.SetRegion(gap_finder.GetGap());
+    while (rel_finder.FindNext()) {
+      auto rel32 = rel_finder.GetRel32();
+      rel32_results.emplace_back(
+          TruncatedResults{rel32.location, rel32.target_rva});
+    }
+  }
+
+  std::vector<TruncatedResults> expected_rel32_results = {
+      {0x04, 0x08},
+      /* {0x09, 0x0D}, */
+      /*{0x0F, 0x13}, */ /* {0x15, 0x19}, */ {0x1B, 0x1F},
+      /* {0x21, 0x25}, */ /* {0x27, 0x2B}, */ {0x2D, 0x31},
+      /* {0x33, 0x37}, */ /* {0x39, 0x3D}, */
+      /* {0x3F, 0x43}, */ {0x45, 0x49},
+      /* {0x4B, 0x4F}, */ /* {0x51, 0x55}, */
+      {0x57, 0x5B},
+      {0x5D, 0x61},
+      {0x63, 0x67}, /* {0x69, 0x6F}, */
+      /* {0x6F, 0x73}, */ {0x75, 0x79},
+      {0x7B, 0x7F},
+      {0x81, 0x85},
+      {0x87, 0x8B},
+      {0x8D, 0x91},
+      {0x94, 0x98},
+      /* {0x9B, 0x9F}, */ /* {0xA2, 0xA6}, */ {0xA9, 0xAD},
+      /* {0xB0, 0xB4}, */ /* {0xB7, 0xBB}, */ {0xBE, 0xC2},
+      {0xC5, 0xC9},
+      /* {0xCC, 0xD0}, */ /* {0xD3, 0xD7}, */ {0xDA, 0xDE},
+      {0xE1, 0xE5},
+  };
+  EXPECT_EQ(expected_rel32_results, rel32_results);
+}
 
 }  // namespace zucchini
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 78d323c..54b653f 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -2946,6 +2946,10 @@
       FILE_PATH_LITERAL("content-visibility-with-pseudo-element.html"));
 }
 
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, ContentVisibilityLabel) {
+  RunRegressionTest(FILE_PATH_LITERAL("content-visibility-label.html"));
+}
+
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, DisplayContentsSelectCrash) {
   RunRegressionTest(FILE_PATH_LITERAL("display-contents-select-crash.html"));
 }
diff --git a/content/browser/cache_storage/cache_storage_context_impl.cc b/content/browser/cache_storage/cache_storage_context_impl.cc
index 05f6d21..327d150 100644
--- a/content/browser/cache_storage/cache_storage_context_impl.cc
+++ b/content/browser/cache_storage/cache_storage_context_impl.cc
@@ -60,6 +60,7 @@
     mojo::PendingRemote<storage::mojom::BlobStorageContext>
         blob_storage_context) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(quota_manager_proxy);
 
   receivers_.Add(this, std::move(control));
   is_incognito_ = user_data_directory.empty();
@@ -76,9 +77,6 @@
       base::MakeRefCounted<BlobStorageContextWrapper>(
           std::move(blob_storage_context)));
 
-  if (!quota_manager_proxy)
-    return;
-
   mojo::PendingRemote<storage::mojom::QuotaClient> cache_storage_client;
   mojo::MakeSelfOwnedReceiver(
       std::make_unique<CacheStorageQuotaClient>(
diff --git a/content/browser/cache_storage/cache_storage_control_wrapper.cc b/content/browser/cache_storage/cache_storage_control_wrapper.cc
index 75d8f1c5..5daa9e3 100644
--- a/content/browser/cache_storage/cache_storage_control_wrapper.cc
+++ b/content/browser/cache_storage/cache_storage_control_wrapper.cc
@@ -14,6 +14,7 @@
     mojo::PendingRemote<storage::mojom::BlobStorageContext>
         blob_storage_context) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(quota_manager_proxy);
 
   cache_storage_context_ = base::SequenceBound<CacheStorageContextImpl>(
       CacheStorageContextImpl::CreateSchedulerTaskRunner());
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_manager.cc b/content/browser/cache_storage/legacy/legacy_cache_storage_manager.cc
index ad5e580..178bb2a 100644
--- a/content/browser/cache_storage/legacy/legacy_cache_storage_manager.cc
+++ b/content/browser/cache_storage/legacy/legacy_cache_storage_manager.cc
@@ -245,6 +245,11 @@
     scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner,
     scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
     scoped_refptr<BlobStorageContextWrapper> blob_storage_context) {
+  DCHECK(cache_task_runner);
+  DCHECK(scheduler_task_runner);
+  DCHECK(quota_manager_proxy);
+  DCHECK(blob_storage_context);
+
   base::FilePath root_path = path;
   if (!path.empty()) {
     root_path = path.Append(storage::kServiceWorkerDirectory)
@@ -527,7 +532,12 @@
       cache_task_runner_(std::move(cache_task_runner)),
       scheduler_task_runner_(std::move(scheduler_task_runner)),
       quota_manager_proxy_(std::move(quota_manager_proxy)),
-      blob_storage_context_(std::move(blob_storage_context)) {}
+      blob_storage_context_(std::move(blob_storage_context)) {
+  DCHECK(cache_task_runner_);
+  DCHECK(scheduler_task_runner_);
+  DCHECK(quota_manager_proxy_);
+  DCHECK(blob_storage_context_);
+}
 
 // static
 base::FilePath LegacyCacheStorageManager::ConstructOriginPath(
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_manager.h b/content/browser/cache_storage/legacy/legacy_cache_storage_manager.h
index 396323ea..f89c81d 100644
--- a/content/browser/cache_storage/legacy/legacy_cache_storage_manager.h
+++ b/content/browser/cache_storage/legacy/legacy_cache_storage_manager.h
@@ -147,10 +147,10 @@
       base::MemoryPressureListener::MemoryPressureLevel level);
 
   base::FilePath root_path_;
-  scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
-  scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
+  const scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner_;
 
-  scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
+  const scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
 
   // The map owns the CacheStorages and the CacheStorages are only accessed on
   // |cache_task_runner_|.
@@ -158,7 +158,7 @@
 
   mojo::RemoteSet<storage::mojom::CacheStorageObserver> observers_;
 
-  scoped_refptr<BlobStorageContextWrapper> blob_storage_context_;
+  const scoped_refptr<BlobStorageContextWrapper> blob_storage_context_;
 
   std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
 
diff --git a/content/browser/conversions/PRESUBMIT.py b/content/browser/conversions/PRESUBMIT.py
index 9238adcf..a4b9864 100644
--- a/content/browser/conversions/PRESUBMIT.py
+++ b/content/browser/conversions/PRESUBMIT.py
@@ -13,7 +13,7 @@
 
   Whenever any of the following files is changed:
     - conversion_storage_sql.cc
-    - conversion_storage_sql_initializer.cc
+    - conversion_storage_sql_migrations.cc
   and kCurrentVersionNumber stays intact, this check returns a
   presubmit warning to make sure the value is updated if necessary.
   """
@@ -39,7 +39,7 @@
     out.append(output_api.PresubmitPromptWarning(
         'Please make sure that the conversions database is properly versioned '
         'and migrated when making changes to schema or table contents. '
-        'kCurrentVersionNumber in conversion_storage_sql_initializer.cc '
+        'kCurrentVersionNumber in conversion_storage_sql.cc '
         'must be updated when doing a migration.'))
   return out
 
diff --git a/content/browser/conversions/conversion_internals_browsertest.cc b/content/browser/conversions/conversion_internals_browsertest.cc
index e0457a5..9d3a072 100644
--- a/content/browser/conversions/conversion_internals_browsertest.cc
+++ b/content/browser/conversions/conversion_internals_browsertest.cc
@@ -89,8 +89,8 @@
   // Execute script to ensure the page has loaded correctly, executing similarly
   // to ExecJsInWebUI().
   EXPECT_EQ(true, EvalJs(shell()->web_contents()->GetMainFrame(),
-                         "document.body.innerHTML.search('Conversion "
-                         "Measurement API Internals') >= 0;",
+                         "document.body.innerHTML.search('Attribution "
+                         "Reporting API Internals') >= 0;",
                          EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1));
 }
 
@@ -156,11 +156,11 @@
   OverrideWebUIConversionManager(&manager);
 
   std::string wait_script = R"(
-    let table = document.getElementById("impression-table-body");
+    let table = document.getElementById("source-table-body");
     let obs = new MutationObserver(() => {
       if (table.children.length === 1 &&
           table.children[0].children[0].innerText ===
-          "No active impressions.") {
+          "No active sources.") {
         document.title = $1;
       }
     });
@@ -192,7 +192,7 @@
   OverrideWebUIConversionManager(&manager);
 
   std::string wait_script = R"(
-    let table = document.getElementById("impression-table-body");
+    let table = document.getElementById("source-table-body");
     let obs = new MutationObserver(() => {
       if (table.children.length === 2 &&
           table.children[0].children[0].innerText === $1 &&
diff --git a/content/browser/conversions/conversion_storage_unittest.cc b/content/browser/conversions/conversion_storage_unittest.cc
index 4cc24d0..59e032a 100644
--- a/content/browser/conversions/conversion_storage_unittest.cc
+++ b/content/browser/conversions/conversion_storage_unittest.cc
@@ -833,6 +833,8 @@
   EXPECT_FALSE(storage()->MaybeCreateAndStoreConversionReport(conversion));
   EXPECT_FALSE(storage()->MaybeCreateAndStoreConversionReport(conversion));
 
+  clock()->Advance(base::TimeDelta::FromMilliseconds(kReportTime));
+
   std::vector<ConversionReport> actual_reports =
       storage()->GetConversionsToReport(clock()->Now());
   EXPECT_TRUE(ReportsEqual({}, actual_reports));
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index ffcbbce..d23d89b 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -708,7 +708,10 @@
     INTERNAL_READ_ERROR(SET_UP_METADATA);
     return s;
   }
-  indexed_db::ReportSchemaVersion(db_schema_version, origin_);
+  indexed_db::ReportSchemaVersion(
+      db_schema_version,
+      // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+      blink::StorageKey(origin_));
   if (!found) {
     // Initialize new backing store.
     db_schema_version = indexed_db::kLatestKnownSchemaVersion;
@@ -790,7 +793,8 @@
   if (!s.ok()) {
     indexed_db::ReportOpenStatus(
         indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_METADATA_SETUP,
-        origin_);
+        // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+        blink::StorageKey(origin_));
     INTERNAL_WRITE_ERROR(SET_UP_METADATA);
     return s;
   }
@@ -801,7 +805,8 @@
       indexed_db::ReportOpenStatus(
           indexed_db::
               INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR,
-          origin_);
+          // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+          blink::StorageKey(origin_));
     }
   }
 #if DCHECK_IS_ON()
@@ -3140,7 +3145,10 @@
     INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA);
     return InternalInconsistencyStatus();
   }
-  indexed_db::ReportV2Schema(has_blobs, origin_);
+  indexed_db::ReportV2Schema(
+      has_blobs,
+      // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+      blink::StorageKey(origin_));
   if (has_blobs) {
     INTERNAL_CONSISTENCY_ERROR(UPGRADING_SCHEMA_CORRUPTED_BLOBS);
     if (origin_.host() != "docs.google.com")
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc
index 08bac643..72b3be52 100644
--- a/content/browser/indexed_db/indexed_db_factory_impl.cc
+++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -110,8 +110,10 @@
         leveldb::Status::IOError("Unable to create IndexedDB database path");
     LOG(ERROR) << status.ToString() << ": \"" << path_base.AsUTF8Unsafe()
                << "\"";
-    ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY,
-                     origin);
+    ReportOpenStatus(
+        indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY,
+        // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+        blink::StorageKey(origin));
     return {base::FilePath(), base::FilePath(), status};
   }
 
@@ -122,8 +124,10 @@
       // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
       indexed_db::GetBlobStoreFileName(blink::StorageKey(origin)));
   if (indexed_db::IsPathTooLong(filesystem, leveldb_path)) {
-    ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG,
-                     origin);
+    ReportOpenStatus(
+        indexed_db::INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG,
+        // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+        blink::StorageKey(origin));
     status = leveldb::Status::IOError("File path too long");
     return {base::FilePath(), base::FilePath(), status};
   }
@@ -715,8 +719,10 @@
   }
 
   if (UNLIKELY(!s.ok())) {
-    ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY,
-                     origin);
+    ReportOpenStatus(
+        indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY,
+        // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+        blink::StorageKey(origin));
 
     if (disk_full) {
       context_->quota_manager_proxy()->NotifyWriteFailed(origin);
@@ -738,15 +744,20 @@
       LevelDBScopes::TaskRunnerMode::kNewCleanupAndRevertSequences);
 
   if (UNLIKELY(!s.ok())) {
-    ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY,
-                     origin);
+    ReportOpenStatus(
+        indexed_db::INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY,
+        // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+        blink::StorageKey(origin));
 
     return {IndexedDBOriginStateHandle(), s, CreateDefaultError(),
             data_loss_info, /*was_cold_open=*/true};
   }
 
   if (!is_incognito_and_in_memory)
-    ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_SUCCESS, origin);
+    ReportOpenStatus(
+        indexed_db::INDEXED_DB_BACKING_STORE_OPEN_SUCCESS,
+        // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+        blink::StorageKey(origin));
 
   auto run_tasks_callback = base::BindRepeating(
       &IndexedDBFactoryImpl::MaybeRunTasksForOrigin,
@@ -834,7 +845,8 @@
       if (is_first_attempt) {
         ReportOpenStatus(
             indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION,
-            origin);
+            // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+            blink::StorageKey(origin));
       }
       data_loss_info.status = blink::mojom::IDBDataLoss::Total;
       data_loss_info.message = base::StrCat(
@@ -903,14 +915,16 @@
     ReportOpenStatus(
         indexed_db::
             INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA,
-        origin);
+        // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+        blink::StorageKey(origin));
     return {nullptr, status, std::move(data_loss_info), /*is_disk_full=*/false};
   } else if (UNLIKELY(!are_schemas_known)) {
     LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it as "
                   "failure to open.";
     ReportOpenStatus(
         indexed_db::INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_SCHEMA,
-        origin);
+        // TODO(crbug.com/1210555): Propagate StorageKey up the chain.
+        blink::StorageKey(origin));
     return {nullptr, leveldb::Status::Corruption("Unknown IndexedDB schema"),
             std::move(data_loss_info), /*is_disk_full=*/false};
   }
diff --git a/content/browser/indexed_db/indexed_db_reporting.cc b/content/browser/indexed_db/indexed_db_reporting.cc
index 40ca445..94e6597 100644
--- a/content/browser/indexed_db/indexed_db_reporting.cc
+++ b/content/browser/indexed_db/indexed_db_reporting.cc
@@ -11,15 +11,16 @@
 #include "base/strings/strcat.h"
 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
 #include "content/browser/indexed_db/indexed_db_leveldb_env.h"
-#include "url/origin.h"
+#include "third_party/blink/public/common/storage_key/storage_key.h"
 
 namespace content {
 namespace indexed_db {
 
 namespace {
 
-std::string OriginToCustomHistogramSuffix(const url::Origin& origin) {
-  if (origin.host() == "docs.google.com")
+std::string StorageKeyToCustomHistogramSuffix(
+    const blink::StorageKey& storage_key) {
+  if (storage_key.origin().host() == "docs.google.com")
     return ".Docs";
   return std::string();
 }
@@ -63,10 +64,10 @@
 }  // namespace
 
 void ReportOpenStatus(IndexedDBBackingStoreOpenResult result,
-                      const url::Origin& origin) {
+                      const blink::StorageKey& storage_key) {
   base::UmaHistogramEnumeration("WebCore.IndexedDB.BackingStore.OpenStatus",
                                 result, INDEXED_DB_BACKING_STORE_OPEN_MAX);
-  const std::string suffix = OriginToCustomHistogramSuffix(origin);
+  const std::string suffix = StorageKeyToCustomHistogramSuffix(storage_key);
   // Data from the WebCore.IndexedDB.BackingStore.OpenStatus histogram is used
   // to generate a graph. So as not to alter the meaning of that graph,
   // continue to collect all stats there (above) but also now collect docs stats
@@ -90,10 +91,10 @@
       ->Add(location);
 }
 
-void ReportSchemaVersion(int version, const url::Origin& origin) {
+void ReportSchemaVersion(int version, const blink::StorageKey& storage_key) {
   UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.SchemaVersion", version,
                             kLatestKnownSchemaVersion + 1);
-  const std::string suffix = OriginToCustomHistogramSuffix(origin);
+  const std::string suffix = StorageKeyToCustomHistogramSuffix(storage_key);
   if (!suffix.empty()) {
     base::LinearHistogram::FactoryGet(
         base::StrCat({"WebCore.IndexedDB.SchemaVersion", suffix}), 0,
@@ -104,10 +105,11 @@
   }
 }
 
-void ReportV2Schema(bool has_broken_blobs, const url::Origin& origin) {
+void ReportV2Schema(bool has_broken_blobs,
+                    const blink::StorageKey& storage_key) {
   base::UmaHistogramBoolean("WebCore.IndexedDB.SchemaV2HasBlobs",
                             has_broken_blobs);
-  const std::string suffix = OriginToCustomHistogramSuffix(origin);
+  const std::string suffix = StorageKeyToCustomHistogramSuffix(storage_key);
   if (!suffix.empty()) {
     base::BooleanHistogram::FactoryGet(
         base::StrCat({"WebCore.IndexedDB.SchemaV2HasBlobs", suffix}),
diff --git a/content/browser/indexed_db/indexed_db_reporting.h b/content/browser/indexed_db/indexed_db_reporting.h
index e56f822d..bf4f0581 100644
--- a/content/browser/indexed_db/indexed_db_reporting.h
+++ b/content/browser/indexed_db/indexed_db_reporting.h
@@ -10,8 +10,8 @@
 #include "base/logging.h"
 #include "third_party/leveldatabase/src/include/leveldb/status.h"
 
-namespace url {
-class Origin;
+namespace blink {
+class StorageKey;
 }
 
 namespace content {
@@ -92,14 +92,15 @@
 };
 
 void ReportOpenStatus(IndexedDBBackingStoreOpenResult result,
-                      const url::Origin& origin);
+                      const blink::StorageKey& storage_key);
 
 void ReportInternalError(const char* type,
                          IndexedDBBackingStoreErrorSource location);
 
-void ReportSchemaVersion(int version, const url::Origin& origin);
+void ReportSchemaVersion(int version, const blink::StorageKey& storage_key);
 
-void ReportV2Schema(bool has_broken_blobs, const url::Origin& origin);
+void ReportV2Schema(bool has_broken_blobs,
+                    const blink::StorageKey& storage_key);
 
 void ReportLevelDBError(const std::string& histogram_name,
                         const leveldb::Status& s);
diff --git a/content/browser/renderer_host/frame_tree_node.cc b/content/browser/renderer_host/frame_tree_node.cc
index 1faf917..890db2b 100644
--- a/content/browser/renderer_host/frame_tree_node.cc
+++ b/content/browser/renderer_host/frame_tree_node.cc
@@ -135,7 +135,7 @@
           false /* is a potentially trustworthy unique origin */,
           false /* has an active user gesture */,
           false /* has received a user gesture before nav */,
-          blink::mojom::AdFrameType::kNonAd)),
+          false /* is_ad_subframe */)),
       is_created_by_script_(is_created_by_script),
       devtools_frame_token_(devtools_frame_token),
       frame_owner_properties_(frame_owner_properties),
@@ -781,12 +781,12 @@
   }
 }
 
-void FrameTreeNode::SetAdFrameType(blink::mojom::AdFrameType ad_frame_type) {
-  if (ad_frame_type == replication_state_->ad_frame_type)
+void FrameTreeNode::SetIsAdSubframe(bool is_ad_subframe) {
+  if (is_ad_subframe == replication_state_->is_ad_subframe)
     return;
 
-  replication_state_->ad_frame_type = ad_frame_type;
-  render_manager()->OnDidSetAdFrameType(ad_frame_type);
+  replication_state_->is_ad_subframe = is_ad_subframe;
+  render_manager()->OnDidSetIsAdSubframe(is_ad_subframe);
 }
 
 void FrameTreeNode::SetInitialPopupURL(const GURL& initial_popup_url) {
diff --git a/content/browser/renderer_host/frame_tree_node.h b/content/browser/renderer_host/frame_tree_node.h
index a14ddd69..51eefe3 100644
--- a/content/browser/renderer_host/frame_tree_node.h
+++ b/content/browser/renderer_host/frame_tree_node.h
@@ -428,7 +428,7 @@
     return tree_scope_type_;
   }
 
-  void SetAdFrameType(blink::mojom::AdFrameType ad_frame_type);
+  void SetIsAdSubframe(bool is_ad_subframe);
 
   // The initial popup URL for new window opened using:
   // `window.open(initial_popup_url)`.
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index f2e4e11b..9dc530e 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -802,6 +802,22 @@
          !network::CompatibleWithCrossOriginIsolated(child_coep);
 }
 
+// Computes the history offset of the new document compared to the current one.
+int EstimateHistoryOffset(NavigationController& controller,
+                          bool should_replace_current_entry) {
+  if (should_replace_current_entry)
+    return 0;
+
+  int current_index = controller.GetLastCommittedEntryIndex();
+  int pending_index = controller.GetPendingEntryIndex();
+
+  // +1 for non history navigation.
+  if (current_index == -1 || pending_index == -1)
+    return 1;
+
+  return pending_index - current_index;
+}
+
 }  // namespace
 
 // static
@@ -1167,6 +1183,9 @@
                 : NavigationTypeToReloadType(common_params_->navigation_type)),
       nav_entry_id_(entry ? entry->GetUniqueID() : 0),
       from_begin_navigation_(from_begin_navigation),
+      navigation_entry_offset_(
+          EstimateHistoryOffset(frame_tree_node_->navigator().controller(),
+                                common_params_->should_replace_current_entry)),
       rfh_restored_from_back_forward_cache_(
           rfh_restored_from_back_forward_cache),
       // Store the old RenderFrameHost id at request creation to be used later.
@@ -1395,8 +1414,6 @@
 
   begin_params_->headers = headers.ToString();
 
-  navigation_entry_offset_ = EstimateHistoryOffset();
-
   commit_params_->is_browser_initiated = browser_initiated_;
 }
 
@@ -4578,22 +4595,6 @@
   return NavigationTypeUtils::IsSameDocument(common_params_->navigation_type);
 }
 
-int NavigationRequest::EstimateHistoryOffset() {
-  if (common_params_->should_replace_current_entry)
-    return 0;
-
-  NavigationController& controller = frame_tree_node_->navigator().controller();
-
-  int current_index = controller.GetLastCommittedEntryIndex();
-  int pending_index = controller.GetPendingEntryIndex();
-
-  // +1 for non history navigation.
-  if (current_index == -1 || pending_index == -1)
-    return 1;
-
-  return pending_index - current_index;
-}
-
 void NavigationRequest::RecordDownloadUseCountersPrePolicyCheck(
     blink::NavigationDownloadPolicy download_policy) {
   RenderFrameHost* rfh = frame_tree_node_->current_frame_host();
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 1574c7dd3..582fdf3 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -1126,10 +1126,6 @@
   // when we commit the new page.
   void AddOldPageInfoToCommitParamsIfNeeded();
 
-  // Compute the history offset of the new document compared to the current one.
-  // See navigation_history_offset_ for more details.
-  int EstimateHistoryOffset();
-
   // Record download related UseCounters when navigation is a download before
   // filtered by download_policy.
   void RecordDownloadUseCountersPrePolicyCheck(
@@ -1475,8 +1471,7 @@
   bool upgrade_if_insecure_ = false;
 
   // The offset of the new document in the history.
-  // See NavigationHandle::GetNavigationEntryOffset() for details.
-  int navigation_entry_offset_ = 0;
+  const int navigation_entry_offset_ = 0;
 
   // Owns the NavigationThrottles associated with this navigation, and is
   // responsible for notifying them about the various navigation events.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index ddcda126..bf3147e 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -11060,9 +11060,8 @@
   return dom_content_loaded_;
 }
 
-void RenderFrameHostImpl::UpdateAdFrameType(
-    blink::mojom::AdFrameType ad_frame_type) {
-  frame_tree_node_->SetAdFrameType(ad_frame_type);
+void RenderFrameHostImpl::UpdateIsAdSubframe(bool is_ad_subframe) {
+  frame_tree_node_->SetIsAdSubframe(is_ad_subframe);
 }
 
 blink::mojom::AuthenticatorStatus
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index f6681b43..718c1de 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -397,7 +397,7 @@
                                   bool animate) override;
   bool Reload() override;
   bool IsDOMContentLoaded() override;
-  void UpdateAdFrameType(blink::mojom::AdFrameType ad_frame_type) override;
+  void UpdateIsAdSubframe(bool is_ad_subframe) override;
   blink::mojom::AuthenticatorStatus PerformGetAssertionWebAuthSecurityChecks(
       const std::string& relying_party_id,
       const url::Origin& effective_origin) override;
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index eb92d5c5..2b89bf4 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -1269,11 +1269,10 @@
   }
 }
 
-void RenderFrameHostManager::OnDidSetAdFrameType(
-    blink::mojom::AdFrameType ad_frame_type) {
+void RenderFrameHostManager::OnDidSetIsAdSubframe(bool is_ad_subframe) {
   for (const auto& pair : proxy_hosts_) {
-    pair.second->GetAssociatedRemoteFrame()->SetReplicatedAdFrameType(
-        ad_frame_type);
+    pair.second->GetAssociatedRemoteFrame()->SetReplicatedIsAdSubframe(
+        is_ad_subframe);
   }
 }
 
diff --git a/content/browser/renderer_host/render_frame_host_manager.h b/content/browser/renderer_host/render_frame_host_manager.h
index b99ae9b..e73603d 100644
--- a/content/browser/renderer_host/render_frame_host_manager.h
+++ b/content/browser/renderer_host/render_frame_host_manager.h
@@ -400,9 +400,9 @@
   void OnDidUpdateOrigin(const url::Origin& origin,
                          bool is_potentially_trustworthy_unique_origin);
 
-  // Send updated ad frame type to all frame proxies at ready-to-commit time
-  // when the ad status gets updated.
-  void OnDidSetAdFrameType(blink::mojom::AdFrameType ad_frame_type);
+  // Send updated ad status to all frame proxies at ready-to-commit time when it
+  // gets updated.
+  void OnDidSetIsAdSubframe(bool is_ad_subframe);
 
   void EnsureRenderViewInitialized(RenderViewHostImpl* render_view_host,
                                    SiteInstance* instance);
diff --git a/content/browser/renderer_host/render_frame_host_manager_unittest.cc b/content/browser/renderer_host/render_frame_host_manager_unittest.cc
index be6de0ae..e2bb55e 100644
--- a/content/browser/renderer_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/renderer_host/render_frame_host_manager_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <stdint.h>
 
-#include <map>
+#include <set>
 #include <string>
 #include <tuple>
 #include <unordered_set>
@@ -3374,31 +3374,28 @@
 
 class AdTaggingSimulator : public WebContentsObserver {
  public:
-  explicit AdTaggingSimulator(
-      const std::map<GURL, blink::mojom::AdFrameType>& ad_urls,
-      WebContents* web_contents)
+  explicit AdTaggingSimulator(const std::set<GURL>& ad_urls,
+                              WebContents* web_contents)
       : WebContentsObserver(web_contents), ad_urls_(ad_urls) {}
 
   void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override {
     auto it = ad_urls_.find(navigation_handle->GetURL());
-    if (it == ad_urls_.end())
-      return;
-    navigation_handle->GetRenderFrameHost()->UpdateAdFrameType(it->second);
+    navigation_handle->GetRenderFrameHost()->UpdateIsAdSubframe(it !=
+                                                                ad_urls_.end());
   }
 
   void SimulateOnFrameIsAdSubframe(RenderFrameHost* rfh) {
-    rfh->UpdateAdFrameType(blink::mojom::AdFrameType::kRootAd);
+    rfh->UpdateIsAdSubframe(true);
   }
 
  private:
-  std::map<GURL, blink::mojom::AdFrameType> ad_urls_;
+  std::set<GURL> ad_urls_;
 };
 
 class AdStatusInterceptingRemoteFrame : public content::FakeRemoteFrame {
  public:
-  void SetReplicatedAdFrameType(
-      blink::mojom::AdFrameType ad_frame_type) override {
-    is_ad_subframe_ = ad_frame_type != blink::mojom::AdFrameType::kNonAd;
+  void SetReplicatedIsAdSubframe(bool is_ad_subframe) override {
+    is_ad_subframe_ = is_ad_subframe;
   }
 
   // These methods reset state back to default when they are called.
@@ -3437,7 +3434,7 @@
 
     if (proxy_host->frame_tree_node()
             ->current_replication_state()
-            .ad_frame_type != blink::mojom::AdFrameType::kNonAd) {
+            .is_ad_subframe) {
       ad_frames_on_proxy_created_.insert(proxy_host);
     }
   }
@@ -3494,8 +3491,7 @@
   const GURL kUrlA("http://a.com/");
   const GURL kUrlB("http://b.com/");
 
-  std::map<GURL, blink::mojom::AdFrameType> ad_urls = {
-      {kUrlB, blink::mojom::AdFrameType::kRootAd}};
+  std::set<GURL> ad_urls = {kUrlB};
 
   AdTaggingSimulator ad_tagging_simulator(ad_urls, contents());
 
@@ -3509,8 +3505,7 @@
   ExpectAdStatusOnFrameProxyCreated(
       subframe_node->render_manager()->GetProxyToParent());
 
-  DCHECK_EQ(subframe_node->current_replication_state().ad_frame_type,
-            blink::mojom::AdFrameType::kRootAd);
+  EXPECT_TRUE(subframe_node->current_replication_state().is_ad_subframe);
 }
 
 // A page with top frame A that has subframes B and A1. A1 is an ad iframe that
@@ -3527,12 +3522,11 @@
   AdTaggingSimulator ad_tagging_simulator({}, contents());
 
   contents()->NavigateAndCommit(kUrlA);
-  DCHECK_EQ(contents()
-                ->GetFrameTree()
-                ->root()
-                ->current_replication_state()
-                .ad_frame_type,
-            blink::mojom::AdFrameType::kNonAd);
+  EXPECT_FALSE(contents()
+                   ->GetFrameTree()
+                   ->root()
+                   ->current_replication_state()
+                   .is_ad_subframe);
 
   AppendChildToFrame("subframe_b", kUrlB, web_contents()->GetMainFrame());
   AppendChildToFrame("subframe_a1", GURL(), web_contents()->GetMainFrame());
@@ -3547,8 +3541,7 @@
   RenderFrameProxyHost* proxy_a1_to_b =
       GetProxyHost(subframe_node_a1, subframe_node_b);
 
-  EXPECT_EQ(subframe_node_a1->current_replication_state().ad_frame_type,
-            blink::mojom::AdFrameType::kRootAd);
+  EXPECT_TRUE(subframe_node_a1->current_replication_state().is_ad_subframe);
   ExpectAdSubframeSignalForFrameProxy(proxy_a1_to_b, true);
 }
 
@@ -3565,18 +3558,16 @@
   const GURL kUrlC("http://c.com/");
   const GURL kUrlD("http://d.com/");
 
-  std::map<GURL, blink::mojom::AdFrameType> ad_urls = {
-      {kUrlD, blink::mojom::AdFrameType::kRootAd}};
+  std::set<GURL> ad_urls = {kUrlD};
 
   AdTaggingSimulator ad_tagging_simulator(ad_urls, contents());
 
   contents()->NavigateAndCommit(kUrlA);
-  DCHECK_EQ(contents()
-                ->GetFrameTree()
-                ->root()
-                ->current_replication_state()
-                .ad_frame_type,
-            blink::mojom::AdFrameType::kNonAd);
+  EXPECT_FALSE(contents()
+                   ->GetFrameTree()
+                   ->root()
+                   ->current_replication_state()
+                   .is_ad_subframe);
 
   AppendChildToFrame("subframe_b", kUrlB, web_contents()->GetMainFrame());
   AppendChildToFrame("subframe_c", kUrlC, web_contents()->GetMainFrame());
@@ -3585,10 +3576,8 @@
   FrameTreeNode* subframe_node_b = top_frame_node_a->child_at(0);
   FrameTreeNode* subframe_node_c = top_frame_node_a->child_at(1);
 
-  EXPECT_EQ(subframe_node_b->current_replication_state().ad_frame_type,
-            blink::mojom::AdFrameType::kNonAd);
-  EXPECT_EQ(subframe_node_c->current_replication_state().ad_frame_type,
-            blink::mojom::AdFrameType::kNonAd);
+  EXPECT_FALSE(subframe_node_b->current_replication_state().is_ad_subframe);
+  EXPECT_FALSE(subframe_node_c->current_replication_state().is_ad_subframe);
 
   RenderFrameProxyHost* proxy_c_to_a =
       GetProxyHost(subframe_node_c, top_frame_node_a);
@@ -3606,8 +3595,7 @@
   NavigationSimulator::NavigateAndCommitFromDocument(
       kUrlD, subframe_node_c->current_frame_host());
 
-  EXPECT_EQ(subframe_node_c->current_replication_state().ad_frame_type,
-            blink::mojom::AdFrameType::kRootAd);
+  EXPECT_TRUE(subframe_node_c->current_replication_state().is_ad_subframe);
 
   ExpectAdSubframeSignalForFrameProxy(proxy_c_to_a, true);
   ExpectAdSubframeSignalForFrameProxy(proxy_c_to_b, true);
@@ -3630,8 +3618,7 @@
   const GURL kUrlB("http://b.com/");
   const GURL kUrlC("http://c.com/");
 
-  std::map<GURL, blink::mojom::AdFrameType> ad_urls = {
-      {kUrlB, blink::mojom::AdFrameType::kRootAd}};
+  std::set<GURL> ad_urls = {kUrlB};
 
   AdTaggingSimulator ad_tagging_simulator(ad_urls, contents());
 
@@ -3659,9 +3646,7 @@
   const GURL kUrlB("http://b.com/");
   const GURL kUrlC("http://c.com/");
 
-  std::map<GURL, blink::mojom::AdFrameType> ad_urls = {
-      {kUrlB, blink::mojom::AdFrameType::kRootAd},
-      {kUrlC, blink::mojom::AdFrameType::kChildAd}};
+  std::set<GURL> ad_urls = {kUrlB, kUrlC};
 
   AdTaggingSimulator ad_tagging_simulator(ad_urls, contents());
 
@@ -3689,10 +3674,8 @@
 
   NavigationSimulator::NavigateAndCommitFromDocument(kUrlC, grandchild_host);
 
-  EXPECT_EQ(subframe_node->current_replication_state().ad_frame_type,
-            blink::mojom::AdFrameType::kRootAd);
-  EXPECT_EQ(grandchild_node->current_replication_state().ad_frame_type,
-            blink::mojom::AdFrameType::kChildAd);
+  EXPECT_TRUE(subframe_node->current_replication_state().is_ad_subframe);
+  EXPECT_TRUE(grandchild_node->current_replication_state().is_ad_subframe);
   ExpectAdSubframeSignalForFrameProxy(proxy_to_main_frame, true);
 }
 
diff --git a/content/browser/resources/conversions/conversion_internals.css b/content/browser/resources/conversions/conversion_internals.css
index 8926c0aa..90ded7fba 100644
--- a/content/browser/resources/conversions/conversion_internals.css
+++ b/content/browser/resources/conversions/conversion_internals.css
@@ -14,7 +14,7 @@
   color: rgb(48, 57, 66);
   display: flex;
   flex-direction: column;
-  font-family: Roboto, sans-seriif;
+  font-family: Roboto, sans-serif;
   font-size: 13px;
   height: 100%;
   margin: 15px;
diff --git a/content/browser/resources/conversions/conversion_internals.html b/content/browser/resources/conversions/conversion_internals.html
index df608b8..5799978 100644
--- a/content/browser/resources/conversions/conversion_internals.html
+++ b/content/browser/resources/conversions/conversion_internals.html
@@ -10,37 +10,37 @@
 
   <link rel="stylesheet" href="conversion_internals.css">
   <script type="module" src="conversion_internals.js"></script>
-  <title>Conversion Measurement API Internals</title>
+  <title>Attribution Reporting API Internals</title>
 </head>
 <body>
 
 <div id="page-heading">
-  Conversion Measurement API Internals
+  Attribution Reporting API Internals
 </div>
 <div id="info">
   <p>Learn more:
     <a href="https://web.dev/using-conversion-measurement/" target="_blank">
-      Conversion Measurement API
+      Attribution Reporting API
     </a>
-  <p>Conversion measurement is currently <span id="feature-status-content"></span>.
+  <p>Attribution reporting is currently <span id="feature-status-content"></span>.
 </div>
 <hr>
 <div id="page-content">
   <div>
     <button id="refresh">Refresh all page data</button>
-    <button id="clear-data">Clear all conversions data</button>
+    <button id="clear-data">Clear all attribution data</button>
   </div>
-  <h2> Active Impressions </h2>
+  <h2> Active Sources </h2>
   <div class="content">
     <div class="table-wrapper">
-      <table id="impression-table">
+      <table id="source-table">
         <thead>
           <tr class="header-row">
             <th>
-              Source Event Id
+              Source Event ID
             </th>
             <th>
-              Source origin
+              Source Origin
             </th>
             <th>
               Destination
@@ -62,12 +62,12 @@
             </th>
           </tr>
         </thead>
-        <tbody id="impression-table-body">
+        <tbody id="source-table-body">
         </tbody>
       </table>
     </div>
   </div>
-  <h2> Pending Conversion Reports </h2>
+  <h2> Pending Reports </h2>
   <div class="content">
     <div>
       <span id="debug-mode-content"></span>
@@ -77,7 +77,7 @@
         <thead>
           <tr class="header-row">
             <th>
-              Source Event Id
+              Source Event ID
             </th>
             <th>
               Trigger Data
@@ -86,7 +86,7 @@
               Destination
             </th>
             <th>
-              Report to
+              Report To
             </th>
             <th>
               Report Time
@@ -104,7 +104,7 @@
       <button id="send-reports">Send All Reports</button>
     </div>
   </div>
-  <h2> Sent Conversion Reports </h2>
+  <h2> Sent Reports </h2>
   <div class="content">
     <div class="table-wrapper">
       <table id="sent-report-table">
@@ -128,35 +128,35 @@
   </div>
 </div>
 
-<template id="impressionrow">
+<template id="source-row">
   <tr>
-    <td class="impression-data-cell"></td>
-    <td class="impression-origin-cell"></td>
-    <td class="conversion-destination-cell"></td>
-    <td class="reporting-origin-cell"></td>
-    <td class="impression-time-cell"></td>
+    <td class="source-event-id-cell"></td>
+    <td class="source-origin-cell"></td>
+    <td class="destination-cell"></td>
+    <td class="report-to-cell"></td>
+    <td class="source-registration-time-cell"></td>
     <td class="expiry-time-cell"></td>
     <td class="source-type-cell"></td>
     <td class="priority-cell"></td>
   </tr>
 </template>
 
-<template id="reportrow">
+<template id="report-row">
   <tr>
-    <td class="impression-data-cell"></td>
-    <td class="conversion-data-cell"></td>
-    <td class="conversion-origin-cell"></td>
-    <td class="reporting-origin-cell"></td>
+    <td class="source-event-id-cell"></td>
+    <td class="trigger-data-cell"></td>
+    <td class="destination-cell"></td>
+    <td class="report-to-cell"></td>
     <td class="report-time-cell"></td>
     <td class="source-type-cell"></td>
   </tr>
 </template>
 
-<template id="sentreportrow">
+<template id="sent-report-row">
   <tr>
-    <td class="report-url-data-cell"></td>
-    <td class="report-body-data-cell"></td>
-    <td class="http-response-code-data-cell"></td>
+    <td class="report-url-cell"></td>
+    <td class="report-body-cell"></td>
+    <td class="http-response-code-cell"></td>
   </tr>
 </template>
 </body>
diff --git a/content/browser/resources/conversions/conversion_internals.js b/content/browser/resources/conversions/conversion_internals.js
index 9546358..d045b8a 100644
--- a/content/browser/resources/conversions/conversion_internals.js
+++ b/content/browser/resources/conversions/conversion_internals.js
@@ -14,10 +14,10 @@
 let pageHandler = null;
 
 /**
- * All impressions held in storage at last update.
+ * All sources held in storage at last update.
  * @type {!Array<!WebUIImpression>}
  */
-let impressions = null;
+let sources = null;
 
 /**
  * All reports held in storage at last update.
@@ -81,22 +81,22 @@
 }
 
 /**
- * Creates a single row for the impression table.
- * @param {!WebUIImpression} impression The info to create the row.
+ * Creates a single row for the source table.
+ * @param {!WebUIImpression} source The info to create the row.
  * @return {!HTMLElement}
  */
-function createImpressionRow(impression) {
-  const template = $('impressionrow').cloneNode(true);
+function createSourceRow(source) {
+  const template = $('source-row').cloneNode(true);
   const td = template.content.querySelectorAll('td');
 
-  td[0].textContent = impression.impressionData;
-  td[1].textContent = UrlToText(impression.impressionOrigin);
-  td[2].textContent = UrlToText(impression.conversionDestination);
-  td[3].textContent = UrlToText(impression.reportingOrigin);
-  td[4].textContent = new Date(impression.impressionTime).toLocaleString();
-  td[5].textContent = new Date(impression.expiryTime).toLocaleString();
-  td[6].textContent = SourceTypeToText(impression.sourceType);
-  td[7].textContent = impression.priority;
+  td[0].textContent = source.impressionData;
+  td[1].textContent = UrlToText(source.impressionOrigin);
+  td[2].textContent = UrlToText(source.conversionDestination);
+  td[3].textContent = UrlToText(source.reportingOrigin);
+  td[4].textContent = new Date(source.impressionTime).toLocaleString();
+  td[5].textContent = new Date(source.expiryTime).toLocaleString();
+  td[6].textContent = SourceTypeToText(source.sourceType);
+  td[7].textContent = source.priority;
   return document.importNode(template.content, true);
 }
 
@@ -106,7 +106,7 @@
  * @return {!HTMLElement}
  */
 function createReportRow(report) {
-  const template = $('reportrow').cloneNode(true);
+  const template = $('report-row').cloneNode(true);
   const td = template.content.querySelectorAll('td');
 
   td[0].textContent = report.impressionData;
@@ -124,7 +124,7 @@
  * @return {!HTMLElement}
  */
 function createSentReportRow(info) {
-  const template = $('sentreportrow').cloneNode(true);
+  const template = $('sent-report-row').cloneNode(true);
   const td = template.content.querySelectorAll('td');
 
   td[0].textContent = info.reportUrl.url;
@@ -134,22 +134,20 @@
 }
 
 /**
- * Regenerates the impression table from |impressions|.
+ * Regenerates the source table from |sources|.
  */
-function renderImpressionTable() {
-  const impressionTable = $('impression-table-body');
-  clearTable(impressionTable);
-  impressions.forEach(
-      impression =>
-          impressionTable.appendChild(createImpressionRow(impression)));
+function renderSourceTable() {
+  const sourceTable = $('source-table-body');
+  clearTable(sourceTable);
+  sources.forEach(source => sourceTable.appendChild(createSourceRow(source)));
 
-  // If there are no impressions, add an empty row to indicate the table is
+  // If there are no sources, add an empty row to indicate the table is
   // purposefully empty.
-  if (!impressions.length) {
-    const template = $('impressionrow').cloneNode(true);
+  if (!sources.length) {
+    const template = $('source-row').cloneNode(true);
     const td = template.content.querySelectorAll('td');
-    td[0].textContent = 'No active impressions.';
-    impressionTable.appendChild(document.importNode(template.content, true));
+    td[0].textContent = 'No active sources.';
+    sourceTable.appendChild(document.importNode(template.content, true));
   }
 }
 
@@ -164,7 +162,7 @@
   // If there are no reports, add an empty row to indicate the table is
   // purposefully empty.
   if (!reports.length) {
-    const template = $('reportrow').cloneNode(true);
+    const template = $('report-row').cloneNode(true);
     const td = template.content.querySelectorAll('td');
     td[0].textContent = 'No pending reports.';
     reportTable.appendChild(document.importNode(template.content, true));
@@ -183,7 +181,7 @@
   // If there are no sent reports, add an empty row to indicate the table is
   // purposefully empty.
   if (!sentReports.length) {
-    const template = $('sentreportrow').cloneNode(true);
+    const template = $('sent-report-row').cloneNode(true);
     const td = template.content.querySelectorAll('td');
     td[0].textContent = 'No sent reports.';
     sentReportTable.appendChild(document.importNode(template.content, true));
@@ -191,7 +189,7 @@
 }
 
 /**
- * Fetch all active impressions, pending reports, and sent reports from the
+ * Fetch all active sources, pending reports, and sent reports from the
  * backend and populate the tables. Also update measurement enabled status.
  */
 function updatePageData() {
@@ -221,8 +219,8 @@
   });
 
   pageHandler.getActiveImpressions().then((response) => {
-    impressions = response.impressions;
-    renderImpressionTable();
+    sources = response.impressions;
+    renderSourceTable();
   });
 
   pageHandler.getPendingReports().then((response) => {
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index fed97ca..cfa74a8c 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -1176,13 +1176,12 @@
 
   // Each consumer is responsible for registering its QuotaClient during
   // its construction.
-  filesystem_context_ =
-      CreateFileSystemContext(browser_context_, partition_path_, is_in_memory_,
-                              quota_manager_proxy.get());
+  filesystem_context_ = CreateFileSystemContext(
+      browser_context_, partition_path_, is_in_memory_, quota_manager_proxy);
 
-  database_tracker_ = base::MakeRefCounted<storage::DatabaseTracker>(
+  database_tracker_ = storage::DatabaseTracker::Create(
       partition_path_, is_in_memory_,
-      browser_context_->GetSpecialStoragePolicy(), quota_manager_proxy.get());
+      browser_context_->GetSpecialStoragePolicy(), quota_manager_proxy);
 
   dom_storage_context_ = DOMStorageContextWrapper::Create(
       this, browser_context_->GetSpecialStoragePolicy());
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 3ce2828..da7b464 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -6135,13 +6135,19 @@
   color_chooser_ = std::make_unique<ColorChooser>(std::move(chooser_receiver),
                                                   std::move(client));
 
-  content::ColorChooser* new_color_chooser =
+  auto new_color_chooser = base::WrapUnique(
       delegate_ ? delegate_->OpenColorChooser(this, color, suggestions)
-                : nullptr;
-  color_chooser_->SetChooser(base::WrapUnique(new_color_chooser));
-
-  if (!new_color_chooser)
+                : nullptr);
+  if (color_chooser_ && new_color_chooser) {
+    color_chooser_->SetChooser(std::move(new_color_chooser));
+  } else if (new_color_chooser) {
+    // OpenColorChooser synchronously called back to DidEndColorChooser.
+    DCHECK(!color_chooser_);
+    new_color_chooser->End();
+  } else if (color_chooser_) {
+    DCHECK(!new_color_chooser);
     color_chooser_.reset();
+  }
 }
 
 #if BUILDFLAG(ENABLE_PLUGINS)
diff --git a/content/browser/web_database/web_database_host_impl_unittest.cc b/content/browser/web_database/web_database_host_impl_unittest.cc
index 30f57e0..aa20ad2 100644
--- a/content/browser/web_database/web_database_host_impl_unittest.cc
+++ b/content/browser/web_database/web_database_host_impl_unittest.cc
@@ -4,8 +4,15 @@
 
 #include "content/browser/web_database/web_database_host_impl.h"
 
+#include <memory>
+#include <string>
+#include <utility>
+
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/files/file_path.h"
+#include "base/location.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/utf_string_conversions.h"
@@ -18,8 +25,12 @@
 #include "content/test/fake_mojo_message_dispatch_context.h"
 #include "mojo/public/cpp/system/functions.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
+#include "storage/browser/quota/special_storage_policy.h"
 #include "storage/common/database/database_identifier.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
 
 namespace content {
 
@@ -44,10 +55,10 @@
         std::make_unique<MockRenderProcessHost>(&browser_context_);
 
     scoped_refptr<storage::DatabaseTracker> db_tracker =
-        base::MakeRefCounted<storage::DatabaseTracker>(
-            base::FilePath(), /*is_incognito=*/false,
-            /*special_storage_policy=*/nullptr,
-            /*quota_manager_proxy=*/nullptr);
+        storage::DatabaseTracker::Create(base::FilePath(),
+                                         /*is_incognito=*/false,
+                                         /*special_storage_policy=*/nullptr,
+                                         /*quota_manager_proxy=*/nullptr);
 
     task_runner_ = db_tracker->task_runner();
     host_ = std::make_unique<WebDatabaseHostImpl>(process_id(),
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h
index 6f6cb5e..973d115 100644
--- a/content/public/browser/render_frame_host.h
+++ b/content/public/browser/render_frame_host.h
@@ -20,7 +20,6 @@
 #include "services/network/public/mojom/web_sandbox_flags.mojom-forward.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/tokens/tokens.h"
-#include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-forward.h"
 #include "third_party/blink/public/mojom/devtools/console_message.mojom-forward.h"
 #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-forward.h"
 #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-forward.h"
@@ -844,17 +843,14 @@
   // Returns true if this frame has fired DOMContentLoaded.
   virtual bool IsDOMContentLoaded() = 0;
 
-  // Update the ad frame state. The parameter |ad_frame_type| cannot be kNonAd,
-  // and once this has been called, it cannot be called again with a different
-  // |ad_frame_type|, since once a frame is determined to be an ad, it will stay
-  // tagged as an ad of the same type for its entire lifetime.
+  // Update whether the frame is considered an ad subframe by Ad Tagging.
   //
-  // Note: The ad frame type is currently maintained and updated *outside*
-  // content. This is used to ensure the render frame proxies are in sync (since
-  // they aren't exposed in the public API). Eventually, we might be able to
-  // simplify this somewhat (maybe //content would be responsible for
-  // maintaining the state, with some content client method used to update it).
-  virtual void UpdateAdFrameType(blink::mojom::AdFrameType ad_frame_type) = 0;
+  // Note: This ad status is currently maintained and updated *outside* content.
+  // This is used to ensure the render frame proxies are in sync (since they
+  // aren't exposed in the public API). Eventually, we might be able to simplify
+  // this somewhat (maybe //content would be responsible for maintaining the
+  // state, with some content client method used to update it).
+  virtual void UpdateIsAdSubframe(bool is_ad_subframe) = 0;
 
   // Perform security checks on Web Authentication requests. These can be
   // called by other |Authenticator| mojo interface implementations in the
diff --git a/content/public/test/fake_remote_frame.cc b/content/public/test/fake_remote_frame.cc
index 34a437f..217093b 100644
--- a/content/public/test/fake_remote_frame.cc
+++ b/content/public/test/fake_remote_frame.cc
@@ -34,8 +34,7 @@
     const url::Origin& origin,
     bool is_potentially_trustworthy_unique_origin) {}
 
-void FakeRemoteFrame::SetReplicatedAdFrameType(
-    blink::mojom::AdFrameType ad_frame_type) {}
+void FakeRemoteFrame::SetReplicatedIsAdSubframe(bool is_ad_subframe) {}
 
 void FakeRemoteFrame::SetReplicatedName(const std::string& name,
                                         const std::string& unique_name) {}
diff --git a/content/public/test/fake_remote_frame.h b/content/public/test/fake_remote_frame.h
index 48b42025..8362047d 100644
--- a/content/public/test/fake_remote_frame.h
+++ b/content/public/test/fake_remote_frame.h
@@ -47,8 +47,7 @@
   void SetReplicatedOrigin(
       const url::Origin& origin,
       bool is_potentially_trustworthy_unique_origin) override;
-  void SetReplicatedAdFrameType(
-      blink::mojom::AdFrameType ad_frame_type) override;
+  void SetReplicatedIsAdSubframe(bool is_ad_subframe) override;
   void SetReplicatedName(const std::string& name,
                          const std::string& unique_name) override;
   void DispatchLoadEventForFrameOwner() override;
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc
index e367219..99f0ec20 100644
--- a/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -453,8 +453,12 @@
     bool subtree,
     ax::mojom::Action event_from_action,
     std::vector<ui::AXEventIntent> event_intents) {
-  EnqueueDirtyObject(obj, ax::mojom::EventFrom::kAction, event_from_action,
-                     event_intents);
+  DirtyObject dirty_object;
+  dirty_object.obj = obj;
+  dirty_object.event_from = ax::mojom::EventFrom::kAction;
+  dirty_object.event_from_action = event_from_action;
+  dirty_object.event_intents = event_intents;
+  dirty_objects_.push_back(dirty_object);
 
   if (subtree)
     serializer_->InvalidateSubtree(obj);
@@ -626,19 +630,6 @@
   return true;
 }
 
-void RenderAccessibilityImpl::EnqueueDirtyObject(
-    const blink::WebAXObject& obj,
-    ax::mojom::EventFrom event_from,
-    ax::mojom::Action event_from_action,
-    std::vector<ui::AXEventIntent> event_intents) {
-  DirtyObject* dirty_object = new DirtyObject();
-  dirty_object->obj = obj;
-  dirty_object->event_from = event_from;
-  dirty_object->event_from_action = event_from_action;
-  dirty_object->event_intents = event_intents;
-  dirty_objects_.push_back(base::WrapUnique<DirtyObject>(dirty_object));
-}
-
 int RenderAccessibilityImpl::GetDeferredEventsDelay() {
   // The amount of time, in milliseconds, to wait before sending non-interactive
   // events that are deferred before the initial page load.
@@ -831,6 +822,10 @@
   std::vector<ui::AXTreeUpdate> updates;
   std::vector<ui::AXEvent> events;
 
+  // Keep track of nodes in the tree that need to be updated.
+  std::vector<DirtyObject> dirty_objects = dirty_objects_;
+  dirty_objects_.clear();
+
   // If there's a layout complete or a scroll changed message, we need to send
   // location changes.
   bool need_to_send_location_changes = false;
@@ -907,12 +902,10 @@
   // Now serialize all dirty objects. Keep track of IDs serialized
   // so we don't have to serialize the same node twice.
   std::set<int32_t> already_serialized_ids;
-  while (!dirty_objects_.empty()) {
-    std::unique_ptr<DirtyObject> current_dirty_object =
-        std::move(dirty_objects_.front());
-    dirty_objects_.pop_front();
-    auto obj = current_dirty_object->obj;
+  for (size_t i = 0; i < dirty_objects.size(); ++i) {
+    DirtyObject current_dirty_object = dirty_objects[i];
 
+    auto obj = current_dirty_object.obj;
     // Dirty objects can be added using MarkWebAXObjectDirty(obj) from other
     // parts of the code as well, so we need to ensure the object still exists.
     // TODO(accessibility) Change this to CheckValidity() if there aren't crash
@@ -964,19 +957,25 @@
         // Similarly, during Event::kTextChanged, if any Ignored,
         // but included in tree ancestor uses NameFrom::kContents,
         // they must also be re-serialized in case the name changed.
-        EnqueueDirtyObject(ancestor, current_dirty_object->event_from,
-                           current_dirty_object->event_from_action,
-                           current_dirty_object->event_intents);
+        DirtyObject dirty_object;
+        dirty_object.obj = ancestor;
+        dirty_object.event_from = current_dirty_object.event_from;
+        dirty_object.event_from_action = current_dirty_object.event_from_action;
+        dirty_object.event_intents = current_dirty_object.event_intents;
+        dirty_objects.push_back(dirty_object);
       }
-      EnqueueDirtyObject(ancestor, current_dirty_object->event_from,
-                         current_dirty_object->event_from_action,
-                         current_dirty_object->event_intents);
+      DirtyObject dirty_object;
+      dirty_object.obj = ancestor;
+      dirty_object.event_from = current_dirty_object.event_from;
+      dirty_object.event_from_action = current_dirty_object.event_from_action;
+      dirty_object.event_intents = current_dirty_object.event_intents;
+      dirty_objects.push_back(dirty_object);
     }
 
     ui::AXTreeUpdate update;
-    update.event_from = current_dirty_object->event_from;
-    update.event_from_action = current_dirty_object->event_from_action;
-    update.event_intents = current_dirty_object->event_intents;
+    update.event_from = current_dirty_object.event_from;
+    update.event_from_action = current_dirty_object.event_from_action;
+    update.event_intents = current_dirty_object.event_intents;
     // If there's a plugin, force the tree data to be generated in every
     // message so the plugin can merge its own tree data changes.
     if (plugin_tree_source_)
diff --git a/content/renderer/accessibility/render_accessibility_impl.h b/content/renderer/accessibility/render_accessibility_impl.h
index f19d93e..f1004a5e 100644
--- a/content/renderer/accessibility/render_accessibility_impl.h
+++ b/content/renderer/accessibility/render_accessibility_impl.h
@@ -5,7 +5,6 @@
 #ifndef CONTENT_RENDERER_ACCESSIBILITY_RENDER_ACCESSIBILITY_IMPL_H_
 #define CONTENT_RENDERER_ACCESSIBILITY_RENDER_ACCESSIBILITY_IMPL_H_
 
-#include <list>
 #include <memory>
 #include <vector>
 
@@ -205,12 +204,6 @@
   bool ShouldSerializeNodeForEvent(const blink::WebAXObject& obj,
                                    const ui::AXEvent& event) const;
 
-  // Add a DirtyObject to the dirty_objects_ queue.
-  void EnqueueDirtyObject(const blink::WebAXObject& obj,
-                          ax::mojom::EventFrom event_from,
-                          ax::mojom::Action event_from_action,
-                          std::vector<ui::AXEventIntent> event_intents);
-
   // If we are calling this from a task, scheduling is allowed even if there is
   // a running task
   void ScheduleSendPendingAccessibilityEvents(
@@ -261,7 +254,7 @@
   // Objects that need to be re-serialized, the next time
   // we send an event bundle to the browser - but don't specifically need
   // an event fired.
-  std::list<std::unique_ptr<DirtyObject>> dirty_objects_;
+  std::vector<DirtyObject> dirty_objects_;
 
   // The adapter that exposes Blink's accessibility tree to AXTreeSerializer.
   std::unique_ptr<BlinkAXTreeSource> tree_source_;
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index fb0f97b8..355db6f 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -259,7 +259,7 @@
       state->insecure_request_policy);
   web_frame_->SetReplicatedInsecureNavigationsSet(
       state->insecure_navigations_set);
-  web_frame_->SetReplicatedAdFrameType(state->ad_frame_type);
+  web_frame_->SetReplicatedIsAdSubframe(state->is_ad_subframe);
   web_frame_->SetReplicatedPermissionsPolicyHeader(
       state->permissions_policy_header);
   if (state->has_active_user_gesture) {
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 5b5a71c..a61bf4db 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -236,20 +236,26 @@
     "critical level not align");
 
 void* CreateHistogram(const char* name, int min, int max, size_t buckets) {
-  if (min <= 0)
-    min = 1;
-  std::string histogram_name;
-  RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
-  if (render_thread_impl) {  // Can be null in tests.
-    histogram_name = render_thread_impl->histogram_customizer()
-                         ->ConvertToCustomHistogramName(name);
-  } else {
-    histogram_name = std::string(name);
+  // Each histogram has an implicit '0' bucket (for underflow), so we can always
+  // bump the minimum to 1.
+  DCHECK_LE(0, min);
+  min = std::max(1, min);
+
+  // For boolean histograms, always include an overflow bucket [2, infinity).
+  if (max == 1 && buckets == 2) {
+    max = 2;
+    buckets = 3;
   }
-  base::HistogramBase* histogram =
-      base::Histogram::FactoryGet(histogram_name, min, max, buckets,
-                                  base::Histogram::kUmaTargetedHistogramFlag);
-  return histogram;
+
+  RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
+  // render_thread_impl can be null in tests.
+  std::string histogram_name = render_thread_impl
+                                   ? render_thread_impl->histogram_customizer()
+                                         ->ConvertToCustomHistogramName(name)
+                                   : std::string{name};
+  return base::Histogram::FactoryGet(
+      histogram_name, min, max, buckets,
+      base::Histogram::kUmaTargetedHistogramFlag);
 }
 
 void AddHistogramSample(void* hist, int sample) {
diff --git a/content/test/data/accessibility/regression/content-visibility-label-expected-blink.txt b/content/test/data/accessibility/regression/content-visibility-label-expected-blink.txt
new file mode 100644
index 0000000..eff0848e
--- /dev/null
+++ b/content/test/data/accessibility/regression/content-visibility-label-expected-blink.txt
@@ -0,0 +1,5 @@
+rootWebArea
+++genericContainer ignored
+++++genericContainer ignored
+++++++genericContainer name='abc'
+++++++++genericContainer ignored invisible
diff --git a/content/test/data/accessibility/regression/content-visibility-label.html b/content/test/data/accessibility/regression/content-visibility-label.html
new file mode 100644
index 0000000..6f143f53
--- /dev/null
+++ b/content/test/data/accessibility/regression/content-visibility-label.html
@@ -0,0 +1,7 @@
+<style>
+.hidden {
+  content-visibility: hidden;
+}
+</style>
+<div class=hidden aria-labelledby="target">
+  <div id="target">abc<option>
diff --git a/content/test/data/conversions/databases/README.md b/content/test/data/conversions/databases/README.md
index de628dac5..75dadaa 100644
--- a/content/test/data/conversions/databases/README.md
+++ b/content/test/data/conversions/databases/README.md
@@ -7,4 +7,4 @@
 schema.
 
 For more info, please see the migration steps located at the top of
-`content/browser/conversions/conversion_storage_sql_initializer.cc`.
+`content/browser/conversions/conversion_storage_sql_migrations.h`.
diff --git a/content/test/data/gpu/pixel_webgpu_util.js b/content/test/data/gpu/pixel_webgpu_util.js
index 6a3b0c2..aef07c6 100644
--- a/content/test/data/gpu/pixel_webgpu_util.js
+++ b/content/test/data/gpu/pixel_webgpu_util.js
@@ -7,28 +7,29 @@
 
   const wgslShaders = {
     vertex: `
-[[builtin(vertex_index)]] var<in> VertexIndex : u32;
-[[builtin(position)]] var<out> Position : vec4<f32>;
-
-[[location(0)]] var<out> fragUV : vec2<f32>;
-
-const quadPos : array<vec4<f32>, 4> = array<vec4<f32>, 4>(
+let quadPos : array<vec4<f32>, 4> = array<vec4<f32>, 4>(
     vec4<f32>(-1.0,  1.0, 0.0, 1.0),
     vec4<f32>(-1.0, -1.0, 0.0, 1.0),
     vec4<f32>( 1.0,  1.0, 0.0, 1.0),
     vec4<f32>( 1.0, -1.0, 0.0, 1.0));
 
-const quadUV : array<vec2<f32>, 4> = array<vec2<f32>, 4>(
+let quadUV : array<vec2<f32>, 4> = array<vec2<f32>, 4>(
     vec2<f32>(0.0, 0.0),
     vec2<f32>(0.0, 1.0),
     vec2<f32>(1.0, 0.0),
     vec2<f32>(1.0, 1.0));
 
+struct VertexOutput {
+  [[builtin(position)]] Position : vec4<f32>;
+  [[location(0)]] fragUV : vec2<f32>;
+};
+
 [[stage(vertex)]]
-fn main() -> void {
-  Position = quadPos[VertexIndex];
-  fragUV = quadUV[VertexIndex];
-  return;
+fn main([[builtin(vertex_index)]] VertexIndex : u32) -> VertexOutput {
+  var output: VertexOutput;
+  output.Position = quadPos[VertexIndex];
+  output.fragUV = quadUV[VertexIndex];
+  return output;
 }
 `,
 
@@ -36,13 +37,9 @@
 [[binding(0), group(0)]] var mySampler: sampler;
 [[binding(1), group(0)]] var myTexture: texture_2d<f32>;
 
-[[location(0)]] var<in> fragUV : vec2<f32>;
-[[location(0)]] var<out> outColor : vec4<f32>;
-
 [[stage(fragment)]]
-fn main() -> void {
-  outColor = textureSample(myTexture, mySampler, fragUV);
-  return;
+fn main([[location(0)]] fragUV : vec2<f32>) -> [[location(0)]] vec4<f32> {
+  return textureSample(myTexture, mySampler, fragUV);
 }
 `,
   };
diff --git a/docs/security/security-labels.md b/docs/security/security-labels.md
index cce7440e..bfd6838c 100644
--- a/docs/security/security-labels.md
+++ b/docs/security/security-labels.md
@@ -30,11 +30,14 @@
   * **Security_Severity-Critical**: **Pri-0**.
   * **High** and **Medium**: **Pri-1**.
   * **Low**: **Pri-2**.
-* **Security_Impact-**{**Head**, **Beta**, **Stable**, **None**}: Designates
-which branch(es) were impacted by the bug. Only apply the label corresponding
-with the earliest affected branch. **None** means that a security bug is in a
-disabled feature, or otherwise doesn't impact Chrome: see the section below
-for more detail.
+* **FoundIn-#**: Designates which milestones of Chrome are
+impacted by the bug. Multiple labels may be set, but the most important one
+is the earliest affected milestone.
+* **Security_Impact-**{**Head**, **Beta**, **Stable**, **None**}: Derived
+from **FoundIn**, this label specifies the earliest affected release channel.
+Should not normally be set by humans, except in the case of **None** which
+means that the bug is in a disabled feature, or otherwise doesn't impact
+Chrome: see the section below for more details.
     * Note that **Security_Severity** should still be set on
       **Security_Impact-None** issues, as if the feature were enabled or the
       code reachable.
@@ -215,10 +218,11 @@
 the 4 valid impact labels (None, Stable, Beta, Head). This rule removes any
 invalid and excess impact labels.
 
-### Adjust **Security_Impact-X** To Match Milestone Labels
+### Adjust **Security_Impact-X** To Match FoundIn Labels
 
-Based on **M-#** milestone labels this rule assigns corresponding
+Based on **FoundIn-#** milestone labels this rule assigns corresponding
 **Security_Impact-X** labels if they are incorrect or absent.
+**Security_Impact-None** is never changed.
 
 ### Update **M-#** Labels
 
@@ -289,13 +293,15 @@
 a novel and nasty-looking buffer overflow in the renderer process. ClusterFuzz
 also confirms that all current releases are affected. Since M27 is the current
 Stable release, and M28 is in Beta, we add the labels of the earliest affected
-release: **M-27**, **Security_Impact-Stable**. The severity of a buffer overflow
+release: **FoundIn-27**. The severity of a buffer overflow
 in a renderer implies **Security_Severity-High** and **Pri-1**. Any external
 report for a confirmed vulnerability needs **reward-topanel**. Sheriffbot will
 usually add it automatically. The stack trace provided by ClusterFuzz suggests
 that the bug is in the component **Blink>DOM**, and such bugs should be labeled
 as applying to all OSs except iOS (where Blink is not used): **OS-**{**Linux**,
-**Windows**, **Android**, **Chrome**, **Fuchsia**}.
+**Windows**, **Android**, **Chrome**, **Fuchsia**}. Sheriffbot will check
+whether 27 is the current stable, beta or head milestone; let's assume
+**Security_Impact-Stable** is applied by Sheriffbot this time.
 1. Within a day or two, the sheriff was able to get the bug assigned and — oh
 joy! — fixed very quickly. When the bug's status changes to **Fixed**,
 Sheriffbot will add the **Merge-Requested** label, and will change
diff --git a/docs/security/sheriff.md b/docs/security/sheriff.md
index 667a5961..a3f27d8 100644
--- a/docs/security/sheriff.md
+++ b/docs/security/sheriff.md
@@ -268,12 +268,18 @@
 mitigated, the V8 team will reduce the security severity (to avoid unnecessary
 risk of merging the bug into stable branches).
 
-#### Step 3. Set Impact
+#### Step 3. Set FoundIn
 
-Identify the earliest affected branch (stable, beta or head) and set either
-`Security_Impact-Stable`, `Security_Impact-Beta` or `Security_Impact-Head`.
+Identify the earliest affected branch (stable, beta or head) and set the
+corresponding `FoundIn` label (for example `FoundIn-66` if the stable
+milestone is 66 and you've confirmed it's reproducible on M66).
 If you reproduced the bug with ClusterFuzz, it should do this on your behalf.
 
+If in doubt about the currently active milestones, check
+[ChromiumDash](https://chromiumdash.appspot.com/releases?platform=Windows).
+There's no need to check for reproducibility on milestones earlier than the
+current Stable milestone.
+
 #### Step 4. [Check other labels](security-labels.md).
 
 Much of Chrome's development and release process depends on bugs having the
@@ -289,7 +295,7 @@
 * **If the reporter wants to remain anonymous or if the bug description or
   comments contain PII**, add **Restrict-View-SecurityEmbargo**.
 * **Security_Severity** - your responsibility as Sheriff.
-* **Security_Impact** - your responsibility as Sheriff.
+* **FoundIn** - your responsibility as Sheriff.
 * **reward_to** - if the bug was filed internally on behalf of somebody
   external. This is also very important; please check.
 
diff --git a/docs/sync/model_api.md b/docs/sync/model_api.md
index 008a279c..73022e22 100644
--- a/docs/sync/model_api.md
+++ b/docs/sync/model_api.md
@@ -264,7 +264,7 @@
     [`ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers`][CreateCommonDataTypeControllers] or platform-specific equivalent in
     [`ChromeSyncClient::CreateDataTypeControllers`][CreateDataTypeControllers].
 *   Add your KeyedService dependency to
-    [`ProfileSyncServiceFactory`][ProfileSyncServiceFactory].
+    [`SyncServiceFactory`][SyncServiceFactory].
 *   Add an field for encrypted data to [`NigoriSpecifics`][NigoriSpecifics].
 *   If your type should have its own toggle in sync settings, add an entry to
     the [`UserSelectableType`][UserSelectableType] enum, add a
@@ -283,7 +283,7 @@
 [ModelTypeController]: https://cs.chromium.org/chromium/src/components/sync/driver/model_type_controller.h
 [CreateCommonDataTypeControllers]: https://cs.chromium.org/search/?q="ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers"
 [CreateDataTypeControllers]: https://cs.chromium.org/search/?q="ChromeSyncClient::CreateDataTypeControllers"
-[ProfileSyncServiceFactory]: https://cs.chromium.org/search/?q=:ProfileSyncServiceFactory%5C(%5C)
+[SyncServiceFactory]: https://cs.chromium.org/search/?q=:SyncServiceFactory%5C(%5C)
 [NigoriSpecifics]: https://cs.chromium.org/chromium/src/components/sync/protocol/nigori_specifics.proto
 [UserSelectableType]: https://cs.chromium.org/chromium/src/components/sync/base/user_selectable_type.h?type=cs&q="enum+class+UserSelectableType"
 [pref_names]: https://cs.chromium.org/chromium/src/components/sync/base/pref_names.h
diff --git a/extensions/browser/api/socket/tcp_socket.cc b/extensions/browser/api/socket/tcp_socket.cc
index f8bd9bd..0ae69cf 100644
--- a/extensions/browser/api/socket/tcp_socket.cc
+++ b/extensions/browser/api/socket/tcp_socket.cc
@@ -199,7 +199,7 @@
 
 void TCPSocket::RecvFrom(int count, RecvFromCompletionCallback callback) {
   std::move(callback).Run(net::ERR_FAILED, nullptr,
-                          false /* socket_destroying */, nullptr, 0);
+                          false /* socket_destroying */, std::string(), 0);
 }
 
 void TCPSocket::SendTo(scoped_refptr<net::IOBuffer> io_buffer,
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
index 0fe08e5..68d2372 100644
--- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
+++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -526,7 +526,7 @@
   header_client_receiver_.reset();
   target_loader_.reset();
 
-  constexpr int kInternalRedirectStatusCode = 307;
+  constexpr int kInternalRedirectStatusCode = net::HTTP_TEMPORARY_REDIRECT;
 
   net::RedirectInfo redirect_info =
       CreateRedirectInfo(request_, redirect_url_, kInternalRedirectStatusCode,
diff --git a/extensions/browser/browser_context_keyed_api_factory.h b/extensions/browser/browser_context_keyed_api_factory.h
index d2fcae2..eb894d2 100644
--- a/extensions/browser/browser_context_keyed_api_factory.h
+++ b/extensions/browser/browser_context_keyed_api_factory.h
@@ -82,7 +82,7 @@
 //         BrowserContextKeyedAPIFactory<ApiResourceManager<T>>* factory) {
 //       factory->DependsOn(
 //           ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
-//       factory->DependsOn(ProfileSyncServiceFactory::GetInstance());
+//       factory->DependsOn(SyncServiceFactory::GetInstance());
 //       ...
 //     }
 //   };
diff --git a/gpu/command_buffer/service/external_vk_image_backing.h b/gpu/command_buffer/service/external_vk_image_backing.h
index e9609fdc..1bcb5362 100644
--- a/gpu/command_buffer/service/external_vk_image_backing.h
+++ b/gpu/command_buffer/service/external_vk_image_backing.h
@@ -104,7 +104,8 @@
       return !use_separate_gl_texture() && (texture_ || texture_passthrough_);
     }
 
-    if (usage() & SHARED_IMAGE_USAGE_SCANOUT) {
+    if ((usage() & SHARED_IMAGE_USAGE_RASTER) &&
+        (usage() & SHARED_IMAGE_USAGE_SCANOUT)) {
       return true;
     }
 
diff --git a/gpu/command_buffer/service/external_vk_image_factory.cc b/gpu/command_buffer/service/external_vk_image_factory.cc
index 8945486..ef135955 100644
--- a/gpu/command_buffer/service/external_vk_image_factory.cc
+++ b/gpu/command_buffer/service/external_vk_image_factory.cc
@@ -150,48 +150,30 @@
                                          gfx::GpuMemoryBufferType gmb_type,
                                          GrContextType gr_context_type,
                                          bool* allow_legacy_mailbox) {
-  bool using_interop_factory = (gr_context_type == GrContextType::kVulkan &&
-                                (usage & SHARED_IMAGE_USAGE_DISPLAY)) ||
-                               (usage & SHARED_IMAGE_USAGE_WEBGPU) ||
-                               (usage & SHARED_IMAGE_USAGE_VIDEO_DECODE);
+  if (gmb_type != gfx::EMPTY_BUFFER && !CanImportGpuMemoryBuffer(gmb_type)) {
+    return false;
+  }
+  // TODO(crbug.com/969114): Not all shared image factory implementations
+  // support concurrent read/write usage.
+  if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
+    return false;
+  }
+  if (thread_safe) {
+    LOG(ERROR) << "ExternalVkImageFactory currently do not support "
+                  "cross-thread usage.";
+    return false;
+  }
 
 #if defined(OS_ANDROID)
   // Scanout on Android requires explicit fence synchronization which is only
   // supported by the interop factory.
-  using_interop_factory |= usage & SHARED_IMAGE_USAGE_SCANOUT;
+  if (usage & SHARED_IMAGE_USAGE_SCANOUT) {
+    return false;
+  }
 #endif
 
-  if (gmb_type != gfx::EMPTY_BUFFER) {
-    bool interop_factory_supports_gmb = CanImportGpuMemoryBuffer(gmb_type);
-
-    if (!interop_factory_supports_gmb) {
-      return false;
-    }
-
-    // If |interop_backing_factory_| supports supplied GMB type then use it
-    using_interop_factory |= interop_factory_supports_gmb;
-  }
-
-  if (using_interop_factory) {
-    // TODO(crbug.com/969114): Not all shared image factory implementations
-    // support concurrent read/write usage.
-    if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
-      LOG(ERROR) << "Unable to create SharedImage backing: Interoperability is "
-                    "not supported for concurrent read/write usage";
-      return false;
-    }
-
-    if (thread_safe) {
-      LOG(ERROR) << "ExternalVkImageFactory currently do not support "
-                    "cross-thread usage.";
-      return false;
-    }
-
-    *allow_legacy_mailbox = false;
-    return true;
-  }
-
-  return false;
+  *allow_legacy_mailbox = false;
+  return true;
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
index ca0c558..9be047c7b 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -740,39 +740,20 @@
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
     bool* allow_legacy_mailbox) {
-  bool using_interop_factory = (gr_context_type == GrContextType::kVulkan &&
-                                (usage & SHARED_IMAGE_USAGE_DISPLAY)) ||
-                               (usage & SHARED_IMAGE_USAGE_WEBGPU) ||
-                               (usage & SHARED_IMAGE_USAGE_VIDEO_DECODE) ||
-                               (usage & SHARED_IMAGE_USAGE_SCANOUT);
-
-  if (gmb_type != gfx::EMPTY_BUFFER) {
-    bool interop_factory_supports_gmb = CanImportGpuMemoryBuffer(gmb_type);
-
-    if (!interop_factory_supports_gmb) {
-      return false;
-    }
-
-    // If |interop_backing_factory_| supports supplied GMB type then use it
-    using_interop_factory |= interop_factory_supports_gmb;
+  if (gmb_type != gfx::EMPTY_BUFFER && !CanImportGpuMemoryBuffer(gmb_type)) {
+    return false;
+  }
+  // TODO(crbug.com/969114): Not all shared image factory implementations
+  // support concurrent read/write usage.
+  if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
+    return false;
+  }
+  if (!IsFormatSupported(format)) {
+    return false;
   }
 
-  if (using_interop_factory) {
-    // TODO(crbug.com/969114): Not all shared image factory implementations
-    // support concurrent read/write usage.
-    if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
-      LOG(ERROR) << "Unable to create SharedImage backing: Interoperability is "
-                    "not supported for concurrent read/write usage";
-      return false;
-    }
-
-    if (IsFormatSupported(format)) {
-      *allow_legacy_mailbox = false;
-      return true;
-    }
-  }
-
-  return false;
+  *allow_legacy_mailbox = false;
+  return true;
 }
 
 bool SharedImageBackingFactoryAHB::IsFormatSupported(
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc b/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
index f7bea85..b2a75f4 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
@@ -368,36 +368,17 @@
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
     bool* allow_legacy_mailbox) {
-  bool using_interop_factory = (gr_context_type == GrContextType::kVulkan &&
-                                (usage & SHARED_IMAGE_USAGE_DISPLAY)) ||
-                               (usage & SHARED_IMAGE_USAGE_WEBGPU) ||
-                               (usage & SHARED_IMAGE_USAGE_VIDEO_DECODE);
-
-  if (gmb_type != gfx::EMPTY_BUFFER) {
-    bool interop_factory_supports_gmb = CanImportGpuMemoryBuffer(gmb_type);
-
-    if (!interop_factory_supports_gmb) {
-      return false;
-    }
-
-    // If |interop_backing_factory_| supports supplied GMB type then use it
-    using_interop_factory |= interop_factory_supports_gmb;
+  if (gmb_type != gfx::EMPTY_BUFFER && !CanImportGpuMemoryBuffer(gmb_type)) {
+    return false;
+  }
+  // TODO(crbug.com/969114): Not all shared image factory implementations
+  // support concurrent read/write usage.
+  if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
+    return false;
   }
 
-  if (using_interop_factory) {
-    // TODO(crbug.com/969114): Not all shared image factory implementations
-    // support concurrent read/write usage.
-    if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
-      LOG(ERROR) << "Unable to create SharedImage backing: Interoperability is "
-                    "not supported for concurrent read/write usage";
-      return false;
-    }
-
-    *allow_legacy_mailbox = false;
-    return true;
-  }
-
-  return false;
+  *allow_legacy_mailbox = false;
+  return true;
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
index e0ac358a..7dea181 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
@@ -376,28 +376,29 @@
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
     bool* allow_legacy_mailbox) {
+#if defined(OS_MAC)
+  // On macOS, there is no separate interop factory. Any GpuMemoryBuffer-backed
+  // image can be used with both OpenGL and Metal
+  *allow_legacy_mailbox = gr_context_type == GrContextType::kGL && !thread_safe;
+  return true;
+#else
   bool needs_interop_factory = (gr_context_type == GrContextType::kVulkan &&
                                 (usage & SHARED_IMAGE_USAGE_DISPLAY)) ||
                                (usage & SHARED_IMAGE_USAGE_WEBGPU) ||
                                (usage & SHARED_IMAGE_USAGE_VIDEO_DECODE);
-
 #if defined(OS_ANDROID)
   // Scanout on Android requires explicit fence synchronization which is only
   // supported by the interop factory.
   needs_interop_factory |= usage & SHARED_IMAGE_USAGE_SCANOUT;
-#elif defined(OS_MAC)
-  // On macOS, there is no separate interop factory. Any GpuMemoryBuffer-backed
-  // image can be used with both OpenGL and Metal.
-  needs_interop_factory = false;
 #endif
 
   if (needs_interop_factory) {
     // return false if it needs interop factory
     return false;
   }
-
   *allow_legacy_mailbox = gr_context_type == GrContextType::kGL && !thread_safe;
   return true;
+#endif
 }
 
 std::unique_ptr<SharedImageBacking>
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
index 174558e..01aa9f3 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
@@ -80,26 +80,18 @@
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
     bool* allow_legacy_mailbox) {
-  bool using_dawn = usage & SHARED_IMAGE_USAGE_WEBGPU;
-  bool vulkan_usage = gr_context_type == GrContextType::kVulkan &&
-                      (usage & SHARED_IMAGE_USAGE_DISPLAY);
-  bool using_interop_factory =
-      vulkan_usage || using_dawn || (usage & SHARED_IMAGE_USAGE_VIDEO_DECODE);
-
-  if (using_interop_factory) {
-    // TODO(crbug.com/969114): Not all shared image factory implementations
-    // support concurrent read/write usage.
-    if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
-      LOG(ERROR) << "Unable to create SharedImage backing: Interoperability is "
-                    "not supported for concurrent read/write usage";
-      return false;
-    }
-
-    *allow_legacy_mailbox = false;
-    return true;
+  // Doesn't support gmb for now
+  if (gmb_type != gfx::EMPTY_BUFFER) {
+    return false;
+  }
+  // TODO(crbug.com/969114): Not all shared image factory implementations
+  // support concurrent read/write usage.
+  if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
+    return false;
   }
 
-  return false;
+  *allow_legacy_mailbox = false;
+  return true;
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc
index bda13a8..59015ea 100644
--- a/gpu/command_buffer/service/wrapped_sk_image.cc
+++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -506,13 +506,12 @@
   if (!CanUseWrappedSkImage(usage, gr_context_type) || thread_safe) {
     return false;
   }
-
-  if (gmb_type == gfx::EMPTY_BUFFER || CanImportGpuMemoryBuffer(gmb_type)) {
-    *allow_legacy_mailbox = false;
-    return true;
+  if (gmb_type != gfx::EMPTY_BUFFER && !CanImportGpuMemoryBuffer(gmb_type)) {
+    return false;
   }
 
-  return false;
+  *allow_legacy_mailbox = false;
+  return true;
 }
 
 std::unique_ptr<SharedImageRepresentationSkia> WrappedSkImage::ProduceSkia(
diff --git a/headless/lib/browser/headless_focus_client.cc b/headless/lib/browser/headless_focus_client.cc
index 661c3a2e..c53bc4e 100644
--- a/headless/lib/browser/headless_focus_client.cc
+++ b/headless/lib/browser/headless_focus_client.cc
@@ -9,8 +9,7 @@
 
 namespace headless {
 
-HeadlessFocusClient::HeadlessFocusClient()
-    : focused_window_(nullptr), observer_manager_(this) {}
+HeadlessFocusClient::HeadlessFocusClient() : focused_window_(nullptr) {}
 
 HeadlessFocusClient::~HeadlessFocusClient() = default;
 
@@ -28,12 +27,14 @@
   if (window && !window->CanFocus())
     return;
 
-  if (focused_window_)
-    observer_manager_.Remove(focused_window_);
+  if (focused_window_) {
+    DCHECK(observation_manager_.IsObservingSource(focused_window_));
+    observation_manager_.Reset();
+  }
   aura::Window* old_focused_window = focused_window_;
   focused_window_ = window;
   if (focused_window_)
-    observer_manager_.Add(focused_window_);
+    observation_manager_.Observe(focused_window_);
 
   for (aura::client::FocusChangeObserver& observer : focus_observers_)
     observer.OnWindowFocused(focused_window_, old_focused_window);
diff --git a/headless/lib/browser/headless_focus_client.h b/headless/lib/browser/headless_focus_client.h
index 0739bfa3..303cf56 100644
--- a/headless/lib/browser/headless_focus_client.h
+++ b/headless/lib/browser/headless_focus_client.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "base/observer_list.h"
-#include "base/scoped_observer.h"
+#include "base/scoped_observation.h"
 #include "ui/aura/client/focus_client.h"
 #include "ui/aura/window_observer.h"
 
@@ -31,7 +31,8 @@
   void OnWindowDestroying(aura::Window* window) override;
 
   aura::Window* focused_window_;
-  ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;
+  base::ScopedObservation<aura::Window, aura::WindowObserver>
+      observation_manager_{this};
   base::ObserverList<aura::client::FocusChangeObserver>::Unchecked
       focus_observers_;
 
diff --git a/infra/DIR_METADATA b/infra/DIR_METADATA
index c9e376bb..d2d9af5 100644
--- a/infra/DIR_METADATA
+++ b/infra/DIR_METADATA
@@ -1,10 +1,10 @@
 # Metadata information for this directory.
 #
 # For more information on DIR_METADATA files, see:
-#   https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
 #
 # For the schema of this file, see Metadata message:
-#   https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
   component: "Infra>Client>Chrome"
diff --git a/infra/config/PRESUBMIT.py b/infra/config/PRESUBMIT.py
index 8b6cd0e4..906654e 100644
--- a/infra/config/PRESUBMIT.py
+++ b/infra/config/PRESUBMIT.py
@@ -122,19 +122,19 @@
                               for k, v in sorted(outages_config.items())]
       return [
           output_api.PresubmitError('\n'.join([
-              'The following outages configuration is in effect:\n  {}'.format(
-                  '\n  '.join(outages_config_lines)),
+              'The following outages configuration is in effect:\n  {}'
+              .format('\n  '.join(outages_config_lines)),
               ('The effect of your change may not be visible '
                'in the generated configuration.'),
               ('If your change is addressing the outage, '
-               'please add the footer {} with a link for the outage.'
-               ).format(_OUTAGE_ACTION_FOOTER),
+               'please add the footer {} with a link for the outage.')
+              .format(_OUTAGE_ACTION_FOOTER),
               ('If your change is not addressing the outage '
                'but you still wish to land it, please add the footer '
-               '{} with a reason.').format(_IGNORE_OUTAGE_FOOTER),
+               '{} with a reason.')
+              .format(_IGNORE_OUTAGE_FOOTER),
               ('For more information on outages configuration, '
-               'see https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/outages'
-               ),
+               'see https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/outages'),
           ])),
       ]
 
diff --git a/infra/config/README.md b/infra/config/README.md
index 0d236b0..7314c84 100644
--- a/infra/config/README.md
+++ b/infra/config/README.md
@@ -1,6 +1,6 @@
 **IMPORTANT:** This branch only has an effect for branches that have projects
 set up in
-https://chrome-internal.googlesource.com/infradata/config/+/refs/heads/main/configs/luci-config/projects.cfg
+https://chrome-internal.googlesource.com/infradata/config/+/refs/heads/master/configs/luci-config/projects.cfg
 
 This directory contains chromium project-wide configurations
 for Chrome Operations services.
diff --git a/infra/config/dev/chromium-header.textpb b/infra/config/dev/chromium-header.textpb
index a6ed7cb..521cc65f 100644
--- a/infra/config/dev/chromium-header.textpb
+++ b/infra/config/dev/chromium-header.textpb
@@ -93,7 +93,7 @@
   }
   links: {
     text: "customize"
-    url: "https://chromium.googlesource.com/chromium/src/+/main/infra/config/luci-milo-dev.cfg"
+    url: "https://chromium.googlesource.com/chromium/src/+/master/infra/config/luci-milo-dev.cfg"
       alt: "Customize this console"
   }
 }
diff --git a/infra/config/generated/luci-milo-dev.cfg b/infra/config/generated/luci-milo-dev.cfg
index 6dbecb5..958fb36 100644
--- a/infra/config/generated/luci-milo-dev.cfg
+++ b/infra/config/generated/luci-milo-dev.cfg
@@ -116,7 +116,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/main/infra/config/luci-milo-dev.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/master/infra/config/luci-milo-dev.cfg"
         alt: "Customize this console"
       }
     }
@@ -226,7 +226,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/main/infra/config/luci-milo-dev.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/master/infra/config/luci-milo-dev.cfg"
         alt: "Customize this console"
       }
     }
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg
index 5bec738..c4054b1 100644
--- a/infra/config/generated/luci-milo.cfg
+++ b/infra/config/generated/luci-milo.cfg
@@ -8,7 +8,7 @@
   id: "main"
   name: "Chromium Main Console"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/android-archive-dbg"
@@ -842,7 +842,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -875,7 +875,7 @@
   id: "mirrors"
   name: "Chromium CQ Mirrors Console"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Win x64 Builder"
@@ -1595,7 +1595,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -1628,7 +1628,7 @@
   id: "sheriff.fuchsia"
   name: "Fuchsia Sheriff Console"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Fuchsia ARM64"
@@ -1959,7 +1959,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -1992,7 +1992,7 @@
   id: "sheriff.ios"
   name: "iOS Sheriff Console"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/ios-device"
@@ -2288,7 +2288,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -2518,7 +2518,7 @@
   id: "chromium"
   name: "chromium"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/android-archive-dbg"
@@ -2859,7 +2859,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -2893,7 +2893,7 @@
   id: "chromium.android"
   name: "chromium.android"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/android-cronet-arm-dbg"
@@ -3397,7 +3397,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -3430,7 +3430,7 @@
   id: "chromium.android.fyi"
   name: "chromium.android.fyi"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Android WebView P FYI (rel)"
@@ -3751,7 +3751,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -3784,7 +3784,7 @@
   id: "chromium.angle"
   name: "chromium.angle"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/android-angle-arm64-builder"
@@ -4230,7 +4230,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -4263,7 +4263,7 @@
   id: "chromium.chromiumos"
   name: "chromium.chromiumos"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/linux-ash-chromium-generator-rel"
@@ -4612,7 +4612,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -4645,7 +4645,7 @@
   id: "chromium.clang"
   name: "chromium.clang"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/ToTLinux"
@@ -5121,7 +5121,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -5154,7 +5154,7 @@
   id: "chromium.dawn"
   name: "chromium.dawn"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Dawn Linux x64 Builder"
@@ -5540,7 +5540,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -5573,7 +5573,7 @@
   id: "chromium.fuzz"
   name: "chromium.fuzz"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Afl Upload Linux ASan"
@@ -5988,7 +5988,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -6021,7 +6021,7 @@
   id: "chromium.fyi"
   name: "chromium.fyi"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/android-code-coverage"
@@ -6737,7 +6737,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -7128,7 +7128,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -7483,7 +7483,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -7517,7 +7517,7 @@
   id: "chromium.gpu"
   name: "chromium.gpu"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/GPU Win x64 Builder"
@@ -7838,7 +7838,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -7871,7 +7871,7 @@
   id: "chromium.gpu.fyi"
   name: "chromium.gpu.fyi"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/GPU FYI Win Builder"
@@ -8497,7 +8497,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -8530,7 +8530,7 @@
   id: "chromium.linux"
   name: "chromium.linux"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Linux Builder"
@@ -8926,7 +8926,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -8959,7 +8959,7 @@
   id: "chromium.mac"
   name: "chromium.mac"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Mac Builder"
@@ -9290,7 +9290,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -9323,7 +9323,7 @@
   id: "chromium.memory"
   name: "chromium.memory"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/win-asan"
@@ -9689,7 +9689,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -9722,7 +9722,7 @@
   id: "chromium.mojo"
   name: "chromium.mojo"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Mojo Android"
@@ -10003,7 +10003,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -10036,7 +10036,7 @@
   id: "chromium.packager"
   name: "chromium.packager"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/3pp-linux-amd64-packager"
@@ -10322,7 +10322,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -10621,7 +10621,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -10655,7 +10655,7 @@
   id: "chromium.swangle"
   name: "chromium.swangle"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/win-swangle-x86"
@@ -10976,7 +10976,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -11009,7 +11009,7 @@
   id: "chromium.updater"
   name: "chromium.updater"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/mac10.15-updater-tester-dbg"
@@ -11395,7 +11395,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -11739,7 +11739,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -12123,7 +12123,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -12156,7 +12156,7 @@
   id: "chromium.win"
   name: "chromium.win"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/Win Builder"
@@ -12477,7 +12477,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -12845,7 +12845,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -13157,7 +13157,7 @@
       }
       links {
         text: "customize"
-        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/infra/config/generated/luci-milo.cfg"
+        url: "https://chromium.googlesource.com/chromium/src/+/refs/heads/master/infra/config/generated/luci-milo.cfg"
         alt: "Customize this console"
       }
     }
@@ -14174,7 +14174,7 @@
   id: "metadata.exporter"
   name: "metadata.exporter"
   repo_url: "https://chromium.googlesource.com/chromium/src"
-  refs: "regexp:refs/heads/main"
+  refs: "regexp:refs/heads/master"
   manifest_name: "REVISION"
   builders {
     name: "buildbucket/luci.chromium.ci/metadata-exporter"
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg
index a5ac84e..deeec9f 100644
--- a/infra/config/generated/luci-scheduler.cfg
+++ b/infra/config/generated/luci-scheduler.cfg
@@ -7274,7 +7274,7 @@
   triggers: "WebRTC Chromium Win Builder"
   gitiles {
     repo: "https://chromium.googlesource.com/chromium/src"
-    refs: "regexp:refs/heads/main"
+    refs: "regexp:refs/heads/master"
   }
 }
 trigger {
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star
index f132c61..55592f2 100644
--- a/infra/config/lib/builders.star
+++ b/infra/config/lib/builders.star
@@ -385,7 +385,7 @@
     attribute with a `lucicfg.var` for all of the fields defined here as well as
     all of the parameters of `luci.builder` that support module-level defaults.
 
-    See https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/main/lucicfg/doc/README.md#luci.builder
+    See https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/master/lucicfg/doc/README.md#luci.builder
     for more information.
 
     Arguments:
diff --git a/infra/config/lib/consoles.star b/infra/config/lib/consoles.star
index 107a781..2c870043 100644
--- a/infra/config/lib/consoles.star
+++ b/infra/config/lib/consoles.star
@@ -319,7 +319,7 @@
         short_name = None):
     """Specifies the details of a console view entry.
 
-    See https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/main/lucicfg/doc/README.md#luci.console_view_entry
+    See https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/master/lucicfg/doc/README.md#luci.console_view_entry
     for more details on the arguments.
 
     Args:
diff --git a/infra/config/lib/headers.star b/infra/config/lib/headers.star
index 321d370d..0557799 100644
--- a/infra/config/lib/headers.star
+++ b/infra/config/lib/headers.star
@@ -76,7 +76,7 @@
       text - The display text for the link.
       alt - The alt text for the link. This is supposed to be the hover text
         according to the proto
-        https://chromium.googlesource.com/infra/luci/luci-go/+/main/milo/api/config/project.proto,
+        https://chromium.googlesource.com/infra/luci/luci-go/+/master/milo/api/config/project.proto,
         but doesn't appear to produce any hover text.
       branch_selector - A branch selector value controlling whether the
         link definition is executed. See branches.star for more information.
diff --git a/infra/config/lib/try.star b/infra/config/lib/try.star
index 6a28483..dd935fa2 100644
--- a/infra/config/lib/try.star
+++ b/infra/config/lib/try.star
@@ -46,7 +46,7 @@
         add_default_excludes = True):
     """Specifies the details of a tryjob verifier.
 
-    See https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/main/lucicfg/doc/README.md#luci.cq_tryjob_verifier
+    See https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/master/lucicfg/doc/README.md#luci.cq_tryjob_verifier
     for details on the most of the arguments.
 
     Arguments:
diff --git a/infra/config/settings.json b/infra/config/settings.json
index 610343f..5c879c2 100644
--- a/infra/config/settings.json
+++ b/infra/config/settings.json
@@ -3,6 +3,6 @@
     "project_title": "Chromium",
     "is_main": true,
     "is_lts_branch": false,
-    "ref": "refs/heads/main",
+    "ref": "refs/heads/master",
     "chrome_project": "chrome"
 }
diff --git a/ios/chrome/app/spotlight/topsites_spotlight_manager.mm b/ios/chrome/app/spotlight/topsites_spotlight_manager.mm
index 7d113b3b..6e504feb 100644
--- a/ios/chrome/app/spotlight/topsites_spotlight_manager.mm
+++ b/ios/chrome/app/spotlight/topsites_spotlight_manager.mm
@@ -19,8 +19,8 @@
 #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
 #include "ios/chrome/browser/history/top_sites_factory.h"
 #include "ios/chrome/browser/suggestions/suggestions_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_observer_bridge.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -157,7 +157,7 @@
                                    browserState)
                  bookmarkModel:ios::BookmarkModelFactory::GetForBrowserState(
                                    browserState)
-                   syncService:ProfileSyncServiceFactory::GetForBrowserState(
+                   syncService:SyncServiceFactory::GetForBrowserState(
                                    browserState)
             suggestionsService:suggestions::SuggestionsServiceFactory::
                                    GetForBrowserState(browserState)];
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm
index 9774009..5f21241 100644
--- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm
+++ b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm
@@ -30,7 +30,7 @@
 #include "ios/chrome/browser/pref_names.h"
 #include "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #include "ios/components/webui/web_ui_url_constants.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -42,10 +42,10 @@
 AutocompleteProviderClientImpl::AutocompleteProviderClientImpl(
     ChromeBrowserState* browser_state)
     : browser_state_(browser_state),
-      url_consent_helper_(unified_consent::UrlKeyedDataCollectionConsentHelper::
-                              NewPersonalizedDataCollectionConsentHelper(
-                                  ProfileSyncServiceFactory::GetForBrowserState(
-                                      browser_state_))),
+      url_consent_helper_(
+          unified_consent::UrlKeyedDataCollectionConsentHelper::
+              NewPersonalizedDataCollectionConsentHelper(
+                  SyncServiceFactory::GetForBrowserState(browser_state_))),
       omnibox_triggered_feature_service_(
           std::make_unique<OmniboxTriggeredFeatureService>()) {}
 
@@ -211,7 +211,7 @@
 
 bool AutocompleteProviderClientImpl::IsSyncActive() const {
   syncer::SyncService* sync =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state_);
+      SyncServiceFactory::GetForBrowserState(browser_state_);
   return sync && sync->IsSyncFeatureActive();
 }
 
diff --git a/ios/chrome/browser/browser_state/bookmark_model_loaded_observer.cc b/ios/chrome/browser/browser_state/bookmark_model_loaded_observer.cc
index ec8fa56d..ababf41 100644
--- a/ios/chrome/browser/browser_state/bookmark_model_loaded_observer.cc
+++ b/ios/chrome/browser/browser_state/bookmark_model_loaded_observer.cc
@@ -5,7 +5,7 @@
 #include "ios/chrome/browser/browser_state/bookmark_model_loaded_observer.h"
 
 #include "components/bookmarks/browser/bookmark_model.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 
 BookmarkModelLoadedObserver::BookmarkModelLoadedObserver(
     ChromeBrowserState* browser_state)
@@ -17,7 +17,7 @@
     bookmarks::BookmarkModel* model,
     bool ids_reassigned) {
   // Causes lazy-load if sync is enabled.
-  ProfileSyncServiceFactory::GetForBrowserState(browser_state_);
+  SyncServiceFactory::GetForBrowserState(browser_state_);
   model->RemoveObserver(this);
   delete this;
 }
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
index 60fd751..36d7b1d 100644
--- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
+++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -57,7 +57,7 @@
 #include "ios/chrome/browser/sync/consent_auditor_factory.h"
 #include "ios/chrome/browser/sync/ios_user_event_service_factory.h"
 #include "ios/chrome/browser/sync/model_type_store_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #include "ios/chrome/browser/translate/translate_accept_languages_factory.h"
 #include "ios/chrome/browser/translate/translate_ranker_factory.h"
@@ -134,7 +134,7 @@
   LanguageModelManagerFactory::GetInstance();
   ManagedBookmarkServiceFactory::GetInstance();
   ModelTypeStoreServiceFactory::GetInstance();
-  ProfileSyncServiceFactory::GetInstance();
+  SyncServiceFactory::GetInstance();
   ReadingListModelFactory::GetInstance();
   RealTimeUrlLookupServiceFactory::GetInstance();
   SigninBrowserStateInfoUpdaterFactory::GetInstance();
diff --git a/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.cc b/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.cc
index ef5640b..94670af 100644
--- a/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.cc
+++ b/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.cc
@@ -21,7 +21,7 @@
 #include "ios/chrome/browser/history/history_service_factory.h"
 #include "ios/chrome/browser/history/web_history_service_factory.h"
 #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/webdata_services/web_data_service_factory.h"
 
 namespace {
@@ -37,7 +37,7 @@
             browser_state, ServiceAccessType::EXPLICIT_ACCESS),
         base::BindRepeating(&ios::WebHistoryServiceFactory::GetForBrowserState,
                             base::Unretained(browser_state)),
-        ProfileSyncServiceFactory::GetForBrowserState(browser_state));
+        SyncServiceFactory::GetForBrowserState(browser_state));
   }
 
   if (pref_name == browsing_data::prefs::kDeleteCache) {
@@ -49,14 +49,14 @@
         IOSChromePasswordStoreFactory::GetForBrowserState(
             browser_state, ServiceAccessType::EXPLICIT_ACCESS),
         /*account_store=*/nullptr,
-        ProfileSyncServiceFactory::GetForBrowserState(browser_state));
+        SyncServiceFactory::GetForBrowserState(browser_state));
   }
 
   if (pref_name == browsing_data::prefs::kDeleteFormData) {
     return std::make_unique<browsing_data::AutofillCounter>(
         ios::WebDataServiceFactory::GetAutofillWebDataForBrowserState(
             browser_state, ServiceAccessType::EXPLICIT_ACCESS),
-        ProfileSyncServiceFactory::GetForBrowserState(browser_state));
+        SyncServiceFactory::GetForBrowserState(browser_state));
   }
 
   return nullptr;
diff --git a/ios/chrome/browser/credential_provider/credential_provider_service_factory.mm b/ios/chrome/browser/credential_provider/credential_provider_service_factory.mm
index b5669ac..0475484e 100644
--- a/ios/chrome/browser/credential_provider/credential_provider_service_factory.mm
+++ b/ios/chrome/browser/credential_provider/credential_provider_service_factory.mm
@@ -11,7 +11,7 @@
 #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/common/credential_provider/archivable_credential_store.h"
 #import "ios/chrome/common/credential_provider/constants.h"
 
@@ -40,7 +40,7 @@
   DependsOn(IOSChromePasswordStoreFactory::GetInstance());
   DependsOn(AuthenticationServiceFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 CredentialProviderServiceFactory::~CredentialProviderServiceFactory() = default;
@@ -61,7 +61,7 @@
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForBrowserState(browser_state);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
 
   return std::make_unique<CredentialProviderService>(
       password_store, authentication_service, credential_store,
diff --git a/ios/chrome/browser/history/web_history_service_factory.cc b/ios/chrome/browser/history/web_history_service_factory.cc
index 3f31ba4..a7281ad 100644
--- a/ios/chrome/browser/history/web_history_service_factory.cc
+++ b/ios/chrome/browser/history/web_history_service_factory.cc
@@ -11,7 +11,7 @@
 #include "components/sync/driver/sync_service.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 
@@ -22,7 +22,7 @@
 // false otherwise.
 bool IsHistorySyncEnabled(ChromeBrowserState* browser_state) {
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
   return sync_service && sync_service->IsSyncFeatureActive() &&
          sync_service->GetActiveDataTypes().Has(
              syncer::HISTORY_DELETE_DIRECTIVES);
@@ -52,7 +52,7 @@
     : BrowserStateKeyedServiceFactory(
           "WebHistoryService",
           BrowserStateDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
 }
 
diff --git a/ios/chrome/browser/metrics/chrome_browser_state_client.mm b/ios/chrome/browser/metrics/chrome_browser_state_client.mm
index c27f601..d5d3c0b 100644
--- a/ios/chrome/browser/metrics/chrome_browser_state_client.mm
+++ b/ios/chrome/browser/metrics/chrome_browser_state_client.mm
@@ -9,7 +9,7 @@
 #include "ios/chrome/browser/browser_state/browser_state_info_cache.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -35,7 +35,7 @@
 syncer::SyncService* ChromeBrowserStateClient::GetSyncService() {
   // Get SyncService from BrowserState that was the last to be used. Will create
   // a new BrowserState if no BrowserState exists.
-  return ProfileSyncServiceFactory::GetForBrowserState(
+  return SyncServiceFactory::GetForBrowserState(
       GetApplicationContext()
           ->GetChromeBrowserStateManager()
           ->GetLastUsedBrowserState()
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm
index a0c9561..c2abe86 100644
--- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm
+++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm
@@ -74,7 +74,7 @@
 #include "ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.h"
 #include "ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_delegate.h"
 #include "ios/chrome/browser/sync/device_info_sync_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/tabs/tab_parenting_global_observer.h"
 #include "ios/chrome/browser/translate/translate_ranker_metrics_provider.h"
 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h"
@@ -440,8 +440,7 @@
           browser_state, ServiceAccessType::IMPLICIT_ACCESS);
   ObserveServiceForDeletions(history_service);
   syncer::SyncService* sync =
-      ProfileSyncServiceFactory::GetInstance()->GetForBrowserState(
-          browser_state);
+      SyncServiceFactory::GetInstance()->GetForBrowserState(browser_state);
   StartObserving(sync, browser_state->GetPrefs());
   return (history_service != nullptr && sync != nullptr);
 }
diff --git a/ios/chrome/browser/metrics/ios_profile_session_durations_service_factory.mm b/ios/chrome/browser/metrics/ios_profile_session_durations_service_factory.mm
index fdcfb3ac..1715c80 100644
--- a/ios/chrome/browser/metrics/ios_profile_session_durations_service_factory.mm
+++ b/ios/chrome/browser/metrics/ios_profile_session_durations_service_factory.mm
@@ -16,7 +16,7 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/metrics/ios_profile_session_durations_service.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 
 // static
 IOSProfileSessionDurationsService*
@@ -38,7 +38,7 @@
     : BrowserStateKeyedServiceFactory(
           "IOSProfileSessionDurationsService",
           BrowserStateDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(IdentityManagerFactory::GetInstance());
 }
 
@@ -51,7 +51,7 @@
   ChromeBrowserState* browser_state =
       ChromeBrowserState::FromBrowserState(context);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForBrowserState(browser_state);
   return std::make_unique<IOSProfileSessionDurationsService>(sync_service,
diff --git a/ios/chrome/browser/passwords/ios_chrome_affiliation_service_factory.cc b/ios/chrome/browser/passwords/ios_chrome_affiliation_service_factory.cc
index faf368b..a13b921 100644
--- a/ios/chrome/browser/passwords/ios_chrome_affiliation_service_factory.cc
+++ b/ios/chrome/browser/passwords/ios_chrome_affiliation_service_factory.cc
@@ -12,7 +12,7 @@
 #include "components/password_manager/core/browser/site_affiliation/affiliation_service_impl.h"
 #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 // static
@@ -34,7 +34,7 @@
     : BrowserStateKeyedServiceFactory(
           "AffiliationService",
           BrowserStateDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 IOSChromeAffiliationServiceFactory::~IOSChromeAffiliationServiceFactory() =
@@ -46,7 +46,7 @@
   ChromeBrowserState* browser_state =
       ChromeBrowserState::FromBrowserState(context);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
   return std::make_unique<password_manager::AffiliationServiceImpl>(
       sync_service, context->GetSharedURLLoaderFactory());
 }
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
index 0616a1c..c26bec7 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_client.mm
@@ -36,7 +36,7 @@
 #import "ios/chrome/browser/safe_browsing/chrome_password_protection_service_factory.h"
 #include "ios/chrome/browser/safe_browsing/features.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/system_flags.h"
 #include "ios/chrome/browser/translate/chrome_ios_translate_client.h"
 #import "ios/chrome/browser/ui/ui_feature_flags.h"
@@ -58,7 +58,7 @@
 namespace {
 
 const syncer::SyncService* GetSyncService(ChromeBrowserState* browser_state) {
-  return ProfileSyncServiceFactory::GetForBrowserStateIfExists(browser_state);
+  return SyncServiceFactory::GetForBrowserStateIfExists(browser_state);
 }
 
 }  // namespace
@@ -94,7 +94,7 @@
 
 SyncState IOSChromePasswordManagerClient::GetPasswordSyncState() const {
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(bridge_.browserState);
+      SyncServiceFactory::GetForBrowserState(bridge_.browserState);
   return password_manager_util::GetPasswordSyncState(sync_service);
 }
 
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
index 00a07db..30a45616 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
+++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
@@ -26,7 +26,7 @@
 #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/passwords/credentials_cleaner_runner_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/webdata_services/web_data_service_factory.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
@@ -57,7 +57,7 @@
   scoped_refptr<password_manager::PasswordStore> password_store =
       GetForBrowserState(browser_state, ServiceAccessType::EXPLICIT_ACCESS);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserStateIfExists(browser_state);
+      SyncServiceFactory::GetForBrowserStateIfExists(browser_state);
   password_manager::ToggleAffiliationBasedMatchingBasedOnPasswordSyncedState(
       password_store.get(), sync_service,
       browser_state->GetSharedURLLoaderFactory(),
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm
index 491fde0..6ec4e0ea 100644
--- a/ios/chrome/browser/passwords/password_controller.mm
+++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -55,7 +55,7 @@
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h"
 #import "ios/chrome/browser/passwords/notify_auto_signin_view_controller.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
@@ -423,7 +423,7 @@
   bool isSyncUser = false;
   if (self.browserState) {
     syncer::SyncService* syncService =
-        ProfileSyncServiceFactory::GetForBrowserState(self.browserState);
+        SyncServiceFactory::GetForBrowserState(self.browserState);
     isSyncUser = password_bubble_experiment::IsSmartLockUser(syncService);
   }
   infobars::InfoBarManager* infoBarManager =
diff --git a/ios/chrome/browser/safe_browsing/chrome_password_protection_service.mm b/ios/chrome/browser/safe_browsing/chrome_password_protection_service.mm
index 20ebd19..5590220 100644
--- a/ios/chrome/browser/safe_browsing/chrome_password_protection_service.mm
+++ b/ios/chrome/browser/safe_browsing/chrome_password_protection_service.mm
@@ -39,7 +39,7 @@
 #import "ios/chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
 #include "ios/chrome/browser/sync/ios_user_event_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/web/public/navigation/navigation_item.h"
 #include "ios/web/public/navigation/navigation_manager.h"
 #include "ios/web/public/thread/web_thread.h"
@@ -471,7 +471,7 @@
 
 bool ChromePasswordProtectionService::IsPrimaryAccountSyncing() const {
   syncer::SyncService* sync =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state_);
+      SyncServiceFactory::GetForBrowserState(browser_state_);
   return sync && sync->IsSyncFeatureActive() && !sync->IsLocalSyncEnabled();
 }
 
@@ -802,4 +802,3 @@
 bool ChromePasswordProtectionService::IsSafeBrowsingEnabled() {
   return ::safe_browsing::IsSafeBrowsingEnabled(*GetPrefs());
 }
-
diff --git a/ios/chrome/browser/safe_browsing/chrome_password_protection_service_factory.mm b/ios/chrome/browser/safe_browsing/chrome_password_protection_service_factory.mm
index 2a9917da..13e9ee1 100644
--- a/ios/chrome/browser/safe_browsing/chrome_password_protection_service_factory.mm
+++ b/ios/chrome/browser/safe_browsing/chrome_password_protection_service_factory.mm
@@ -13,7 +13,7 @@
 #import "ios/chrome/browser/safe_browsing/chrome_password_protection_service.h"
 #import "ios/chrome/browser/signin/identity_manager_factory.h"
 #include "ios/chrome/browser/sync/ios_user_event_service_factory.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -41,7 +41,7 @@
   DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(IOSChromePasswordStoreFactory::GetInstance());
   DependsOn(IOSUserEventServiceFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(ios::HistoryServiceFactory::GetInstance());
 }
 
diff --git a/ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.mm b/ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.mm
index b41e77a..26ad549 100644
--- a/ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.mm
+++ b/ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.mm
@@ -17,7 +17,7 @@
 #import "ios/chrome/browser/safe_browsing/user_population.h"
 #import "ios/chrome/browser/safe_browsing/verdict_cache_manager_factory.h"
 #import "ios/chrome/browser/signin/identity_manager_factory.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -44,7 +44,7 @@
           "RealTimeUrlLookupService",
           BrowserStateDependencyManager::GetInstance()) {
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
   DependsOn(VerdictCacheManagerFactory::GetInstance());
 }
 
@@ -68,7 +68,7 @@
       base::BindRepeating(
           &safe_browsing::SyncUtils::
               AreSigninAndSyncSetUpForSafeBrowsingTokenFetches,
-          ProfileSyncServiceFactory::GetForBrowserState(chrome_browser_state),
+          SyncServiceFactory::GetForBrowserState(chrome_browser_state),
           IdentityManagerFactory::GetForBrowserState(chrome_browser_state)),
       chrome_browser_state->IsOffTheRecord(),
       GetApplicationContext()->GetVariationsService(),
diff --git a/ios/chrome/browser/safe_browsing/user_population.mm b/ios/chrome/browser/safe_browsing/user_population.mm
index 3d82b840..547cd9ca 100644
--- a/ios/chrome/browser/safe_browsing/user_population.mm
+++ b/ios/chrome/browser/safe_browsing/user_population.mm
@@ -13,7 +13,7 @@
 #import "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/policy/browser_policy_connector_ios.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -40,7 +40,7 @@
   population.set_is_incognito(browser_state->IsOffTheRecord());
 
   syncer::SyncService* sync =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
   bool is_history_sync_enabled =
       sync && sync->IsSyncFeatureActive() && !sync->IsLocalSyncEnabled() &&
       sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES);
@@ -51,4 +51,4 @@
           GetApplicationContext()->GetBrowserPolicyConnector()));
 
   return population;
-}
\ No newline at end of file
+}
diff --git a/ios/chrome/browser/signin/authentication_service_factory.mm b/ios/chrome/browser/signin/authentication_service_factory.mm
index 1b5b129..fc46aa3 100644
--- a/ios/chrome/browser/signin/authentication_service_factory.mm
+++ b/ios/chrome/browser/signin/authentication_service_factory.mm
@@ -13,7 +13,7 @@
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_delegate.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -30,7 +30,7 @@
       browser_state->GetPrefs(),
       SyncSetupServiceFactory::GetForBrowserState(browser_state),
       IdentityManagerFactory::GetForBrowserState(browser_state),
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state));
+      SyncServiceFactory::GetForBrowserState(browser_state));
 }
 
 }  // namespace
@@ -72,7 +72,7 @@
           BrowserStateDependencyManager::GetInstance()) {
   DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(SyncSetupServiceFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 AuthenticationServiceFactory::~AuthenticationServiceFactory() {}
diff --git a/ios/chrome/browser/signin/authentication_service_fake.mm b/ios/chrome/browser/signin/authentication_service_fake.mm
index 99e1c2b9..24ff5c0 100644
--- a/ios/chrome/browser/signin/authentication_service_fake.mm
+++ b/ios/chrome/browser/signin/authentication_service_fake.mm
@@ -10,7 +10,7 @@
 #import "ios/chrome/browser/signin/authentication_service_delegate_fake.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h"
@@ -95,7 +95,7 @@
       browser_state->GetPrefs(),
       SyncSetupServiceFactory::GetForBrowserState(browser_state),
       IdentityManagerFactory::GetForBrowserState(browser_state),
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state)));
+      SyncServiceFactory::GetForBrowserState(browser_state)));
   service->Initialize(std::make_unique<AuthenticationServiceDelegateFake>());
   return service;
 }
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm
index 35d5cc2..65309b0 100644
--- a/ios/chrome/browser/signin/authentication_service_unittest.mm
+++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -30,7 +30,7 @@
 #import "ios/chrome/browser/signin/authentication_service_delegate_fake.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #include "ios/chrome/browser/system_flags.h"
@@ -70,7 +70,7 @@
 
     TestChromeBrowserState::Builder builder;
     builder.SetPrefService(CreatePrefService());
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&BuildMockSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
@@ -157,7 +157,7 @@
 
   syncer::MockSyncService* mock_sync_service() {
     return static_cast<syncer::MockSyncService*>(
-        ProfileSyncServiceFactory::GetForBrowserState(browser_state_.get()));
+        SyncServiceFactory::GetForBrowserState(browser_state_.get()));
   }
 
   SyncSetupServiceMock* sync_setup_service_mock() {
diff --git a/ios/chrome/browser/suggestions/suggestions_service_factory.mm b/ios/chrome/browser/suggestions/suggestions_service_factory.mm
index e6234f16..dc4f48eb 100644
--- a/ios/chrome/browser/suggestions/suggestions_service_factory.mm
+++ b/ios/chrome/browser/suggestions/suggestions_service_factory.mm
@@ -19,7 +19,7 @@
 #include "components/sync/driver/sync_service.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/web/public/browser_state.h"
 #include "ios/web/public/thread/web_thread.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -48,7 +48,7 @@
           "SuggestionsService",
           BrowserStateDependencyManager::GetInstance()) {
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 SuggestionsServiceFactory::~SuggestionsServiceFactory() {
@@ -62,7 +62,7 @@
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForBrowserState(browser_state);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
 
   std::unique_ptr<SuggestionsStore> suggestions_store(
       new SuggestionsStore(browser_state->GetPrefs()));
diff --git a/ios/chrome/browser/sync/BUILD.gn b/ios/chrome/browser/sync/BUILD.gn
index 797395f6..d7e3b90 100644
--- a/ios/chrome/browser/sync/BUILD.gn
+++ b/ios/chrome/browser/sync/BUILD.gn
@@ -23,8 +23,6 @@
     "ios_user_event_service_factory.h",
     "model_type_store_service_factory.cc",
     "model_type_store_service_factory.h",
-    "profile_sync_service_factory.cc",
-    "profile_sync_service_factory.h",
     "send_tab_to_self_sync_service_factory.h",
     "send_tab_to_self_sync_service_factory.mm",
     "session_sync_service_factory.h",
@@ -33,6 +31,8 @@
     "sync_invalidations_service_factory.mm",
     "sync_observer_bridge.h",
     "sync_observer_bridge.mm",
+    "sync_service_factory.cc",
+    "sync_service_factory.h",
     "sync_setup_service.cc",
     "sync_setup_service.h",
     "sync_setup_service_factory.cc",
@@ -134,8 +134,8 @@
   testonly = true
   sources = [
     "ios_chrome_synced_tab_delegate_unittest.mm",
-    "profile_sync_service_factory_unittest.cc",
     "session_sync_service_factory_unittest.cc",
+    "sync_service_factory_unittest.cc",
   ]
   deps = [
     ":sync",
diff --git a/ios/chrome/browser/sync/glue/sync_start_util.cc b/ios/chrome/browser/sync/glue/sync_start_util.cc
index 6e00c930..7524b70b 100644
--- a/ios/chrome/browser/sync/glue/sync_start_util.cc
+++ b/ios/chrome/browser/sync/glue/sync_start_util.cc
@@ -12,7 +12,7 @@
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/web/public/thread/web_task_traits.h"
 #include "ios/web/public/thread/web_thread.h"
 
@@ -37,7 +37,7 @@
   }
 
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
   if (!sync_service) {
     DVLOG(2) << "No SyncService for browser state, can't start sync.";
     return;
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory.cc b/ios/chrome/browser/sync/sync_service_factory.cc
similarity index 90%
rename from ios/chrome/browser/sync/profile_sync_service_factory.cc
rename to ios/chrome/browser/sync/sync_service_factory.cc
index 1729fca..ed00949 100644
--- a/ios/chrome/browser/sync/profile_sync_service_factory.cc
+++ b/ios/chrome/browser/sync/sync_service_factory.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 "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 
 #include <utility>
 
@@ -68,13 +68,13 @@
 }  // namespace
 
 // static
-ProfileSyncServiceFactory* ProfileSyncServiceFactory::GetInstance() {
-  static base::NoDestructor<ProfileSyncServiceFactory> instance;
+SyncServiceFactory* SyncServiceFactory::GetInstance() {
+  static base::NoDestructor<SyncServiceFactory> instance;
   return instance.get();
 }
 
 // static
-syncer::SyncService* ProfileSyncServiceFactory::GetForBrowserState(
+syncer::SyncService* SyncServiceFactory::GetForBrowserState(
     ChromeBrowserState* browser_state) {
   if (!switches::IsSyncAllowedByFlag())
     return nullptr;
@@ -84,7 +84,7 @@
 }
 
 // static
-syncer::SyncService* ProfileSyncServiceFactory::GetForBrowserStateIfExists(
+syncer::SyncService* SyncServiceFactory::GetForBrowserStateIfExists(
     ChromeBrowserState* browser_state) {
   if (!switches::IsSyncAllowedByFlag())
     return nullptr;
@@ -95,7 +95,7 @@
 
 // static
 syncer::ProfileSyncService*
-ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
+SyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
     ChromeBrowserState* browser_state) {
   return static_cast<syncer::ProfileSyncService*>(
       GetForBrowserState(browser_state));
@@ -103,17 +103,17 @@
 
 // static
 syncer::ProfileSyncService*
-ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserStateIfExists(
+SyncServiceFactory::GetAsProfileSyncServiceForBrowserStateIfExists(
     ChromeBrowserState* browser_state) {
   return static_cast<syncer::ProfileSyncService*>(
       GetForBrowserStateIfExists(browser_state));
 }
 
-ProfileSyncServiceFactory::ProfileSyncServiceFactory()
+SyncServiceFactory::SyncServiceFactory()
     : BrowserStateKeyedServiceFactory(
-          "ProfileSyncService",
+          "SyncService",
           BrowserStateDependencyManager::GetInstance()) {
-  // The ProfileSyncService depends on various SyncableServices being around
+  // The SyncService depends on various SyncableServices being around
   // when it is shut down.  Specify those dependencies here to build the proper
   // destruction order.
   DependsOn(autofill::PersonalDataManagerFactory::GetInstance());
@@ -137,10 +137,9 @@
   DependsOn(SyncInvalidationsServiceFactory::GetInstance());
 }
 
-ProfileSyncServiceFactory::~ProfileSyncServiceFactory() {}
+SyncServiceFactory::~SyncServiceFactory() {}
 
-std::unique_ptr<KeyedService>
-ProfileSyncServiceFactory::BuildServiceInstanceFor(
+std::unique_ptr<KeyedService> SyncServiceFactory::BuildServiceInstanceFor(
     web::BrowserState* context) const {
   ChromeBrowserState* browser_state =
       ChromeBrowserState::FromBrowserState(context);
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory.h b/ios/chrome/browser/sync/sync_service_factory.h
similarity index 71%
rename from ios/chrome/browser/sync/profile_sync_service_factory.h
rename to ios/chrome/browser/sync/sync_service_factory.h
index 9ec08ebc..8672f58 100644
--- a/ios/chrome/browser/sync/profile_sync_service_factory.h
+++ b/ios/chrome/browser/sync/sync_service_factory.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 IOS_CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
-#define IOS_CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
+#ifndef IOS_CHROME_BROWSER_SYNC_SYNC_SERVICE_FACTORY_H_
+#define IOS_CHROME_BROWSER_SYNC_SYNC_SERVICE_FACTORY_H_
 
 #include <memory>
 
@@ -20,7 +20,7 @@
 
 // Singleton that owns all SyncServices and associates them with
 // ChromeBrowserState.
-class ProfileSyncServiceFactory : public BrowserStateKeyedServiceFactory {
+class SyncServiceFactory : public BrowserStateKeyedServiceFactory {
  public:
   static syncer::SyncService* GetForBrowserState(
       ChromeBrowserState* browser_state);
@@ -35,17 +35,17 @@
   GetAsProfileSyncServiceForBrowserStateIfExists(
       ChromeBrowserState* browser_state);
 
-  static ProfileSyncServiceFactory* GetInstance();
+  static SyncServiceFactory* GetInstance();
 
  private:
-  friend class base::NoDestructor<ProfileSyncServiceFactory>;
+  friend class base::NoDestructor<SyncServiceFactory>;
 
-  ProfileSyncServiceFactory();
-  ~ProfileSyncServiceFactory() override;
+  SyncServiceFactory();
+  ~SyncServiceFactory() override;
 
   // BrowserStateKeyedServiceFactory implementation.
   std::unique_ptr<KeyedService> BuildServiceInstanceFor(
       web::BrowserState* context) const override;
 };
 
-#endif  // IOS_CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_FACTORY_H_
+#endif  // IOS_CHROME_BROWSER_SYNC_SYNC_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/ios/chrome/browser/sync/sync_service_factory_unittest.cc
similarity index 89%
rename from ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
rename to ios/chrome/browser/sync/sync_service_factory_unittest.cc
index 9a042e6..99d0cfc 100644
--- a/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
+++ b/ios/chrome/browser/sync/sync_service_factory_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 
 #include <stddef.h>
 
@@ -24,9 +24,9 @@
 
 using syncer::DataTypeController;
 
-class ProfileSyncServiceFactoryTest : public PlatformTest {
+class SyncServiceFactoryTest : public PlatformTest {
  public:
-  ProfileSyncServiceFactoryTest() {
+  SyncServiceFactoryTest() {
     TestChromeBrowserState::Builder browser_state_builder;
     // BOOKMARKS requires the FaviconService, which requires the HistoryService.
     browser_state_builder.AddTestingFactory(
@@ -112,17 +112,16 @@
 };
 
 // Verify that the disable sync flag disables creation of the sync service.
-TEST_F(ProfileSyncServiceFactoryTest, DisableSyncFlag) {
+TEST_F(SyncServiceFactoryTest, DisableSyncFlag) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kDisableSync);
-  EXPECT_FALSE(
-      ProfileSyncServiceFactory::GetForBrowserState(chrome_browser_state()));
+  EXPECT_FALSE(SyncServiceFactory::GetForBrowserState(chrome_browser_state()));
 }
 
 // Verify that a normal (no command line flags) PSS can be created and
 // properly initialized.
-TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDefault) {
+TEST_F(SyncServiceFactoryTest, CreatePSSDefault) {
   syncer::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
+      SyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
           chrome_browser_state());
   syncer::ModelTypeSet types = sync_service->GetRegisteredDataTypesForTest();
   EXPECT_EQ(DefaultDatatypesCount(), types.Size());
@@ -131,11 +130,11 @@
 
 // Verify that a PSS with a disabled datatype can be created and properly
 // initialized.
-TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDisableOne) {
+TEST_F(SyncServiceFactoryTest, CreatePSSDisableOne) {
   syncer::ModelTypeSet disabled_types(syncer::AUTOFILL);
   SetDisabledTypes(disabled_types);
   syncer::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
+      SyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
           chrome_browser_state());
   syncer::ModelTypeSet types = sync_service->GetRegisteredDataTypesForTest();
   EXPECT_EQ(DefaultDatatypesCount() - disabled_types.Size(), types.Size());
@@ -144,12 +143,12 @@
 
 // Verify that a PSS with multiple disabled datatypes can be created and
 // properly initialized.
-TEST_F(ProfileSyncServiceFactoryTest, CreatePSSDisableMultiple) {
+TEST_F(SyncServiceFactoryTest, CreatePSSDisableMultiple) {
   syncer::ModelTypeSet disabled_types(syncer::AUTOFILL_PROFILE,
                                       syncer::BOOKMARKS);
   SetDisabledTypes(disabled_types);
   syncer::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
+      SyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
           chrome_browser_state());
   syncer::ModelTypeSet types = sync_service->GetRegisteredDataTypesForTest();
   EXPECT_EQ(DefaultDatatypesCount() - disabled_types.Size(), types.Size());
diff --git a/ios/chrome/browser/sync/sync_setup_service_factory.cc b/ios/chrome/browser/sync/sync_setup_service_factory.cc
index 5d5a411..a9005e3 100644
--- a/ios/chrome/browser/sync/sync_setup_service_factory.cc
+++ b/ios/chrome/browser/sync/sync_setup_service_factory.cc
@@ -8,7 +8,7 @@
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "components/sync/driver/sync_service.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 
 // static
@@ -35,7 +35,7 @@
     : BrowserStateKeyedServiceFactory(
           "SyncSetupService",
           BrowserStateDependencyManager::GetInstance()) {
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 SyncSetupServiceFactory::~SyncSetupServiceFactory() {
@@ -46,5 +46,5 @@
   ChromeBrowserState* browser_state =
       ChromeBrowserState::FromBrowserState(context);
   return std::make_unique<SyncSetupService>(
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state));
+      SyncServiceFactory::GetForBrowserState(browser_state));
 }
diff --git a/ios/chrome/browser/sync/sync_setup_service_mock.cc b/ios/chrome/browser/sync/sync_setup_service_mock.cc
index 794591c..f2e01d734 100644
--- a/ios/chrome/browser/sync/sync_setup_service_mock.cc
+++ b/ios/chrome/browser/sync/sync_setup_service_mock.cc
@@ -5,7 +5,7 @@
 #import "ios/chrome/browser/sync/sync_setup_service_mock.h"
 
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/web/public/browser_state.h"
 
 SyncSetupServiceMock::SyncSetupServiceMock(syncer::SyncService* sync_service)
@@ -23,5 +23,5 @@
   ChromeBrowserState* browser_state =
       ChromeBrowserState::FromBrowserState(context);
   return std::make_unique<SyncSetupServiceMock>(
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state));
+      SyncServiceFactory::GetForBrowserState(browser_state));
 }
diff --git a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.mm
index 8db360e..9b7c13d 100644
--- a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.mm
@@ -13,7 +13,7 @@
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/identity_manager_factory.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service.h"
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
@@ -82,8 +82,7 @@
       SyncSetupServiceFactory::GetForBrowserState(
           self.browser->GetBrowserState());
   syncer::SyncService* syncService =
-      ProfileSyncServiceFactory::GetForBrowserState(
-          self.browser->GetBrowserState());
+      SyncServiceFactory::GetForBrowserState(self.browser->GetBrowserState());
   self.advancedSettingsSigninMediator = [[AdvancedSettingsSigninMediator alloc]
       initWithSyncSetupService:syncSetupService
          authenticationService:authenticationService
diff --git a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_mediator_unittest.mm b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_mediator_unittest.mm
index 89b4d13..09f59a1 100644
--- a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_mediator_unittest.mm
@@ -15,7 +15,7 @@
 #import "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity.h"
@@ -59,7 +59,7 @@
         AuthenticationServiceFactory::GetInstance(),
         base::BindRepeating(
             &AuthenticationServiceFake::CreateAuthenticationService));
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&CreateMockSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
@@ -102,7 +102,7 @@
   }
 
   SyncService* sync_service() {
-    return ProfileSyncServiceFactory::GetForBrowserState(browser_state_.get());
+    return SyncServiceFactory::GetForBrowserState(browser_state_.get());
   }
 
   ios::FakeChromeIdentityService* identity_service() {
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator_unittest.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator_unittest.mm
index 9f0d2c0b..1e24c721 100644
--- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_mediator_unittest.mm
@@ -17,7 +17,7 @@
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
 #import "ios/chrome/browser/signin/identity_manager_factory.h"
 #import "ios/chrome/browser/sync/consent_auditor_factory.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/browser/ui/authentication/authentication_flow.h"
@@ -67,7 +67,7 @@
             &AuthenticationServiceFake::CreateAuthenticationService));
     builder.AddTestingFactory(ConsentAuditorFactory::GetInstance(),
                               base::BindRepeating(&CreateFakeConsentAuditor));
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&CreateMockSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm
index 8ff141f..7b0d52d 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm
@@ -19,7 +19,7 @@
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
 #include "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view.h"
@@ -62,7 +62,7 @@
     close_button_hidden_ = YES;
 
     TestChromeBrowserState::Builder builder;
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&BuildMockSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator_unittest.mm b/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator_unittest.mm
index 93d21e7..26051cf 100644
--- a/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/signout_action_sheet_coordinator_unittest.mm
@@ -13,7 +13,7 @@
 #import "ios/chrome/browser/main/test_browser.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/test/scoped_key_window.h"
@@ -57,7 +57,7 @@
         AuthenticationServiceFactory::GetInstance(),
         base::BindRepeating(
             &AuthenticationServiceFake::CreateAuthenticationService));
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&BuildMockSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
@@ -68,7 +68,7 @@
         std::make_unique<TestBrowser>(browser_state_.get(), web_state_list);
 
     sync_service_mock_ = static_cast<syncer::MockSyncService*>(
-        ProfileSyncServiceFactory::GetForBrowserState(browser_state_.get()));
+        SyncServiceFactory::GetForBrowserState(browser_state_.get()));
   }
 
   // Identity services.
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
index ef6971d..113c6dfa 100644
--- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
+++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -41,7 +41,7 @@
 #include "ios/chrome/browser/infobars/infobar_utils.h"
 #import "ios/chrome/browser/passwords/password_tab_helper.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/translate/chrome_ios_translate_client.h"
 #include "ios/chrome/browser/ui/autofill/card_expiration_date_fix_flow_view_bridge.h"
 #include "ios/chrome/browser/ui/autofill/card_name_fix_flow_view_bridge.h"
@@ -88,8 +88,7 @@
     id<AutofillClientIOSBridge> bridge,
     password_manager::PasswordManager* password_manager)
     : pref_service_(browser_state->GetPrefs()),
-      sync_service_(
-          ProfileSyncServiceFactory::GetForBrowserState(browser_state)),
+      sync_service_(SyncServiceFactory::GetForBrowserState(browser_state)),
       personal_data_manager_(PersonalDataManagerFactory::GetForBrowserState(
           browser_state->GetOriginalChromeBrowserState())),
       autocomplete_history_manager_(
diff --git a/ios/chrome/browser/ui/bookmarks/synced_bookmarks_bridge.mm b/ios/chrome/browser/ui/bookmarks/synced_bookmarks_bridge.mm
index f53ae2f..5798f836 100644
--- a/ios/chrome/browser/ui/bookmarks/synced_bookmarks_bridge.mm
+++ b/ios/chrome/browser/ui/bookmarks/synced_bookmarks_bridge.mm
@@ -8,7 +8,7 @@
 #include "components/sync/driver/sync_service.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 
@@ -23,9 +23,8 @@
 SyncedBookmarksObserverBridge::SyncedBookmarksObserverBridge(
     id<SyncObserverModelBridge> delegate,
     ChromeBrowserState* browserState)
-    : SyncObserverBridge(
-          delegate,
-          ProfileSyncServiceFactory::GetForBrowserState(browserState)),
+    : SyncObserverBridge(delegate,
+                         SyncServiceFactory::GetForBrowserState(browserState)),
       identity_manager_(
           IdentityManagerFactory::GetForBrowserState(browserState)),
       browser_state_(browserState) {}
diff --git a/ios/chrome/browser/ui/history/history_coordinator.mm b/ios/chrome/browser/ui/history/history_coordinator.mm
index 61de5369..c7640c9 100644
--- a/ios/chrome/browser/ui/history/history_coordinator.mm
+++ b/ios/chrome/browser/ui/history/history_coordinator.mm
@@ -13,7 +13,7 @@
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/main/browser_observer_bridge.h"
 #import "ios/chrome/browser/policy/policy_util.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/ui/activity_services/activity_params.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
 #import "ios/chrome/browser/ui/history/history_clear_browsing_data_coordinator.h"
@@ -96,8 +96,7 @@
       _browsingHistoryDriver.get(),
       ios::HistoryServiceFactory::GetForBrowserState(
           self.browser->GetBrowserState(), ServiceAccessType::EXPLICIT_ACCESS),
-      ProfileSyncServiceFactory::GetForBrowserState(
-          self.browser->GetBrowserState()));
+      SyncServiceFactory::GetForBrowserState(self.browser->GetBrowserState()));
   self.historyTableViewController.historyService =
       _browsingHistoryService.get();
 
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator_unittest.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator_unittest.mm
index ae127fb..022b015 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator_unittest.mm
@@ -20,7 +20,6 @@
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #include "ios/chrome/browser/main/test_browser.h"
 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/session_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
index b84b882..519a8ec1 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
@@ -36,7 +36,7 @@
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
@@ -345,7 +345,7 @@
 
   [model addSectionWithIdentifier:SectionIdentifierSavedSiteData];
   syncer::SyncService* syncService =
-      ProfileSyncServiceFactory::GetForBrowserState(self.browserState);
+      SyncServiceFactory::GetForBrowserState(self.browserState);
   if (syncService && syncService->IsSyncFeatureActive()) {
     [model setFooter:[self footerClearSyncAndSavedSiteDataItem]
         forSectionWithIdentifier:SectionIdentifierSavedSiteData];
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager_unittest.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager_unittest.mm
index 24500bc..b76b8440 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager_unittest.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager_unittest.mm
@@ -20,7 +20,7 @@
 #include "ios/chrome/browser/signin/authentication_service.h"
 #include "ios/chrome/browser/signin/authentication_service_delegate_fake.h"
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/browser/ui/settings/clear_browsing_data/fake_browsing_data_counter_wrapper_producer.h"
@@ -56,7 +56,7 @@
     RegisterBrowserStatePrefs(registry.get());
 
     TestChromeBrowserState::Builder builder;
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&CreateTestSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
@@ -82,7 +82,7 @@
             [[FakeBrowsingDataCounterWrapperProducer alloc] init]];
 
     test_sync_service_ = static_cast<syncer::TestSyncService*>(
-        ProfileSyncServiceFactory::GetForBrowserState(browser_state_.get()));
+        SyncServiceFactory::GetForBrowserState(browser_state_.get()));
 
     time_range_pref_.Init(browsing_data::prefs::kDeleteTimePeriod,
                           browser_state_->GetPrefs());
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
index 70c5d10..9ba0747 100644
--- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -20,7 +20,6 @@
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
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 cc77522a..33a438b7 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
@@ -15,7 +15,7 @@
 #include "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
@@ -121,8 +121,8 @@
       self.browser->GetBrowserState());
   self.mediator.commandHandler = self;
   self.mediator.syncErrorHandler = self;
-  self.mediator.syncService = ProfileSyncServiceFactory::GetForBrowserState(
-      self.browser->GetBrowserState());
+  self.mediator.syncService =
+      SyncServiceFactory::GetForBrowserState(self.browser->GetBrowserState());
   viewController.modelDelegate = self.mediator;
   viewController.serviceDelegate = self.mediator;
   viewController.dispatcher = static_cast<
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 7475c95..b1ac8c76 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
@@ -17,8 +17,8 @@
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_observer_bridge.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
@@ -145,7 +145,7 @@
 #pragma mark - Properties
 
 - (syncer::SyncService*)syncService {
-  return ProfileSyncServiceFactory::GetForBrowserState(
+  return SyncServiceFactory::GetForBrowserState(
       self.browser->GetBrowserState());
 }
 
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
index 00a2315..3582872 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
@@ -14,7 +14,6 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/sync/driver/sync_service.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_observer_bridge.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #import "ios/chrome/browser/ui/list_model/list_model.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator_unittest.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator_unittest.mm
index 0f9f3f5..2aa7f4f 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator_unittest.mm
@@ -17,7 +17,7 @@
 #import "ios/chrome/browser/main/test_browser.h"
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h"
@@ -74,7 +74,7 @@
     identity_service()->AddIdentity(identity);
 
     TestChromeBrowserState::Builder builder;
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&CreateMockSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
@@ -99,7 +99,7 @@
     sync_setup_service_mock_ = static_cast<SyncSetupServiceMock*>(
         SyncSetupServiceFactory::GetForBrowserState(browser_state_.get()));
     sync_service_mock_ = static_cast<syncer::MockSyncService*>(
-        ProfileSyncServiceFactory::GetForBrowserState(browser_state_.get()));
+        SyncServiceFactory::GetForBrowserState(browser_state_.get()));
 
     mediator_ = [[ManageSyncSettingsMediator alloc]
         initWithSyncService:sync_service_mock_
diff --git a/ios/chrome/browser/ui/settings/passphrase_table_view_controller_test.mm b/ios/chrome/browser/ui/settings/passphrase_table_view_controller_test.mm
index 7301bd4..02f1226d 100644
--- a/ios/chrome/browser/ui/settings/passphrase_table_view_controller_test.mm
+++ b/ios/chrome/browser/ui/settings/passphrase_table_view_controller_test.mm
@@ -21,7 +21,7 @@
 #include "ios/chrome/browser/prefs/browser_prefs.h"
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/main/scene_state.h"
@@ -86,7 +86,7 @@
   SceneStateBrowserAgent::CreateForBrowser(browser_.get(), scene_state_);
 
   fake_sync_service_ = static_cast<syncer::MockSyncService*>(
-      ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+      SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
           chrome_browser_state_.get(),
           base::BindRepeating(&CreateNiceMockSyncService)));
 
diff --git a/ios/chrome/browser/ui/settings/password/passwords_mediator_unittest.mm b/ios/chrome/browser/ui/settings/password/passwords_mediator_unittest.mm
index f000a1d..c5f95783 100644
--- a/ios/chrome/browser/ui/settings/password/passwords_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/password/passwords_mediator_unittest.mm
@@ -22,7 +22,6 @@
 #include "ios/chrome/browser/passwords/password_check_observer_bridge.h"
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/browser/ui/settings/password/passwords_consumer.h"
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm
index 8a6cadf..f552798 100644
--- a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm
@@ -24,7 +24,7 @@
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/policy/policy_util.h"
 #include "ios/chrome/browser/pref_names.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h"
@@ -221,8 +221,7 @@
   std::vector<GURL> urls;
 
   syncer::SyncService* syncService =
-      ProfileSyncServiceFactory::GetInstance()->GetForBrowserState(
-          _browserState);
+      SyncServiceFactory::GetInstance()->GetForBrowserState(_browserState);
 
   if (!signin::IsMobileIdentityConsistencyEnabled()) {
     privacyFooterText =
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller_unittest.mm
index 91d2e746..d8d10586 100644
--- a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller_unittest.mm
@@ -23,7 +23,7 @@
 #import "ios/chrome/browser/main/test_browser.h"
 #include "ios/chrome/browser/pref_names.h"
 #include "ios/chrome/browser/prefs/browser_prefs.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/system_flags.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
@@ -54,7 +54,7 @@
     TestChromeBrowserState::Builder test_cbs_builder;
     test_cbs_builder.SetPrefService(CreatePrefService());
     test_cbs_builder.AddTestingFactory(
-        ProfileSyncServiceFactory::GetInstance(),
+        SyncServiceFactory::GetInstance(),
         base::BindRepeating(&BuildMockSyncService));
     chrome_browser_state_ = test_cbs_builder.Build();
 
@@ -94,8 +94,7 @@
 
   syncer::MockSyncService* mock_sync_service() {
     return static_cast<syncer::MockSyncService*>(
-        ProfileSyncServiceFactory::GetForBrowserState(
-            chrome_browser_state_.get()));
+        SyncServiceFactory::GetForBrowserState(chrome_browser_state_.get()));
   }
 
   web::WebTaskEnvironment task_environment_;
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm
index 0575fc1..9a001a8a 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.mm
@@ -17,7 +17,6 @@
 #include "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h"
 #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service.h"
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
index ee8f09f..ba3c793 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
@@ -31,7 +31,6 @@
 #include "ios/chrome/browser/passwords/password_check_observer_bridge.h"
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/browser/ui/settings/cells/settings_check_item.h"
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index b0eb757..e448d753 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -44,8 +44,8 @@
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_observer_bridge.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #include "ios/chrome/browser/system_flags.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_consumer.h"
@@ -154,7 +154,7 @@
 
 SyncState GetSyncStateFromBrowserState(ChromeBrowserState* browserState) {
   syncer::SyncService* syncService =
-      ProfileSyncServiceFactory::GetForBrowserState(browserState);
+      SyncServiceFactory::GetForBrowserState(browserState);
   SyncSetupService* syncSetupService =
       SyncSetupServiceFactory::GetForBrowserState(browserState);
   // Sync is disabled by administrator policy.
@@ -323,7 +323,7 @@
     _identityObserverBridge.reset(
         new signin::IdentityManagerObserverBridge(identityManager, self));
     syncer::SyncService* syncService =
-        ProfileSyncServiceFactory::GetForBrowserState(_browserState);
+        SyncServiceFactory::GetForBrowserState(_browserState);
     _syncObserverBridge.reset(new SyncObserverBridge(self, syncService));
 
     _showMemoryDebugToolsEnabled = [[PrefBackedBoolean alloc]
@@ -648,7 +648,7 @@
 // previously closed or seen too many times by a single user account.
 - (BOOL)shouldDisplaySyncPromo {
   syncer::SyncService* syncService =
-      ProfileSyncServiceFactory::GetForBrowserState(_browserState);
+      SyncServiceFactory::GetForBrowserState(_browserState);
   return base::FeatureList::IsEnabled(signin::kMobileIdentityConsistency) &&
          [SigninPromoViewMediator
              shouldDisplaySigninPromoViewWithAccessPoint:
@@ -1541,7 +1541,7 @@
     (SettingsImageDetailTextItem*)googleServicesItem {
   googleServicesItem.detailTextColor = nil;
   syncer::SyncService* syncService =
-      ProfileSyncServiceFactory::GetForBrowserState(_browserState);
+      SyncServiceFactory::GetForBrowserState(_browserState);
   SyncSetupService* syncSetupService =
       SyncSetupServiceFactory::GetForBrowserState(_browserState);
   AuthenticationService* authService =
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller_mice_unittest.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller_mice_unittest.mm
index 5d7aa08..b4454fb 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller_mice_unittest.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller_mice_unittest.mm
@@ -16,7 +16,7 @@
 #import "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service.h"
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_mock.h"
@@ -61,7 +61,7 @@
     ChromeTableViewControllerTest::SetUp();
 
     TestChromeBrowserState::Builder builder;
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&CreateMockSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
@@ -83,8 +83,7 @@
         SyncSetupServiceFactory::GetForBrowserState(
             chrome_browser_state_.get()));
     sync_service_mock_ = static_cast<syncer::MockSyncService*>(
-        ProfileSyncServiceFactory::GetForBrowserState(
-            chrome_browser_state_.get()));
+        SyncServiceFactory::GetForBrowserState(chrome_browser_state_.get()));
 
     auth_service_ = static_cast<AuthenticationServiceFake*>(
         AuthenticationServiceFactory::GetInstance()->GetForBrowserState(
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller_unittest.mm
index 3988d3c..8a813e8 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller_unittest.mm
@@ -24,7 +24,7 @@
 #import "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/authentication_service_fake.h"
-#import "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
@@ -71,7 +71,7 @@
     ChromeTableViewControllerTest::SetUp();
 
     TestChromeBrowserState::Builder builder;
-    builder.AddTestingFactory(ProfileSyncServiceFactory::GetInstance(),
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                               base::BindRepeating(&CreateMockSyncService));
     builder.AddTestingFactory(
         SyncSetupServiceFactory::GetInstance(),
@@ -94,8 +94,7 @@
         SyncSetupServiceFactory::GetForBrowserState(
             chrome_browser_state_.get()));
     sync_service_mock_ = static_cast<syncer::MockSyncService*>(
-        ProfileSyncServiceFactory::GetForBrowserState(
-            chrome_browser_state_.get()));
+        SyncServiceFactory::GetForBrowserState(chrome_browser_state_.get()));
 
     auth_service_ = static_cast<AuthenticationServiceFake*>(
         AuthenticationServiceFactory::GetInstance()->GetForBrowserState(
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm
index c5443318..02129b01 100644
--- a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm
@@ -24,7 +24,7 @@
 #import "ios/chrome/browser/signin/authentication_service.h"
 #include "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/main/scene_state.h"
@@ -101,7 +101,7 @@
 
   ChromeBrowserState* browserState = _browser->GetBrowserState();
   syncer::SyncService* service =
-      ProfileSyncServiceFactory::GetForBrowserState(browserState);
+      SyncServiceFactory::GetForBrowserState(browserState);
   // TODO(crbug.com/1208307): The reason this is an if and not a DCHECK is
   // because SyncCreatePassphraseTableViewController inherits from this class.
   // This should be changed, i.e. either extract the minimum common logic
@@ -303,14 +303,14 @@
 
   if (!_syncObserver.get()) {
     _syncObserver.reset(new SyncObserverBridge(
-        self, ProfileSyncServiceFactory::GetForBrowserState(browserState)));
+        self, SyncServiceFactory::GetForBrowserState(browserState)));
   }
 
   // Clear out the error message.
   self.syncErrorMessage = nil;
 
   syncer::SyncService* service =
-      ProfileSyncServiceFactory::GetForBrowserState(browserState);
+      SyncServiceFactory::GetForBrowserState(browserState);
   DCHECK(service);
   // It is possible for a race condition to happen where a user is allowed
   // to call the backend with the passphrase before the backend is
@@ -489,7 +489,7 @@
 - (void)onSyncStateChanged {
   ChromeBrowserState* browserState = self.browser->GetBrowserState();
   syncer::SyncService* service =
-      ProfileSyncServiceFactory::GetForBrowserState(browserState);
+      SyncServiceFactory::GetForBrowserState(browserState);
 
   if (!service->IsEngineInitialized()) {
     return;
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller_unittest.mm
index 85c0405..5ec11e4 100644
--- a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller_unittest.mm
@@ -17,7 +17,6 @@
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service_mock.h"
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm
index 71d8b208c..b8933b4e 100644
--- a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm
@@ -18,8 +18,8 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
 #import "ios/chrome/browser/main/browser.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
 #import "ios/chrome/browser/sync/sync_observer_bridge.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/ui/settings/settings_controller_protocol.h"
 #import "ios/chrome/browser/ui/settings/sync/sync_create_passphrase_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.h"
@@ -77,7 +77,7 @@
     ChromeBrowserState* browserState = self.browser->GetBrowserState();
     self.title = l10n_util::GetNSString(IDS_IOS_SYNC_ENCRYPTION_TITLE);
     syncer::SyncService* syncService =
-        ProfileSyncServiceFactory::GetForBrowserState(browserState);
+        SyncServiceFactory::GetForBrowserState(browserState);
     _isUsingExplicitPassphrase =
         syncService->IsEngineInitialized() &&
         syncService->GetUserSettings()->IsUsingExplicitPassphrase();
@@ -175,7 +175,7 @@
       DCHECK(switches::IsSyncAllowedByFlag());
       ChromeBrowserState* browserState = self.browser->GetBrowserState();
       syncer::SyncService* service =
-          ProfileSyncServiceFactory::GetForBrowserState(browserState);
+          SyncServiceFactory::GetForBrowserState(browserState);
       if (service->IsEngineInitialized() &&
           !service->GetUserSettings()->IsUsingExplicitPassphrase()) {
         SyncCreatePassphraseTableViewController* controller =
@@ -220,7 +220,7 @@
       << "onSyncStateChanged called after -settingsWillBeDismissed";
   ChromeBrowserState* browserState = self.browser->GetBrowserState();
   syncer::SyncService* service =
-      ProfileSyncServiceFactory::GetForBrowserState(browserState);
+      SyncServiceFactory::GetForBrowserState(browserState);
   BOOL isNowUsingExplicitPassphrase =
       service->IsEngineInitialized() &&
       service->GetUserSettings()->IsUsingExplicitPassphrase();
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller_unittest.mm
index 3fb2cd7c..84670a74 100644
--- a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller_unittest.mm
@@ -12,7 +12,7 @@
 #include "components/sync/driver/test_sync_service.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/main/test_browser.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -38,7 +38,7 @@
   void SetUp() override {
     TestChromeBrowserState::Builder test_cbs_builder;
     test_cbs_builder.AddTestingFactory(
-        ProfileSyncServiceFactory::GetInstance(),
+        SyncServiceFactory::GetInstance(),
         base::BindRepeating(&CreateTestSyncService));
     browser_ = std::make_unique<TestBrowser>();
     ChromeTableViewControllerTest::SetUp();
@@ -46,7 +46,7 @@
     ChromeBrowserState* browserState = browser_.get()->GetBrowserState();
     syncer::TestSyncService* test_sync_service =
         static_cast<syncer::TestSyncService*>(
-            ProfileSyncServiceFactory::GetForBrowserState(browserState));
+            SyncServiceFactory::GetForBrowserState(browserState));
     test_sync_service->SetIsUsingExplicitPassphrase(true);
 
     CreateController();
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 a7d7930..720d085 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
@@ -19,7 +19,7 @@
 #include "components/sync/driver/sync_service_utils.h"
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/infobars/infobar_utils.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/ui/settings/sync/utils/sync_presenter.h"
@@ -59,13 +59,13 @@
 
   // Register for sync status changes.
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state_);
+      SyncServiceFactory::GetForBrowserState(browser_state_);
   sync_service->AddObserver(this);
 }
 
 SyncErrorInfoBarDelegate::~SyncErrorInfoBarDelegate() {
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state_);
+      SyncServiceFactory::GetForBrowserState(browser_state_);
   sync_service->RemoveObserver(this);
 }
 
diff --git a/ios/chrome/browser/ui/webui/chrome_web_ui_provider.cc b/ios/chrome/browser/ui/webui/chrome_web_ui_provider.cc
index e52a598..00610d7 100644
--- a/ios/chrome/browser/ui/webui/chrome_web_ui_provider.cc
+++ b/ios/chrome/browser/ui/webui/chrome_web_ui_provider.cc
@@ -5,14 +5,14 @@
 #include "ios/components/webui/web_ui_provider.h"
 
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/common/channel_info.h"
 
 namespace web_ui {
 
 syncer::SyncService* GetSyncServiceForWebUI(web::WebUIIOS* web_ui) {
   ChromeBrowserState* browser_state = ChromeBrowserState::FromWebUIIOS(web_ui);
-  return ProfileSyncServiceFactory::GetForBrowserState(
+  return SyncServiceFactory::GetForBrowserState(
       browser_state->GetOriginalChromeBrowserState());
 }
 
diff --git a/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc b/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc
index 0e24b2f9..5e1d19c 100644
--- a/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc
+++ b/ios/chrome/browser/unified_consent/unified_consent_service_factory.cc
@@ -16,14 +16,14 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/pref_names.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 
 UnifiedConsentServiceFactory::UnifiedConsentServiceFactory()
     : BrowserStateKeyedServiceFactory(
           "UnifiedConsentService",
           BrowserStateDependencyManager::GetInstance()) {
   DependsOn(IdentityManagerFactory::GetInstance());
-  DependsOn(ProfileSyncServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 UnifiedConsentServiceFactory::~UnifiedConsentServiceFactory() = default;
@@ -61,7 +61,7 @@
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForBrowserState(browser_state);
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
 
   // Record settings for pre- and post-UnifiedConsent users.
   unified_consent::metrics::RecordSettingsHistogram(user_pref_service);
diff --git a/ios/chrome/test/app/sync_test_util.mm b/ios/chrome/test/app/sync_test_util.mm
index a04bedb0..8c5bc3fb 100644
--- a/ios/chrome/test/app/sync_test_util.mm
+++ b/ios/chrome/test/app/sync_test_util.mm
@@ -37,7 +37,7 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/history/history_service_factory.h"
 #include "ios/chrome/browser/sync/device_info_sync_service_factory.h"
-#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/test/app/chrome_test_util.h"
@@ -61,8 +61,7 @@
       chrome_test_util::GetOriginalBrowserState();
   DCHECK(browser_state);
   syncer::ProfileSyncService* service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
-          browser_state);
+      SyncServiceFactory::GetAsProfileSyncServiceForBrowserState(browser_state);
   service->OverrideNetworkForTest(create_http_post_provider_factory_cb);
 }
 
@@ -106,8 +105,7 @@
       SyncSetupServiceFactory::GetForBrowserState(browser_state);
   sync_setup_service->SetSyncEnabled(true);
   syncer::ProfileSyncService* sync_service =
-      ProfileSyncServiceFactory::GetAsProfileSyncServiceForBrowserState(
-          browser_state);
+      SyncServiceFactory::GetAsProfileSyncServiceForBrowserState(browser_state);
   sync_service->TriggerPoliciesLoadedForTest();
 }
 
@@ -124,7 +122,7 @@
   ChromeBrowserState* browser_state =
       chrome_test_util::GetOriginalBrowserState();
   syncer::SyncService* sync_service =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
   sync_service->TriggerRefresh({type});
 }
 
@@ -191,7 +189,7 @@
       chrome_test_util::GetOriginalBrowserState();
   DCHECK(browser_state);
   syncer::SyncService* syncService =
-      ProfileSyncServiceFactory::GetForBrowserState(browser_state);
+      SyncServiceFactory::GetForBrowserState(browser_state);
   return syncService->IsEngineInitialized();
 }
 
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index e0725b3..f25ebfc 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -197,12 +197,12 @@
     "internal/sync/web_view_model_type_store_service_factory.mm",
     "internal/sync/web_view_profile_invalidation_provider_factory.h",
     "internal/sync/web_view_profile_invalidation_provider_factory.mm",
-    "internal/sync/web_view_profile_sync_service_factory.h",
-    "internal/sync/web_view_profile_sync_service_factory.mm",
     "internal/sync/web_view_sync_client.h",
     "internal/sync/web_view_sync_client.mm",
     "internal/sync/web_view_sync_invalidations_service_factory.h",
     "internal/sync/web_view_sync_invalidations_service_factory.mm",
+    "internal/sync/web_view_sync_service_factory.h",
+    "internal/sync/web_view_sync_service_factory.mm",
     "internal/translate/cwv_translation_controller.mm",
     "internal/translate/cwv_translation_controller_internal.h",
     "internal/translate/cwv_translation_language.mm",
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller.mm b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
index 30bb8724..08bf6b7 100644
--- a/ios/web_view/internal/autofill/cwv_autofill_controller.mm
+++ b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
@@ -47,7 +47,6 @@
 #import "ios/web_view/internal/passwords/web_view_account_password_store_factory.h"
 #import "ios/web_view/internal/passwords/web_view_password_manager_driver.h"
 #include "ios/web_view/internal/signin/web_view_identity_manager_factory.h"
-#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
 #include "ios/web_view/internal/web_view_browser_state.h"
 #import "ios/web_view/public/cwv_autofill_controller_delegate.h"
 #import "net/base/mac/url_conversions.h"
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
index 594ada8..ce2c815 100644
--- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
+++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
@@ -24,7 +24,7 @@
 #include "ios/web_view/internal/autofill/web_view_personal_data_manager_factory.h"
 #include "ios/web_view/internal/autofill/web_view_strike_database_factory.h"
 #include "ios/web_view/internal/signin/web_view_identity_manager_factory.h"
-#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
+#import "ios/web_view/internal/sync/web_view_sync_service_factory.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 
@@ -50,7 +50,7 @@
           browser_state->GetRecordingBrowserState()),
       ios_web_view::WebViewStrikeDatabaseFactory::GetForBrowserState(
           browser_state->GetRecordingBrowserState()),
-      ios_web_view::WebViewProfileSyncServiceFactory::GetForBrowserState(
+      ios_web_view::WebViewSyncServiceFactory::GetForBrowserState(
           browser_state),
       // TODO(crbug.com/928595): Replace the closure with a callback to the
       // renderer that indicates if log messages should be sent from the
diff --git a/ios/web_view/internal/cwv_web_view_configuration.mm b/ios/web_view/internal/cwv_web_view_configuration.mm
index 9ef4306e..fd83782 100644
--- a/ios/web_view/internal/cwv_web_view_configuration.mm
+++ b/ios/web_view/internal/cwv_web_view_configuration.mm
@@ -19,7 +19,7 @@
 #import "ios/web_view/internal/passwords/web_view_account_password_store_factory.h"
 #include "ios/web_view/internal/signin/web_view_identity_manager_factory.h"
 #import "ios/web_view/internal/sync/cwv_sync_controller_internal.h"
-#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
+#import "ios/web_view/internal/sync/web_view_sync_service_factory.h"
 #include "ios/web_view/internal/web_view_browser_state.h"
 #include "ios/web_view/internal/web_view_global_state_util.h"
 
@@ -146,7 +146,7 @@
 - (CWVSyncController*)syncController {
   if (!_syncController && self.persistent) {
     syncer::SyncService* syncService =
-        ios_web_view::WebViewProfileSyncServiceFactory::GetForBrowserState(
+        ios_web_view::WebViewSyncServiceFactory::GetForBrowserState(
             self.browserState);
     signin::IdentityManager* identityManager =
         ios_web_view::WebViewIdentityManagerFactory::GetForBrowserState(
diff --git a/ios/web_view/internal/passwords/web_view_password_manager_client.mm b/ios/web_view/internal/passwords/web_view_password_manager_client.mm
index e4bc1fd..e1dc0fa 100644
--- a/ios/web_view/internal/passwords/web_view_password_manager_client.mm
+++ b/ios/web_view/internal/passwords/web_view_password_manager_client.mm
@@ -18,7 +18,7 @@
 #import "ios/web_view/internal/passwords/web_view_password_requirements_service_factory.h"
 #include "ios/web_view/internal/passwords/web_view_password_store_factory.h"
 #include "ios/web_view/internal/signin/web_view_identity_manager_factory.h"
-#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
+#import "ios/web_view/internal/sync/web_view_sync_service_factory.h"
 #include "net/cert/cert_status_flags.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
@@ -38,7 +38,7 @@
 WebViewPasswordManagerClient::Create(web::WebState* web_state,
                                      WebViewBrowserState* browser_state) {
   syncer::SyncService* sync_service =
-      ios_web_view::WebViewProfileSyncServiceFactory::GetForBrowserState(
+      ios_web_view::WebViewSyncServiceFactory::GetForBrowserState(
           browser_state);
   signin::IdentityManager* identity_manager =
       ios_web_view::WebViewIdentityManagerFactory::GetForBrowserState(
diff --git a/ios/web_view/internal/passwords/web_view_password_store_factory.mm b/ios/web_view/internal/passwords/web_view_password_store_factory.mm
index 38ddfdd..237b503 100644
--- a/ios/web_view/internal/passwords/web_view_password_store_factory.mm
+++ b/ios/web_view/internal/passwords/web_view_password_store_factory.mm
@@ -21,7 +21,6 @@
 #include "components/password_manager/core/browser/password_store_impl.h"
 #include "components/sync/driver/sync_service.h"
 #include "ios/web_view/internal/app/application_context.h"
-#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
 #include "ios/web_view/internal/web_view_browser_state.h"
 #include "ios/web_view/internal/webdata_services/web_view_web_data_service_wrapper_factory.h"
 
diff --git a/ios/web_view/internal/sync/web_view_profile_sync_service_factory.h b/ios/web_view/internal/sync/web_view_profile_sync_service_factory.h
deleted file mode 100644
index c25243c3..0000000
--- a/ios/web_view/internal/sync/web_view_profile_sync_service_factory.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_WEB_VIEW_INTERNAL_SYNC_WEB_VIEW_PROFILE_SYNC_SERVICE_FACTORY_H_
-#define IOS_WEB_VIEW_INTERNAL_SYNC_WEB_VIEW_PROFILE_SYNC_SERVICE_FACTORY_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/no_destructor.h"
-#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
-
-namespace syncer {
-class SyncService;
-}  // namespace syncer
-
-namespace ios_web_view {
-class WebViewBrowserState;
-
-// Singleton that owns all ProfileSyncService and associates them with
-// WebViewBrowserState.
-class WebViewProfileSyncServiceFactory
-    : public BrowserStateKeyedServiceFactory {
- public:
-  static syncer::SyncService* GetForBrowserState(
-      WebViewBrowserState* browser_state);
-
-  static WebViewProfileSyncServiceFactory* GetInstance();
-
- private:
-  friend class base::NoDestructor<WebViewProfileSyncServiceFactory>;
-
-  WebViewProfileSyncServiceFactory();
-  ~WebViewProfileSyncServiceFactory() override;
-
-  // BrowserStateKeyedServiceFactory implementation.
-  std::unique_ptr<KeyedService> BuildServiceInstanceFor(
-      web::BrowserState* context) const override;
-
-  DISALLOW_COPY_AND_ASSIGN(WebViewProfileSyncServiceFactory);
-};
-
-}  // namespace ios_web_view
-
-#endif  // IOS_WEB_VIEW_INTERNAL_SYNC_WEB_VIEW_PROFILE_SYNC_SERVICE_FACTORY_H_
diff --git a/ios/web_view/internal/sync/web_view_sync_service_factory.h b/ios/web_view/internal/sync/web_view_sync_service_factory.h
new file mode 100644
index 0000000..5594dbac
--- /dev/null
+++ b/ios/web_view/internal/sync/web_view_sync_service_factory.h
@@ -0,0 +1,45 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_VIEW_INTERNAL_SYNC_WEB_VIEW_SYNC_SERVICE_FACTORY_H_
+#define IOS_WEB_VIEW_INTERNAL_SYNC_WEB_VIEW_SYNC_SERVICE_FACTORY_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/no_destructor.h"
+#include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
+
+namespace syncer {
+class SyncService;
+}  // namespace syncer
+
+namespace ios_web_view {
+class WebViewBrowserState;
+
+// Singleton that owns all ProfileSyncService and associates them with
+// WebViewBrowserState.
+class WebViewSyncServiceFactory : public BrowserStateKeyedServiceFactory {
+ public:
+  static syncer::SyncService* GetForBrowserState(
+      WebViewBrowserState* browser_state);
+
+  static WebViewSyncServiceFactory* GetInstance();
+
+ private:
+  friend class base::NoDestructor<WebViewSyncServiceFactory>;
+
+  WebViewSyncServiceFactory();
+  ~WebViewSyncServiceFactory() override;
+
+  // BrowserStateKeyedServiceFactory implementation.
+  std::unique_ptr<KeyedService> BuildServiceInstanceFor(
+      web::BrowserState* context) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(WebViewSyncServiceFactory);
+};
+
+}  // namespace ios_web_view
+
+#endif  // IOS_WEB_VIEW_INTERNAL_SYNC_WEB_VIEW_SYNC_SERVICE_FACTORY_H_
diff --git a/ios/web_view/internal/sync/web_view_profile_sync_service_factory.mm b/ios/web_view/internal/sync/web_view_sync_service_factory.mm
similarity index 87%
rename from ios/web_view/internal/sync/web_view_profile_sync_service_factory.mm
rename to ios/web_view/internal/sync/web_view_sync_service_factory.mm
index 16a90e880..b0485f9 100644
--- a/ios/web_view/internal/sync/web_view_profile_sync_service_factory.mm
+++ b/ios/web_view/internal/sync/web_view_sync_service_factory.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
+#import "ios/web_view/internal/sync/web_view_sync_service_factory.h"
 
 #include <utility>
 
@@ -39,24 +39,23 @@
 namespace ios_web_view {
 
 // static
-WebViewProfileSyncServiceFactory*
-WebViewProfileSyncServiceFactory::GetInstance() {
-  static base::NoDestructor<WebViewProfileSyncServiceFactory> instance;
+WebViewSyncServiceFactory* WebViewSyncServiceFactory::GetInstance() {
+  static base::NoDestructor<WebViewSyncServiceFactory> instance;
   return instance.get();
 }
 
 // static
-syncer::SyncService* WebViewProfileSyncServiceFactory::GetForBrowserState(
+syncer::SyncService* WebViewSyncServiceFactory::GetForBrowserState(
     WebViewBrowserState* browser_state) {
   return static_cast<syncer::SyncService*>(
       GetInstance()->GetServiceForBrowserState(browser_state, true));
 }
 
-WebViewProfileSyncServiceFactory::WebViewProfileSyncServiceFactory()
+WebViewSyncServiceFactory::WebViewSyncServiceFactory()
     : BrowserStateKeyedServiceFactory(
-          "ProfileSyncService",
+          "SyncService",
           BrowserStateDependencyManager::GetInstance()) {
-  // The ProfileSyncService depends on various SyncableServices being around
+  // The SyncService depends on various SyncableServices being around
   // when it is shut down.  Specify those dependencies here to build the proper
   // destruction order.
   DependsOn(WebViewDeviceInfoSyncServiceFactory::GetInstance());
@@ -70,10 +69,10 @@
   DependsOn(WebViewSyncInvalidationsServiceFactory::GetInstance());
 }
 
-WebViewProfileSyncServiceFactory::~WebViewProfileSyncServiceFactory() {}
+WebViewSyncServiceFactory::~WebViewSyncServiceFactory() {}
 
 std::unique_ptr<KeyedService>
-WebViewProfileSyncServiceFactory::BuildServiceInstanceFor(
+WebViewSyncServiceFactory::BuildServiceInstanceFor(
     web::BrowserState* context) const {
   WebViewBrowserState* browser_state =
       WebViewBrowserState::FromBrowserState(context);
diff --git a/ios/web_view/internal/web_view_browser_state.mm b/ios/web_view/internal/web_view_browser_state.mm
index 76d6e1d..d3a0832 100644
--- a/ios/web_view/internal/web_view_browser_state.mm
+++ b/ios/web_view/internal/web_view_browser_state.mm
@@ -49,7 +49,7 @@
 #import "ios/web_view/internal/sync/web_view_gcm_profile_service_factory.h"
 #import "ios/web_view/internal/sync/web_view_model_type_store_service_factory.h"
 #import "ios/web_view/internal/sync/web_view_profile_invalidation_provider_factory.h"
-#import "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
+#import "ios/web_view/internal/sync/web_view_sync_service_factory.h"
 #include "ios/web_view/internal/translate/web_view_translate_accept_languages_factory.h"
 #include "ios/web_view/internal/translate/web_view_translate_ranker_factory.h"
 #include "ios/web_view/internal/web_view_download_manager.h"
@@ -199,7 +199,7 @@
   WebViewIdentityManagerFactory::GetInstance();
   WebViewGCMProfileServiceFactory::GetInstance();
   WebViewProfileInvalidationProviderFactory::GetInstance();
-  WebViewProfileSyncServiceFactory::GetInstance();
+  WebViewSyncServiceFactory::GetInstance();
   WebViewModelTypeStoreServiceFactory::GetInstance();
 
   BrowserStateDependencyManager::GetInstance()
diff --git a/ios/web_view/internal/webui/web_view_web_ui_provider.mm b/ios/web_view/internal/webui/web_view_web_ui_provider.mm
index 2b881b68..3104b636 100644
--- a/ios/web_view/internal/webui/web_view_web_ui_provider.mm
+++ b/ios/web_view/internal/webui/web_view_web_ui_provider.mm
@@ -5,7 +5,7 @@
 #import "ios/components/webui/web_ui_provider.h"
 
 #include "components/version_info/channel.h"
-#include "ios/web_view/internal/sync/web_view_profile_sync_service_factory.h"
+#include "ios/web_view/internal/sync/web_view_sync_service_factory.h"
 #include "ios/web_view/internal/web_view_browser_state.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -19,7 +19,7 @@
 syncer::SyncService* GetSyncServiceForWebUI(web::WebUIIOS* web_ui) {
   ios_web_view::WebViewBrowserState* browser_state =
       ios_web_view::WebViewBrowserState::FromWebUIIOS(web_ui);
-  return ios_web_view::WebViewProfileSyncServiceFactory::GetForBrowserState(
+  return ios_web_view::WebViewSyncServiceFactory::GetForBrowserState(
       browser_state->GetRecordingBrowserState());
 }
 
diff --git a/media/base/cdm_context.h b/media/base/cdm_context.h
index f426dd3..366e41d 100644
--- a/media/base/cdm_context.h
+++ b/media/base/cdm_context.h
@@ -56,7 +56,7 @@
 
     // A hardware reset happened. Some hardware context, e.g. hardware decoder
     // context may be lost.
-    kHardwareContextLost,
+    kHardwareContextReset,
   };
 
   // Callback to notify the occurrence of an Event.
diff --git a/media/base/cdm_promise.h b/media/base/cdm_promise.h
index 5b3d05f..4fc35221a 100644
--- a/media/base/cdm_promise.h
+++ b/media/base/cdm_promise.h
@@ -169,6 +169,25 @@
 MEDIA_EXPORT CdmPromise::ResolveParameterType CdmPromiseTemplate<
     CdmKeyInformation::KeyStatus>::GetResolveParameterType() const;
 
+// A dummy CdmPromise that does nothing. Used for APIs requiring a CdmPromise
+// while the result will be ignored.
+template <typename... T>
+class MEDIA_EXPORT DoNothingCdmPromise : public CdmPromiseTemplate<T...> {
+ public:
+  DoNothingCdmPromise() = default;
+  DoNothingCdmPromise(const DoNothingCdmPromise&) = delete;
+  DoNothingCdmPromise& operator=(const DoNothingCdmPromise&) = delete;
+  ~DoNothingCdmPromise() override = default;
+
+  // CdmPromiseTemplate.
+  void resolve() final { CdmPromiseTemplate<T...>::MarkPromiseSettled(); }
+  void reject(CdmPromise::Exception exception_code,
+              uint32_t system_code,
+              const std::string& error_message) final {
+    CdmPromiseTemplate<T...>::MarkPromiseSettled();
+  }
+};
+
 }  // namespace media
 
 #endif  // MEDIA_BASE_CDM_PROMISE_H_
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index f29e529..eec6487 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -1331,7 +1331,7 @@
 }
 
 bool PipelineImpl::IsSuspended() const {
-  DVLOG(2) << __func__;
+  DVLOG(2) << __func__ << "(" << is_suspended_ << ")";
   DCHECK(thread_checker_.CalledOnValidThread());
   return is_suspended_;
 }
diff --git a/media/base/pipeline_status.cc b/media/base/pipeline_status.cc
index 32c24f1..ed7ff23 100644
--- a/media/base/pipeline_status.cc
+++ b/media/base/pipeline_status.cc
@@ -46,6 +46,8 @@
       return PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED;
     case StatusCode::kPipelineErrorDemuxerErrorDetectedHLS:
       return DEMUXER_ERROR_DETECTED_HLS;
+    case StatusCode::kPipelineErrorHardwareContextReset:
+      return PIPELINE_ERROR_HARDWARE_CONTEXT_RESET;
     default:
       NOTREACHED();
       return absl::nullopt;
@@ -90,6 +92,8 @@
       return StatusCode::kPipelineErrorExternalRendererFailed;
     case DEMUXER_ERROR_DETECTED_HLS:
       return StatusCode::kPipelineErrorDemuxerErrorDetectedHLS;
+    case PIPELINE_ERROR_HARDWARE_CONTEXT_RESET:
+      return StatusCode::kPipelineErrorHardwareContextReset;
   }
 
   NOTREACHED();
@@ -113,6 +117,7 @@
     STRINGIFY_STATUS_CASE(PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED);
     STRINGIFY_STATUS_CASE(PIPELINE_ERROR_READ);
     STRINGIFY_STATUS_CASE(PIPELINE_ERROR_INVALID_STATE);
+    STRINGIFY_STATUS_CASE(PIPELINE_ERROR_HARDWARE_CONTEXT_RESET);
     STRINGIFY_STATUS_CASE(DEMUXER_ERROR_COULD_NOT_OPEN);
     STRINGIFY_STATUS_CASE(DEMUXER_ERROR_COULD_NOT_PARSE);
     STRINGIFY_STATUS_CASE(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
diff --git a/media/base/pipeline_status.h b/media/base/pipeline_status.h
index cab7506..195bd8c 100644
--- a/media/base/pipeline_status.h
+++ b/media/base/pipeline_status.h
@@ -58,8 +58,13 @@
   // not exactly an 'error' per say.
   DEMUXER_ERROR_DETECTED_HLS = 22,
 
+  // Used when hardware context is reset (e.g. OS sleep/resume), where we should
+  // recreate the Renderer instead of failing the playback. See
+  // https://crbug.com/1208618
+  PIPELINE_ERROR_HARDWARE_CONTEXT_RESET = 23,
+
   // Must be equal to the largest value ever logged.
-  PIPELINE_STATUS_MAX = DEMUXER_ERROR_DETECTED_HLS,
+  PIPELINE_STATUS_MAX = PIPELINE_ERROR_HARDWARE_CONTEXT_RESET,
 };
 
 MEDIA_EXPORT absl::optional<PipelineStatus> StatusCodeToPipelineStatus(
diff --git a/media/base/status_codes.h b/media/base/status_codes.h
index 70078b0..6485b1d 100644
--- a/media/base/status_codes.h
+++ b/media/base/status_codes.h
@@ -173,6 +173,10 @@
   // Android only. Used as a signal to fallback MediaPlayerRenderer, and thus
   // not exactly an 'error' per say.
   kPipelineErrorDemuxerErrorDetectedHLS = 0x00000916,
+  // Used when hardware context is reset (e.g. OS sleep/resume), where we should
+  // recreate the Renderer instead of fail the playback. See
+  // https://crbug.com/1208618
+  kPipelineErrorHardwareContextReset = 0x00000917,
 
   // Frame operation errors: 0x0A
   kUnsupportedFrameFormatError = 0x00000A01,
diff --git a/media/base/win/media_foundation_cdm_proxy.h b/media/base/win/media_foundation_cdm_proxy.h
index e7e7c51d..8ba852a 100644
--- a/media/base/win/media_foundation_cdm_proxy.h
+++ b/media/base/win/media_foundation_cdm_proxy.h
@@ -55,6 +55,11 @@
   virtual HRESULT ProcessContentEnabler(IUnknown* request,
                                         IMFAsyncResult* result) = 0;
 
+  // Notify the CDM on DRM_E_TEE_INVALID_HWDRM_STATE (0x8004cd12), which happens
+  // in cases like OS Sleep. In this case, the CDM should close all sessions
+  // because they are in bad state.
+  virtual void OnHardwareContextReset() = 0;
+
  protected:
   friend base::RefCountedThreadSafe<MediaFoundationCdmProxy>;
   virtual ~MediaFoundationCdmProxy() = default;
diff --git a/media/blink/webcontentdecryptionmodulesession_impl.cc b/media/blink/webcontentdecryptionmodulesession_impl.cc
index 0be92465..e3f8e80 100644
--- a/media/blink/webcontentdecryptionmodulesession_impl.cc
+++ b/media/blink/webcontentdecryptionmodulesession_impl.cc
@@ -204,23 +204,6 @@
   return true;
 }
 
-// If we need to close the session while destroying this object, we need a
-// dummy promise that won't call back into this object (or try to pass
-// something back to blink).
-class IgnoreResponsePromise : public SimpleCdmPromise {
- public:
-  IgnoreResponsePromise() = default;
-  ~IgnoreResponsePromise() override = default;
-
-  // SimpleCdmPromise implementation.
-  void resolve() final { MarkPromiseSettled(); }
-  void reject(CdmPromise::Exception exception_code,
-              uint32_t system_code,
-              const std::string& error_message) final {
-    MarkPromiseSettled();
-  }
-};
-
 }  // namespace
 
 WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl(
@@ -251,7 +234,7 @@
     // session will be gone.
     if (!is_closed_ && !has_close_been_called_) {
       adapter_->CloseSession(session_id_,
-                             std::make_unique<IgnoreResponsePromise>());
+                             std::make_unique<DoNothingCdmPromise<>>());
     }
   }
 }
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 09f81a8..11888c6a 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -1837,7 +1837,15 @@
   // We found hls in a data:// URL, fail immediately.
   if (found_hls)
     status = PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED;
-#endif
+#elif defined(OS_WIN)
+  // Hardware context reset is not an error. Restart to recover.
+  // TODO(crbug.com/1208618): Find a way to break the potential infinite loop of
+  // restart -> PIPELINE_ERROR_HARDWARE_CONTEXT_RESET -> restart.
+  if (status == PipelineStatus::PIPELINE_ERROR_HARDWARE_CONTEXT_RESET) {
+    ScheduleRestart();
+    return;
+  }
+#endif  // defined(OS_ANDROID)
 
   MaybeSetContainerNameForMetrics();
   simple_watch_timer_.Stop();
diff --git a/media/cdm/win/media_foundation_cdm.cc b/media/cdm/win/media_foundation_cdm.cc
index b1f2ae2d..629aa4bb 100644
--- a/media/cdm/win/media_foundation_cdm.cc
+++ b/media/cdm/win/media_foundation_cdm.cc
@@ -17,6 +17,7 @@
 #include "media/base/cdm_promise.h"
 #include "media/base/win/media_foundation_cdm_proxy.h"
 #include "media/base/win/mf_helpers.h"
+#include "media/cdm/win/media_foundation_cdm_module.h"
 #include "media/cdm/win/media_foundation_cdm_session.h"
 
 namespace media {
@@ -98,8 +99,10 @@
 
 class CdmProxyImpl : public MediaFoundationCdmProxy {
  public:
-  explicit CdmProxyImpl(ComPtr<IMFContentDecryptionModule> mf_cdm)
-      : mf_cdm_(mf_cdm) {}
+  CdmProxyImpl(ComPtr<IMFContentDecryptionModule> mf_cdm,
+               base::RepeatingClosure hardware_context_reset_cb)
+      : mf_cdm_(mf_cdm),
+        hardware_context_reset_cb_(std::move(hardware_context_reset_cb)) {}
 
   // MediaFoundationCdmProxy implementation
 
@@ -186,6 +189,19 @@
     return mf_cdm_->SetContentEnabler(content_enabler.Get(), result);
   }
 
+  void OnHardwareContextReset() override {
+    // Hardware context reset happens, all the crypto sessions are in invalid
+    // states. So drop everything here.
+    // TODO(xhwang): Keep the `last_key_ids_` here for faster resume.
+    trusted_input_.Reset();
+    input_trust_authorities_.clear();
+    last_key_ids_.clear();
+
+    // Must be the last call because `this` could be destructed when running
+    // the callback. We are not certain because `this` is ref-counted.
+    hardware_context_reset_cb_.Run();
+  }
+
  private:
   ~CdmProxyImpl() override = default;
 
@@ -208,6 +224,9 @@
 
   ComPtr<IMFContentDecryptionModule> mf_cdm_;
 
+  // A callback to notify hardware context reset.
+  base::RepeatingClosure hardware_context_reset_cb_;
+
   // Store IMFTrustedInput to avoid potential performance cost.
   ComPtr<IMFTrustedInput> trusted_input_;
 
@@ -229,18 +248,18 @@
 }
 
 MediaFoundationCdm::MediaFoundationCdm(
-    Microsoft::WRL::ComPtr<IMFContentDecryptionModule> mf_cdm,
+    const CreateMFCdmCB& create_mf_cdm_cb,
     const SessionMessageCB& session_message_cb,
     const SessionClosedCB& session_closed_cb,
     const SessionKeysChangeCB& session_keys_change_cb,
     const SessionExpirationUpdateCB& session_expiration_update_cb)
-    : mf_cdm_(std::move(mf_cdm)),
+    : create_mf_cdm_cb_(create_mf_cdm_cb),
       session_message_cb_(session_message_cb),
       session_closed_cb_(session_closed_cb),
       session_keys_change_cb_(session_keys_change_cb),
       session_expiration_update_cb_(session_expiration_update_cb) {
   DVLOG_FUNC(1);
-  DCHECK(mf_cdm_);
+  DCHECK(create_mf_cdm_cb_);
   DCHECK(session_message_cb_);
   DCHECK(session_closed_cb_);
   DCHECK(session_keys_change_cb_);
@@ -251,11 +270,29 @@
   DVLOG_FUNC(1);
 }
 
+HRESULT MediaFoundationCdm::Initialize() {
+  HRESULT hresult = E_FAIL;
+  ComPtr<IMFContentDecryptionModule> mf_cdm;
+  create_mf_cdm_cb_.Run(hresult, mf_cdm);
+  if (!mf_cdm) {
+    DCHECK(FAILED(hresult));
+    return hresult;
+  }
+
+  mf_cdm_.Swap(mf_cdm);
+  return S_OK;
+}
+
 void MediaFoundationCdm::SetServerCertificate(
     const std::vector<uint8_t>& certificate,
     std::unique_ptr<SimpleCdmPromise> promise) {
   DVLOG_FUNC(1);
 
+  if (!mf_cdm_) {
+    promise->reject(Exception::INVALID_STATE_ERROR, 0, "CDM Unavailable");
+    return;
+  }
+
   if (FAILED(mf_cdm_->SetServerCertificate(certificate.data(),
                                            certificate.size()))) {
     promise->reject(Exception::NOT_SUPPORTED_ERROR, 0, "Failed to set cert");
@@ -265,10 +302,15 @@
   promise->resolve();
 }
 
-// TODO(xhwang): Implement this.
+// TODO(hmchen): Implement this method.
 void MediaFoundationCdm::GetStatusForPolicy(
     HdcpVersion min_hdcp_version,
     std::unique_ptr<KeyStatusCdmPromise> promise) {
+  if (!mf_cdm_) {
+    promise->reject(Exception::INVALID_STATE_ERROR, 0, "CDM Unavailable");
+    return;
+  }
+
   NOTIMPLEMENTED();
   promise->reject(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0,
                   "GetStatusForPolicy() is not supported.");
@@ -281,6 +323,11 @@
     std::unique_ptr<NewSessionCdmPromise> promise) {
   DVLOG_FUNC(1);
 
+  if (!mf_cdm_) {
+    promise->reject(Exception::INVALID_STATE_ERROR, 0, "CDM Unavailable");
+    return;
+  }
+
   // TODO(xhwang): Implement session expiration update.
   auto session = std::make_unique<MediaFoundationCdmSession>(
       session_message_cb_, session_keys_change_cb_,
@@ -315,6 +362,12 @@
     const std::string& session_id,
     std::unique_ptr<NewSessionCdmPromise> promise) {
   DVLOG_FUNC(1);
+
+  if (!mf_cdm_) {
+    promise->reject(Exception::INVALID_STATE_ERROR, 0, "CDM Unavailable");
+    return;
+  }
+
   NOTIMPLEMENTED();
   promise->reject(Exception::NOT_SUPPORTED_ERROR, 0, "Load not supported");
 }
@@ -325,6 +378,11 @@
     std::unique_ptr<SimpleCdmPromise> promise) {
   DVLOG_FUNC(1);
 
+  if (!mf_cdm_) {
+    promise->reject(Exception::INVALID_STATE_ERROR, 0, "CDM Unavailable");
+    return;
+  }
+
   auto* session = GetSession(session_id);
   if (!session) {
     promise->reject(Exception::INVALID_STATE_ERROR, 0, "Session not found");
@@ -344,6 +402,11 @@
     std::unique_ptr<SimpleCdmPromise> promise) {
   DVLOG_FUNC(1);
 
+  if (!mf_cdm_) {
+    promise->reject(Exception::INVALID_STATE_ERROR, 0, "CDM Unavailable");
+    return;
+  }
+
   // Validate that this is a reference to an open session. close() shouldn't
   // be called if the session is already closed. However, the operation is
   // asynchronous, so there is a window where close() was called a second time
@@ -376,6 +439,11 @@
     std::unique_ptr<SimpleCdmPromise> promise) {
   DVLOG_FUNC(1);
 
+  if (!mf_cdm_) {
+    promise->reject(Exception::INVALID_STATE_ERROR, 0, "CDM Unavailable");
+    return;
+  }
+
   auto* session = GetSession(session_id);
   if (!session) {
     promise->reject(Exception::INVALID_STATE_ERROR, 0, "Session not found");
@@ -402,8 +470,17 @@
     GetMediaFoundationCdmProxyCB get_mf_cdm_proxy_cb) {
   DVLOG_FUNC(1);
 
-  if (!cdm_proxy_)
-    cdm_proxy_ = base::MakeRefCounted<CdmProxyImpl>(mf_cdm_);
+  if (!mf_cdm_) {
+    DLOG(ERROR) << __func__ << ": Invalid state with null `mf_cdm_`";
+    return false;
+  }
+
+  if (!cdm_proxy_) {
+    cdm_proxy_ = base::MakeRefCounted<CdmProxyImpl>(
+        mf_cdm_,
+        base::BindRepeating(&MediaFoundationCdm::OnHardwareContextReset,
+                            weak_factory_.GetWeakPtr()));
+  }
 
   BindToCurrentLoop(std::move(get_mf_cdm_proxy_cb)).Run(cdm_proxy_);
   return true;
@@ -442,4 +519,30 @@
   return itr->second.get();
 }
 
+// When hardware context is reset, all sessions are in a bad state. Close all
+// the sessions and hopefully the player will create new sessions to resume.
+void MediaFoundationCdm::OnHardwareContextReset() {
+  DVLOG_FUNC(1);
+
+  // Collect all the session IDs to avoid iterating the map while we delete
+  // entries in the map (in `CloseSession()`).
+  std::vector<std::string> session_ids;
+  for (const auto& s : sessions_)
+    session_ids.push_back(s.first);
+
+  for (const auto& session_id : session_ids)
+    CloseSession(session_id, std::make_unique<DoNothingCdmPromise<>>());
+
+  cdm_proxy_.reset();
+
+  // Reset IMFContentDecryptionModule which also holds the old ITA.
+  mf_cdm_.Reset();
+
+  // Recreates IMFContentDecryptionModule so we can create new sessions.
+  if (FAILED(Initialize())) {
+    DLOG(ERROR) << __func__ << ": Re-initialization failed";
+    DCHECK(!mf_cdm_);
+  }
+}
+
 }  // namespace media
diff --git a/media/cdm/win/media_foundation_cdm.h b/media/cdm/win/media_foundation_cdm.h
index b5e80df..b49d287 100644
--- a/media/cdm/win/media_foundation_cdm.h
+++ b/media/cdm/win/media_foundation_cdm.h
@@ -13,6 +13,7 @@
 #include <string>
 
 #include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
 #include "media/base/cdm_context.h"
 #include "media/base/content_decryption_module.h"
 #include "media/base/media_export.h"
@@ -30,8 +31,15 @@
   // checks need to be made to determine the usability and the capabilities.
   static bool IsAvailable();
 
+  // Callback to create an IMFContentDecryptionModule. If failed,
+  // IMFContentDecryptionModule must be null.
+  using CreateMFCdmCB = base::RepeatingCallback<
+      void(HRESULT&, Microsoft::WRL::ComPtr<IMFContentDecryptionModule>&)>;
+
+  // Constructs `MediaFoundationCdm`. Note that `Initialize()` must be called
+  // before calling any other methods.
   MediaFoundationCdm(
-      Microsoft::WRL::ComPtr<IMFContentDecryptionModule> mf_cdm,
+      const CreateMFCdmCB& create_mf_cdm_cb,
       const SessionMessageCB& session_message_cb,
       const SessionClosedCB& session_closed_cb,
       const SessionKeysChangeCB& session_keys_change_cb,
@@ -39,6 +47,10 @@
   MediaFoundationCdm(const MediaFoundationCdm&) = delete;
   MediaFoundationCdm& operator=(const MediaFoundationCdm&) = delete;
 
+  // Initializes `this` and returns whether the initialization succeeds. Must
+  // be called before any other methods.
+  HRESULT Initialize();
+
   // ContentDecryptionModule implementation.
   void SetServerCertificate(const std::vector<uint8_t>& certificate,
                             std::unique_ptr<SimpleCdmPromise> promise) final;
@@ -76,7 +88,11 @@
 
   MediaFoundationCdmSession* GetSession(const std::string& session_id);
 
-  Microsoft::WRL::ComPtr<IMFContentDecryptionModule> mf_cdm_;
+  // Closes all outstanding sessions.
+  void OnHardwareContextReset();
+
+  // Callback to create `mf_cdm_`.
+  CreateMFCdmCB create_mf_cdm_cb_;
 
   // Callbacks for firing session events.
   SessionMessageCB session_message_cb_;
@@ -84,6 +100,8 @@
   SessionKeysChangeCB session_keys_change_cb_;
   SessionExpirationUpdateCB session_expiration_update_cb_;
 
+  Microsoft::WRL::ComPtr<IMFContentDecryptionModule> mf_cdm_;
+
   // Used to generate unique tokens for identifying pending sessions before
   // session ID is available.
   int next_session_token_ = 0;
@@ -95,6 +113,9 @@
   std::map<std::string, std::unique_ptr<MediaFoundationCdmSession>> sessions_;
 
   scoped_refptr<MediaFoundationCdmProxy> cdm_proxy_;
+
+  // This must be the last member.
+  base::WeakPtrFactory<MediaFoundationCdm> weak_factory_{this};
 };
 
 }  // namespace media
diff --git a/media/cdm/win/media_foundation_cdm_factory.cc b/media/cdm/win/media_foundation_cdm_factory.cc
index 57d5b68..4e4929f 100644
--- a/media/cdm/win/media_foundation_cdm_factory.cc
+++ b/media/cdm/win/media_foundation_cdm_factory.cc
@@ -203,17 +203,22 @@
     return;
   }
 
-  ComPtr<IMFContentDecryptionModule> mf_cdm;
-  if (FAILED(
-          CreateCdmInternal(key_system, cdm_config, cdm_origin_id, mf_cdm))) {
-    std::move(cdm_created_cb).Run(nullptr, "Failed to create CDM");
+  auto cdm = base::MakeRefCounted<MediaFoundationCdm>(
+      base::BindRepeating(&MediaFoundationCdmFactory::CreateMfCdm,
+                          weak_factory_.GetWeakPtr(), key_system, cdm_config,
+                          cdm_origin_id),
+      session_message_cb, session_closed_cb, session_keys_change_cb,
+      session_expiration_update_cb);
+
+  // `cdm_created_cb` should always be run asynchronously.
+  auto bound_cdm_created_cb = BindToCurrentLoop(std::move(cdm_created_cb));
+
+  if (FAILED(cdm->Initialize())) {
+    std::move(bound_cdm_created_cb).Run(nullptr, "Failed to create CDM");
     return;
   }
 
-  auto cdm = base::MakeRefCounted<MediaFoundationCdm>(
-      std::move(mf_cdm), session_message_cb, session_closed_cb,
-      session_keys_change_cb, session_expiration_update_cb);
-  std::move(cdm_created_cb).Run(cdm, "");
+  std::move(bound_cdm_created_cb).Run(cdm, "");
 }
 
 HRESULT MediaFoundationCdmFactory::GetCdmFactory(
@@ -236,7 +241,7 @@
   return S_OK;
 }
 
-HRESULT MediaFoundationCdmFactory::CreateCdmInternal(
+HRESULT MediaFoundationCdmFactory::CreateMfCdmInternal(
     const std::string& key_system,
     const CdmConfig& cdm_config,
     const base::UnguessableToken& cdm_origin_id,
@@ -283,4 +288,13 @@
   return S_OK;
 }
 
+void MediaFoundationCdmFactory::CreateMfCdm(
+    const std::string& key_system,
+    const CdmConfig& cdm_config,
+    const base::UnguessableToken& cdm_origin_id,
+    HRESULT& hresult,
+    Microsoft::WRL::ComPtr<IMFContentDecryptionModule>& mf_cdm) {
+  hresult = CreateMfCdmInternal(key_system, cdm_config, cdm_origin_id, mf_cdm);
+}
+
 }  // namespace media
diff --git a/media/cdm/win/media_foundation_cdm_factory.h b/media/cdm/win/media_foundation_cdm_factory.h
index b40a98c..2ed40c40 100644
--- a/media/cdm/win/media_foundation_cdm_factory.h
+++ b/media/cdm/win/media_foundation_cdm_factory.h
@@ -50,14 +50,6 @@
               CdmCreatedCB cdm_created_cb) final;
 
  private:
-  HRESULT GetCdmFactory(
-      const std::string& key_system,
-      Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& cdm_factory);
-  HRESULT CreateCdmInternal(
-      const std::string& key_system,
-      const CdmConfig& cdm_config,
-      const base::UnguessableToken& cdm_origin_id,
-      Microsoft::WRL::ComPtr<IMFContentDecryptionModule>& mf_cdm);
   void OnCdmOriginIdObtained(
       const std::string& key_system,
       const CdmConfig& cdm_config,
@@ -68,6 +60,24 @@
       CdmCreatedCB cdm_created_cb,
       const base::UnguessableToken& cdm_origin_id);
 
+  HRESULT GetCdmFactory(
+      const std::string& key_system,
+      Microsoft::WRL::ComPtr<IMFContentDecryptionModuleFactory>& cdm_factory);
+
+  HRESULT CreateMfCdmInternal(
+      const std::string& key_system,
+      const CdmConfig& cdm_config,
+      const base::UnguessableToken& cdm_origin_id,
+      Microsoft::WRL::ComPtr<IMFContentDecryptionModule>& mf_cdm);
+
+  // Same as `CreateMfCdmInternal()`, but returns the HRESULT in out parameter
+  // so we can bind it to a repeating callback using weak pointer.
+  void CreateMfCdm(const std::string& key_system,
+                   const CdmConfig& cdm_config,
+                   const base::UnguessableToken& cdm_origin_id,
+                   HRESULT& hresult,
+                   Microsoft::WRL::ComPtr<IMFContentDecryptionModule>& mf_cdm);
+
   std::unique_ptr<CdmAuxiliaryHelper> helper_;
   base::FilePath user_data_dir_;
 
diff --git a/media/cdm/win/media_foundation_cdm_unittest.cc b/media/cdm/win/media_foundation_cdm_unittest.cc
index 4b564f7..0c57dae 100644
--- a/media/cdm/win/media_foundation_cdm_unittest.cc
+++ b/media/cdm/win/media_foundation_cdm_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/test/task_environment.h"
 #include "media/base/mock_filters.h"
 #include "media/base/test_helpers.h"
+#include "media/base/win/media_foundation_cdm_proxy.h"
 #include "media/base/win/mf_helpers.h"
 #include "media/base/win/mf_mocks.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -50,7 +51,8 @@
       : mf_cdm_(MakeComPtr<MockMFCdm>()),
         mf_cdm_session_(MakeComPtr<MockMFCdmSession>()),
         cdm_(base::MakeRefCounted<MediaFoundationCdm>(
-            mf_cdm_,
+            base::BindRepeating(&MediaFoundationCdmTest::CreateMFCdm,
+                                base::Unretained(this)),
             base::BindRepeating(&MockCdmClient::OnSessionMessage,
                                 base::Unretained(&cdm_client_)),
             base::BindRepeating(&MockCdmClient::OnSessionClosed,
@@ -62,6 +64,24 @@
 
   ~MediaFoundationCdmTest() override = default;
 
+  void CreateMFCdm(HRESULT& hresult,
+                   Microsoft::WRL::ComPtr<IMFContentDecryptionModule>& mf_cdm) {
+    if (can_initialize_) {
+      hresult = S_OK;
+      mf_cdm = mf_cdm_;
+    } else {
+      hresult = E_FAIL;
+      mf_cdm.Reset();
+    }
+  }
+
+  void Initialize() { ASSERT_SUCCESS(cdm_->Initialize()); }
+
+  void InitializeAndExpectFailure() {
+    can_initialize_ = false;
+    ASSERT_FAILED(cdm_->Initialize());
+  }
+
   void SetGenerateRequestExpectations(
       ComPtr<MockMFCdmSession> mf_cdm_session,
       const char* session_id,
@@ -115,6 +135,10 @@
     EXPECT_EQ(session_id_, kSessionId);
   }
 
+  void OnCdmProxyReceived(scoped_refptr<MediaFoundationCdmProxy> mf_cdm_proxy) {
+    mf_cdm_proxy_ = std::move(mf_cdm_proxy);
+  }
+
  protected:
   base::test::TaskEnvironment task_environment_;
 
@@ -122,11 +146,15 @@
   ComPtr<MockMFCdm> mf_cdm_;
   ComPtr<MockMFCdmSession> mf_cdm_session_;
   ComPtr<IMFContentDecryptionModuleSessionCallbacks> mf_cdm_session_callbacks_;
-  scoped_refptr<ContentDecryptionModule> cdm_;
+  scoped_refptr<MediaFoundationCdm> cdm_;
+  bool can_initialize_ = true;
   std::string session_id_;
+  scoped_refptr<MediaFoundationCdmProxy> mf_cdm_proxy_;
 };
 
 TEST_F(MediaFoundationCdmTest, SetServerCertificate) {
+  Initialize();
+
   std::vector<uint8_t> certificate = StringToVector("certificate");
   COM_EXPECT_CALL(mf_cdm_,
                   SetServerCertificate(certificate.data(), certificate.size()))
@@ -137,6 +165,8 @@
 }
 
 TEST_F(MediaFoundationCdmTest, SetServerCertificate_Failure) {
+  Initialize();
+
   std::vector<uint8_t> certificate = StringToVector("certificate");
   COM_EXPECT_CALL(mf_cdm_,
                   SetServerCertificate(certificate.data(), certificate.size()))
@@ -147,11 +177,14 @@
 }
 
 TEST_F(MediaFoundationCdmTest, CreateSessionAndGenerateRequest) {
+  Initialize();
   CreateSessionAndGenerateRequest();
 }
 
 // Tests the case where two sessions are being created in parallel.
 TEST_F(MediaFoundationCdmTest, CreateSessionAndGenerateRequest_Parallel) {
+  Initialize();
+
   std::vector<uint8_t> init_data = StringToVector("init_data");
   const char kSessionId1[] = "session_id_1";
   const char kSessionId2[] = "session_id_2";
@@ -189,13 +222,28 @@
   EXPECT_EQ(session_id_2, kSessionId2);
 }
 
+TEST_F(MediaFoundationCdmTest, InitializeFailure) {
+  InitializeAndExpectFailure();
+
+  std::vector<uint8_t> init_data = StringToVector("init_data");
+  cdm_->CreateSessionAndGenerateRequest(
+      CdmSessionType::kTemporary, EmeInitDataType::WEBM, init_data,
+      std::make_unique<MockCdmSessionPromise>(/*expect_success=*/false,
+                                              &session_id_));
+
+  task_environment_.RunUntilIdle();
+  EXPECT_TRUE(session_id_.empty());
+}
+
 TEST_F(MediaFoundationCdmTest,
        CreateSessionAndGenerateRequest_CreateSessionFailure) {
-  std::vector<uint8_t> init_data = StringToVector("init_data");
+  Initialize();
+
   COM_EXPECT_CALL(mf_cdm_,
                   CreateSession(MF_MEDIAKEYSESSION_TYPE_TEMPORARY, _, _))
       .WillOnce(Return(E_FAIL));
 
+  std::vector<uint8_t> init_data = StringToVector("init_data");
   cdm_->CreateSessionAndGenerateRequest(
       CdmSessionType::kTemporary, EmeInitDataType::WEBM, init_data,
       std::make_unique<MockCdmSessionPromise>(/*expect_success=*/false,
@@ -207,13 +255,14 @@
 
 TEST_F(MediaFoundationCdmTest,
        CreateSessionAndGenerateRequest_GenerateRequestFailure) {
-  std::vector<uint8_t> init_data = StringToVector("init_data");
+  Initialize();
 
   COM_EXPECT_CALL(mf_cdm_,
                   CreateSession(MF_MEDIAKEYSESSION_TYPE_TEMPORARY, _, _))
       .WillOnce(DoAll(SaveComPtr<1>(&mf_cdm_session_callbacks_),
                       SetComPointee<2>(mf_cdm_session_.Get()), Return(S_OK)));
 
+  std::vector<uint8_t> init_data = StringToVector("init_data");
   COM_EXPECT_CALL(mf_cdm_session_,
                   GenerateRequest(StrEq(L"webm"), NotNull(), init_data.size()))
       .WillOnce(Return(E_FAIL));
@@ -230,7 +279,7 @@
 // Duplicate session IDs cause session creation failure.
 TEST_F(MediaFoundationCdmTest,
        CreateSessionAndGenerateRequest_DuplicateSessionId) {
-  std::vector<uint8_t> init_data = StringToVector("init_data");
+  Initialize();
 
   auto mf_cdm_session_1 = MakeComPtr<MockMFCdmSession>();
   auto mf_cdm_session_2 = MakeComPtr<MockMFCdmSession>();
@@ -253,6 +302,7 @@
                                  /*expect_message=*/false);
   std::string session_id_1;
   std::string session_id_2;
+  std::vector<uint8_t> init_data = StringToVector("init_data");
   cdm_->CreateSessionAndGenerateRequest(
       CdmSessionType::kTemporary, EmeInitDataType::WEBM, init_data,
       std::make_unique<MockCdmSessionPromise>(/*expect_success=*/true,
@@ -269,6 +319,8 @@
 
 // LoadSession() is not implemented.
 TEST_F(MediaFoundationCdmTest, LoadSession) {
+  Initialize();
+
   cdm_->LoadSession(CdmSessionType::kPersistentLicense, kSessionId,
                     std::make_unique<MockCdmSessionPromise>(
                         /*expect_success=*/false, &session_id_));
@@ -278,6 +330,7 @@
 }
 
 TEST_F(MediaFoundationCdmTest, UpdateSession) {
+  Initialize();
   CreateSessionAndGenerateRequest();
 
   std::vector<uint8_t> response = StringToVector("response");
@@ -297,6 +350,7 @@
 }
 
 TEST_F(MediaFoundationCdmTest, UpdateSession_InvalidSessionId) {
+  Initialize();
   CreateSessionAndGenerateRequest();
 
   std::vector<uint8_t> response = StringToVector("response");
@@ -307,6 +361,7 @@
 }
 
 TEST_F(MediaFoundationCdmTest, UpdateSession_Failure) {
+  Initialize();
   CreateSessionAndGenerateRequest();
 
   std::vector<uint8_t> response = StringToVector("response");
@@ -320,6 +375,7 @@
 }
 
 TEST_F(MediaFoundationCdmTest, CloseSession) {
+  Initialize();
   CreateSessionAndGenerateRequest();
 
   COM_EXPECT_CALL(mf_cdm_session_, Close()).WillOnce(Return(S_OK));
@@ -331,6 +387,7 @@
 }
 
 TEST_F(MediaFoundationCdmTest, CloseSession_Failure) {
+  Initialize();
   CreateSessionAndGenerateRequest();
 
   COM_EXPECT_CALL(mf_cdm_session_, Close()).WillOnce(Return(E_FAIL));
@@ -341,6 +398,7 @@
 }
 
 TEST_F(MediaFoundationCdmTest, RemoveSession) {
+  Initialize();
   CreateSessionAndGenerateRequest();
 
   COM_EXPECT_CALL(mf_cdm_session_, Remove()).WillOnce(Return(S_OK));
@@ -354,6 +412,7 @@
 }
 
 TEST_F(MediaFoundationCdmTest, RemoveSession_Failure) {
+  Initialize();
   CreateSessionAndGenerateRequest();
 
   COM_EXPECT_CALL(mf_cdm_session_, Remove()).WillOnce(Return(E_FAIL));
@@ -363,4 +422,47 @@
   task_environment_.RunUntilIdle();
 }
 
+TEST_F(MediaFoundationCdmTest, HardwareContextReset) {
+  Initialize();
+  CreateSessionAndGenerateRequest();
+
+  CdmContext* cdm_context = cdm_->GetCdmContext();
+  cdm_context->GetMediaFoundationCdmProxy(base::BindOnce(
+      &MediaFoundationCdmTest::OnCdmProxyReceived, base::Unretained(this)));
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(mf_cdm_proxy_);
+
+  COM_EXPECT_CALL(mf_cdm_session_, Close()).WillOnce(Return(S_OK));
+  EXPECT_CALL(cdm_client_, OnSessionClosed(kSessionId));
+  mf_cdm_proxy_->OnHardwareContextReset();
+
+  // Create a new session and expect success.
+  CreateSessionAndGenerateRequest();
+}
+
+TEST_F(MediaFoundationCdmTest, HardwareContextReset_InitializeFailure) {
+  Initialize();
+  CreateSessionAndGenerateRequest();
+
+  CdmContext* cdm_context = cdm_->GetCdmContext();
+  cdm_context->GetMediaFoundationCdmProxy(base::BindOnce(
+      &MediaFoundationCdmTest::OnCdmProxyReceived, base::Unretained(this)));
+  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(mf_cdm_proxy_);
+
+  // Make the next `Initialize()` fail.
+  can_initialize_ = false;
+
+  COM_EXPECT_CALL(mf_cdm_session_, Close()).WillOnce(Return(S_OK));
+  EXPECT_CALL(cdm_client_, OnSessionClosed(kSessionId));
+  mf_cdm_proxy_->OnHardwareContextReset();
+
+  std::vector<uint8_t> init_data = StringToVector("init_data");
+  cdm_->CreateSessionAndGenerateRequest(
+      CdmSessionType::kTemporary, EmeInitDataType::WEBM, init_data,
+      std::make_unique<MockCdmSessionPromise>(/*expect_success=*/false,
+                                              &session_id_));
+  task_environment_.RunUntilIdle();
+}
+
 }  // namespace media
diff --git a/media/filters/fuchsia/fuchsia_video_decoder.cc b/media/filters/fuchsia/fuchsia_video_decoder.cc
index fc109b9..d84c36a 100644
--- a/media/filters/fuchsia/fuchsia_video_decoder.cc
+++ b/media/filters/fuchsia/fuchsia_video_decoder.cc
@@ -82,10 +82,9 @@
       scoped_refptr<viz::RasterContextProvider> raster_context_provider,
       std::unique_ptr<gfx::GpuMemoryBuffer> gmb)
       : raster_context_provider_(raster_context_provider), weak_factory_(this) {
-    uint32_t usage = gpu::SHARED_IMAGE_USAGE_RASTER |
-                     gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION |
-                     gpu::SHARED_IMAGE_USAGE_DISPLAY |
-                     gpu::SHARED_IMAGE_USAGE_SCANOUT;
+    uint32_t usage = gpu::SHARED_IMAGE_USAGE_DISPLAY |
+                     gpu::SHARED_IMAGE_USAGE_SCANOUT |
+                     gpu::SHARED_IMAGE_USAGE_VIDEO_DECODE;
     mailbox_ =
         raster_context_provider_->SharedImageInterface()->CreateSharedImage(
             gmb.get(), nullptr, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin,
diff --git a/media/formats/BUILD.gn b/media/formats/BUILD.gn
index 1a9089f..618d7fa 100644
--- a/media/formats/BUILD.gn
+++ b/media/formats/BUILD.gn
@@ -65,6 +65,8 @@
     "webm/webm_info_parser.h",
     "webm/webm_parser.cc",
     "webm/webm_parser.h",
+    "webm/webm_projection_parser.cc",
+    "webm/webm_projection_parser.h",
     "webm/webm_stream_parser.cc",
     "webm/webm_stream_parser.h",
     "webm/webm_tracks_parser.cc",
@@ -224,6 +226,7 @@
     "webm/webm_content_encodings_client_unittest.cc",
     "webm/webm_crypto_helpers_unittest.cc",
     "webm/webm_parser_unittest.cc",
+    "webm/webm_projection_parser_unittest.cc",
     "webm/webm_stream_parser_unittest.cc",
     "webm/webm_tracks_parser_unittest.cc",
     "webm/webm_video_client_unittest.cc",
diff --git a/media/formats/webm/webm_constants.h b/media/formats/webm/webm_constants.h
index 4ca2e94..d971ba8 100644
--- a/media/formats/webm/webm_constants.h
+++ b/media/formats/webm/webm_constants.h
@@ -25,8 +25,8 @@
 const int kWebMIdBitsPerChannel = 0x55B2;
 const int kWebMIdBlock = 0xA1;
 const int kWebMIdBlockAddID = 0xEE;
-const int kWebMIdBlockAdditions = 0x75A1;
 const int kWebMIdBlockAdditional = 0xA5;
+const int kWebMIdBlockAdditions = 0x75A1;
 const int kWebMIdBlockDuration = 0x9B;
 const int kWebMIdBlockGroup = 0xA0;
 const int kWebMIdBlockMore = 0xA6;
@@ -165,6 +165,12 @@
 const int kWebMIdPrimaryGChromaticityY = 0x55D4;
 const int kWebMIdPrimaryRChromaticityX = 0x55D1;
 const int kWebMIdPrimaryRChromaticityY = 0x55D2;
+const int kWebMIdProjection = 0x7670;
+const int kWebMIdProjectionPosePitch = 0x7674;
+const int kWebMIdProjectionPoseRoll = 0x7675;
+const int kWebMIdProjectionPoseYaw = 0x7673;
+const int kWebMIdProjectionPrivate = 0x7672;
+const int kWebMIdProjectionType = 0x7671;
 const int kWebMIdRange = 0x55B9;
 const int kWebMIdReferenceBlock = 0xFB;
 const int kWebMIdReferencePriority = 0xFA;
diff --git a/media/formats/webm/webm_parser.cc b/media/formats/webm/webm_parser.cc
index ddc9718..ea7f050 100644
--- a/media/formats/webm/webm_parser.cc
+++ b/media/formats/webm/webm_parser.cc
@@ -191,6 +191,7 @@
     {UINT, kWebMIdDisplayHeight},   {UINT, kWebMIdDisplayUnit},
     {UINT, kWebMIdAspectRatioType}, {SKIP_BINARY, kWebMIdColorSpace},
     {SKIP_FLOAT, kWebMIdFrameRate}, {LIST, kWebMIdColour},
+    {LIST, kWebMIdProjection},
 };
 
 static const ElementIdInfo kColourIds[] = {
@@ -223,6 +224,12 @@
     {FLOAT, kWebMIdLuminanceMin},
 };
 
+static const ElementIdInfo kProjectionIds[]{
+    {UINT, kWebMIdProjectionType},      {SKIP_BINARY, kWebMIdProjectionPrivate},
+    {FLOAT, kWebMIdProjectionPoseYaw},  {FLOAT, kWebMIdProjectionPosePitch},
+    {FLOAT, kWebMIdProjectionPoseRoll},
+};
+
 static const ElementIdInfo kAudioIds[] = {
     {FLOAT, kWebMIdSamplingFrequency},
     {FLOAT, kWebMIdOutputSamplingFrequency},
@@ -426,6 +433,7 @@
     LIST_ELEMENT_INFO(kWebMIdSimpleTag, 3, kSimpleTagIds),
     LIST_ELEMENT_INFO(kWebMIdColour, 4, kColourIds),
     LIST_ELEMENT_INFO(kWebMIdMasteringMetadata, 5, kMasteringMetadataIds),
+    LIST_ELEMENT_INFO(kWebMIdProjection, 4, kProjectionIds),
 };
 
 // Parses an element header id or size field. These fields are variable length
diff --git a/media/formats/webm/webm_projection_parser.cc b/media/formats/webm/webm_projection_parser.cc
new file mode 100644
index 0000000..c7923908
--- /dev/null
+++ b/media/formats/webm/webm_projection_parser.cc
@@ -0,0 +1,145 @@
+// 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 "media/formats/webm/webm_projection_parser.h"
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "media/formats/webm/webm_constants.h"
+
+namespace {
+int64_t INVALID_PROJECTION_TYPE = -1;
+double INVALID_ANGLE = -1000;
+
+bool IsValidAngle(double val, double min, double max) {
+  return (val >= min && val <= max);
+}
+
+// Values for "ProjectionType" are spec'd here:
+// https://www.matroska.org/technical/elements.html#ProjectionType
+bool IsValidProjectionType(int64_t projection_type_code) {
+  const int64_t projection_type_min = 0;  // rectangular
+  const int64_t projection_type_max = 3;  // mesh
+  return projection_type_code >= projection_type_min &&
+         projection_type_code <= projection_type_max;
+}
+}  // namespace
+
+namespace media {
+
+WebMProjectionParser::WebMProjectionParser(MediaLog* media_log)
+    : media_log_(media_log) {
+  Reset();
+}
+
+WebMProjectionParser::~WebMProjectionParser() = default;
+
+void WebMProjectionParser::Reset() {
+  projection_type_ = INVALID_PROJECTION_TYPE;
+  pose_yaw_ = INVALID_ANGLE;
+  pose_pitch_ = INVALID_ANGLE;
+  pose_roll_ = INVALID_ANGLE;
+}
+
+// WebMParserClient
+bool WebMProjectionParser::OnUInt(int id, int64_t val) {
+  if (id != kWebMIdProjectionType) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Unexpected id in Projection: 0x" << std::hex << id;
+    return false;
+  }
+
+  if (projection_type_ != INVALID_PROJECTION_TYPE) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Multiple values for id: 0x" << std::hex << id << " specified ("
+        << projection_type_ << " and " << val << ")";
+    return false;
+  }
+
+  if (!IsValidProjectionType(val)) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Unexpected value for ProjectionType: 0x" << std::hex << val;
+    return false;
+  }
+
+  projection_type_ = val;
+  return true;
+}
+
+// WebMParserClient
+bool WebMProjectionParser::OnFloat(int id, double val) {
+  double* dst = NULL;
+  bool is_valid = false;
+
+  switch (id) {
+    case kWebMIdProjectionPoseYaw:
+      dst = &pose_yaw_;
+      // Valid range defined:
+      // https://www.matroska.org/technical/elements.html#ProjectionPoseYaw
+      is_valid = IsValidAngle(val, -180, 180);
+      break;
+    case kWebMIdProjectionPosePitch:
+      dst = &pose_pitch_;
+      // Valid range defined:
+      // https://www.matroska.org/technical/elements.html#ProjectionPosePitch
+      is_valid = IsValidAngle(val, -90, 90);
+      break;
+    case kWebMIdProjectionPoseRoll:
+      dst = &pose_roll_;
+      // Valid range defined:
+      // https://www.matroska.org/technical/elements.html#ProjectionPoseRoll
+      is_valid = IsValidAngle(val, -180, 180);
+      break;
+    default:
+      MEDIA_LOG(ERROR, media_log_)
+          << "Unexpected id in Projection: 0x" << std::hex << id;
+      return false;
+  }
+
+  if (*dst != INVALID_ANGLE) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Multiple values for id: 0x" << std::hex << id << " specified ("
+        << *dst << " and " << val << ")";
+    return false;
+  }
+
+  if (!is_valid) {
+    MEDIA_LOG(ERROR, media_log_) << "Value not within valid range. id: 0x"
+                                 << std::hex << id << " val:" << val;
+    return false;
+  }
+
+  *dst = val;
+  return true;
+}
+
+bool WebMProjectionParser::Validate() const {
+  if (projection_type_ == INVALID_PROJECTION_TYPE) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Projection element is incomplete; ProjectionType required.";
+    return false;
+  }
+
+  if (pose_yaw_ == INVALID_ANGLE) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Projection element is incomplete; ProjectionPoseYaw required.";
+    return false;
+  }
+
+  if (pose_pitch_ == INVALID_ANGLE) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Projection element is incomplete; ProjectionPosePitch required.";
+    return false;
+  }
+
+  if (pose_roll_ == INVALID_ANGLE) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Projection element is incomplete; ProjectionPoseRoll required.";
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace media
\ No newline at end of file
diff --git a/media/formats/webm/webm_projection_parser.h b/media/formats/webm/webm_projection_parser.h
new file mode 100644
index 0000000..b377b5e
--- /dev/null
+++ b/media/formats/webm/webm_projection_parser.h
@@ -0,0 +1,42 @@
+// 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 MEDIA_FORMATS_WEBM_WEBM_PROJECTION_PARSER_H_
+#define MEDIA_FORMATS_WEBM_WEBM_PROJECTION_PARSER_H_
+
+#include "base/macros.h"
+#include "media/base/media_log.h"
+#include "media/formats/webm/webm_parser.h"
+
+namespace media {
+
+// Parser for WebM Projection element:
+class MEDIA_EXPORT WebMProjectionParser : public WebMParserClient {
+ public:
+  explicit WebMProjectionParser(MediaLog* media_log);
+  ~WebMProjectionParser() override;
+
+  void Reset();
+  bool Validate() const;
+
+ private:
+  friend class WebMProjectionParserTest;
+
+  // WebMParserClient implementation.
+  bool OnUInt(int id, int64_t val) override;
+  bool OnFloat(int id, double val) override;
+
+  // private data
+  MediaLog* media_log_;
+  int64_t projection_type_;
+  double pose_yaw_;    // value must be [-180, 180]
+  double pose_pitch_;  // value must be [-90, 90]
+  double pose_roll_;   // value must be [-180, 180]
+
+  DISALLOW_COPY_AND_ASSIGN(WebMProjectionParser);
+};
+
+}  // namespace media
+
+#endif  // #define MEDIA_FORMATS_WEBM_WEBM_PROJECTION_PARSER_H_
\ No newline at end of file
diff --git a/media/formats/webm/webm_projection_parser_unittest.cc b/media/formats/webm/webm_projection_parser_unittest.cc
new file mode 100644
index 0000000..fd56cc7
--- /dev/null
+++ b/media/formats/webm/webm_projection_parser_unittest.cc
@@ -0,0 +1,186 @@
+// 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 "media/formats/webm/webm_projection_parser.h"
+
+#include "media/base/mock_media_log.h"
+#include "media/formats/webm/webm_constants.h"
+#include "media/formats/webm/webm_video_client.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::StrictMock;
+
+namespace media {
+
+// Matchers for verifying common media log entry strings.
+MATCHER(UnexpectedProjectionId, "") {
+  return CONTAINS_STRING(arg, "Unexpected id in Projection: 0x");
+}
+
+MATCHER(UnexpectedProjectionType, "") {
+  return CONTAINS_STRING(arg, "Unexpected value for ProjectionType: 0x");
+}
+
+MATCHER(UnexpectedMultipleValuesForProjectionType, "") {
+  return CONTAINS_STRING(arg, "Multiple values for id: 0x7671");
+}
+
+MATCHER(UnexpectedMultipleValuesForYaw, "") {
+  return CONTAINS_STRING(arg, "Multiple values for id: 0x7673");
+}
+
+MATCHER(UnexpectedMultipleValuesForPitch, "") {
+  return CONTAINS_STRING(arg, "Multiple values for id: 0x7674");
+}
+
+MATCHER(UnexpectedMultipleValuesForRoll, "") {
+  return CONTAINS_STRING(arg, "Multiple values for id: 0x7675");
+}
+
+MATCHER(UnexpectedProjectionYaw, "") {
+  return CONTAINS_STRING(arg, "Value not within valid range. id: 0x7673 val:");
+}
+
+MATCHER(UnexpectedProjectionPitch, "") {
+  return CONTAINS_STRING(arg, "Value not within valid range. id: 0x7674 val:");
+}
+
+MATCHER(UnexpectedProjectionRoll, "") {
+  return CONTAINS_STRING(arg, "Value not within valid range. id: 0x7675 val:");
+}
+
+MATCHER(MissingProjectionType, "") {
+  return CONTAINS_STRING(
+      arg, "Projection element is incomplete; ProjectionType required.");
+}
+
+MATCHER(MissingProjectionPoseYaw, "") {
+  return CONTAINS_STRING(
+      arg, "Projection element is incomplete; ProjectionPoseYaw required.");
+}
+
+MATCHER(MissingProjectionPosePitch, "") {
+  return CONTAINS_STRING(
+      arg, "Projection element is incomplete; ProjectionPosePitch required.");
+}
+
+MATCHER(MissingProjectionPoseRoll, "") {
+  return CONTAINS_STRING(
+      arg, "Projection element is incomplete; ProjectionPoseRoll required.");
+}
+
+class WebMProjectionParserTest : public testing::Test {
+ public:
+  WebMProjectionParserTest()
+      : projection_parser_(&media_log_), webm_video_client_(&media_log_) {}
+
+  bool OnUInt(int id, int64_t val) {
+    return projection_parser_.OnUInt(id, val);
+  }
+
+  bool OnFloat(int id, double val) {
+    return projection_parser_.OnFloat(id, val);
+  }
+
+  WebMParserClient* VideoClientOnListStart(int id) {
+    return webm_video_client_.OnListStart(id);
+  }
+
+  void VideoClientOnListEnd(int id) { webm_video_client_.OnListEnd(id); }
+
+  bool VideoClientOnUInt(int id, int64_t val) {
+    return webm_video_client_.OnUInt(id, val);
+  }
+
+  StrictMock<MockMediaLog> media_log_;
+  WebMProjectionParser projection_parser_;
+  WebMVideoClient webm_video_client_;
+};
+
+TEST_F(WebMProjectionParserTest, UnexpectedInt) {
+  EXPECT_MEDIA_LOG(UnexpectedProjectionId());
+  OnUInt(kWebMIdPrimaryBChromaticityX, 1);
+}
+
+TEST_F(WebMProjectionParserTest, UnexpectedFloat) {
+  EXPECT_MEDIA_LOG(UnexpectedProjectionId());
+  OnFloat(kWebMIdPrimaryBChromaticityX, 0);
+}
+
+TEST_F(WebMProjectionParserTest, InvalidProjectionType) {
+  EXPECT_MEDIA_LOG(UnexpectedProjectionType());
+  OnUInt(kWebMIdProjectionType, 4);
+}
+
+TEST_F(WebMProjectionParserTest, MultipleProjectionType) {
+  OnUInt(kWebMIdProjectionType, 1);
+  EXPECT_MEDIA_LOG(UnexpectedMultipleValuesForProjectionType());
+  OnUInt(kWebMIdProjectionType, 1);
+}
+
+TEST_F(WebMProjectionParserTest, InvalidProjectionYaw) {
+  EXPECT_MEDIA_LOG(UnexpectedProjectionYaw());
+  OnFloat(kWebMIdProjectionPoseYaw, 181);
+}
+
+TEST_F(WebMProjectionParserTest, InvalidProjectionPitch) {
+  EXPECT_MEDIA_LOG(UnexpectedProjectionPitch());
+  OnFloat(kWebMIdProjectionPosePitch, 91);
+}
+
+TEST_F(WebMProjectionParserTest, InvalidProjectionRoll) {
+  EXPECT_MEDIA_LOG(UnexpectedProjectionRoll());
+  OnFloat(kWebMIdProjectionPoseRoll, 181);
+}
+
+TEST_F(WebMProjectionParserTest, MultipleProjectionYaw) {
+  OnFloat(kWebMIdProjectionPoseYaw, 180);
+  EXPECT_MEDIA_LOG(UnexpectedMultipleValuesForYaw());
+  OnFloat(kWebMIdProjectionPoseYaw, 180);
+}
+
+TEST_F(WebMProjectionParserTest, MultipleProjectionPitch) {
+  OnFloat(kWebMIdProjectionPosePitch, 90);
+  EXPECT_MEDIA_LOG(UnexpectedMultipleValuesForPitch());
+  OnFloat(kWebMIdProjectionPosePitch, 90);
+}
+
+TEST_F(WebMProjectionParserTest, MultipleProjectionRoll) {
+  OnFloat(kWebMIdProjectionPoseRoll, 180);
+  EXPECT_MEDIA_LOG(UnexpectedMultipleValuesForRoll());
+  OnFloat(kWebMIdProjectionPoseRoll, 180);
+}
+
+TEST_F(WebMProjectionParserTest, MissingProjectionType) {
+  VideoClientOnListStart(kWebMIdProjection);
+  EXPECT_MEDIA_LOG(MissingProjectionType());
+  VideoClientOnListEnd(kWebMIdProjection);
+}
+
+TEST_F(WebMProjectionParserTest, MissingProjectionPosYaw) {
+  auto* parser = VideoClientOnListStart(kWebMIdProjection);
+  parser->OnUInt(kWebMIdProjectionType, 1);
+  EXPECT_MEDIA_LOG(MissingProjectionPoseYaw());
+  VideoClientOnListEnd(kWebMIdProjection);
+}
+
+TEST_F(WebMProjectionParserTest, MissingProjectionPosePitch) {
+  auto* parser = VideoClientOnListStart(kWebMIdProjection);
+  parser->OnUInt(kWebMIdProjectionType, 1);
+  parser->OnFloat(kWebMIdProjectionPoseYaw, 90);
+  EXPECT_MEDIA_LOG(MissingProjectionPosePitch());
+  VideoClientOnListEnd(kWebMIdProjection);
+}
+
+TEST_F(WebMProjectionParserTest, MissingProjectionPoseRoll) {
+  auto* parser = VideoClientOnListStart(kWebMIdProjection);
+  parser->OnUInt(kWebMIdProjectionType, 1);
+  parser->OnFloat(kWebMIdProjectionPoseYaw, 90);
+  parser->OnFloat(kWebMIdProjectionPosePitch, 90);
+  EXPECT_MEDIA_LOG(MissingProjectionPoseRoll());
+  VideoClientOnListEnd(kWebMIdProjection);
+}
+
+}  // namespace media
diff --git a/media/formats/webm/webm_stream_parser_unittest.cc b/media/formats/webm/webm_stream_parser_unittest.cc
index fdb1903..c6fb3bb 100644
--- a/media/formats/webm/webm_stream_parser_unittest.cc
+++ b/media/formats/webm/webm_stream_parser_unittest.cc
@@ -217,4 +217,17 @@
   EXPECT_EQ(video_config.color_space_info(), expected_color_space);
 }
 
+TEST_F(WebMStreamParserTest, ParseVideoWithSphericalMetadata) {
+  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimatedAny())
+      .Times(testing::AnyNumber());
+  StreamParser::InitParameters params(kInfiniteDuration);
+  params.detected_audio_track_count = 0;
+  params.detected_video_track_count = 1;
+  params.detected_text_track_count = 0;
+  ParseWebMFile("bear-spherical-metadata.webm", params);
+  EXPECT_EQ(media_tracks_->tracks().size(), 1u);
+
+  const auto& video_track = media_tracks_->tracks()[0];
+  EXPECT_EQ(video_track->type(), MediaTrack::Video);
+}
 }  // namespace media
diff --git a/media/formats/webm/webm_video_client.cc b/media/formats/webm/webm_video_client.cc
index 9eba79d..407c11b 100644
--- a/media/formats/webm/webm_video_client.cc
+++ b/media/formats/webm/webm_video_client.cc
@@ -28,9 +28,20 @@
       static_cast<size_t>(VP9PROFILE_PROFILE0) + data[2]);
 }
 
+// Values for "StereoMode" are spec'd here:
+// https://www.matroska.org/technical/elements.html#StereoMode
+bool IsValidStereoMode(int64_t stereo_mode_code) {
+  const int64_t stereo_mode_min = 0;  // mono
+  // both eyes laced in one Block (right eye is first)
+  const int64_t stereo_mode_max = 14;
+  return stereo_mode_code >= stereo_mode_min &&
+         stereo_mode_code <= stereo_mode_max;
+}
+
 }  // namespace
 
-WebMVideoClient::WebMVideoClient(MediaLog* media_log) : media_log_(media_log) {
+WebMVideoClient::WebMVideoClient(MediaLog* media_log)
+    : media_log_(media_log), projection_parser_(media_log) {
   Reset();
 }
 
@@ -48,6 +59,8 @@
   display_unit_ = -1;
   alpha_mode_ = -1;
   colour_parsed_ = false;
+  stereo_mode_ = -1;
+  projection_parsed_ = false;
 }
 
 bool WebMVideoClient::InitializeConfig(
@@ -137,6 +150,7 @@
                          : VideoDecoderConfig::AlphaMode::kIsOpaque,
                      color_space, kNoTransformation, coded_size, visible_rect,
                      natural_size, codec_private, encryption_scheme);
+
   return config->IsValidConfig();
 }
 
@@ -146,12 +160,27 @@
     return &colour_parser_;
   }
 
+  if (id == kWebMIdProjection) {
+    if (projection_parsed_ == true) {
+      MEDIA_LOG(ERROR, media_log_)
+          << "Unexpected multiple Projection elements.";
+      return NULL;
+    }
+    return &projection_parser_;
+  }
+
   return this;
 }
 
 bool WebMVideoClient::OnListEnd(int id) {
-  if (id == kWebMIdColour)
+  if (id == kWebMIdColour) {
     colour_parsed_ = true;
+  } else if (id == kWebMIdProjection) {
+    if (!projection_parser_.Validate()) {
+      return false;
+    }
+    projection_parsed_ = true;
+  }
   return true;
 }
 
@@ -189,6 +218,9 @@
     case kWebMIdAlphaMode:
       dst = &alpha_mode_;
       break;
+    case kWebMIdStereoMode:
+      dst = &stereo_mode_;
+      break;
     default:
       return true;
   }
@@ -200,6 +232,12 @@
     return false;
   }
 
+  if (id == kWebMIdStereoMode && !IsValidStereoMode(val)) {
+    MEDIA_LOG(ERROR, media_log_)
+        << "Unexpected value for StereoMode: 0x" << std::hex << val;
+    return false;
+  }
+
   *dst = val;
   return true;
 }
diff --git a/media/formats/webm/webm_video_client.h b/media/formats/webm/webm_video_client.h
index 3c15c463..558831d 100644
--- a/media/formats/webm/webm_video_client.h
+++ b/media/formats/webm/webm_video_client.h
@@ -16,6 +16,7 @@
 #include "media/base/media_log.h"
 #include "media/formats/webm/webm_colour_parser.h"
 #include "media/formats/webm/webm_parser.h"
+#include "media/formats/webm/webm_projection_parser.h"
 
 namespace media {
 class VideoDecoderConfig;
@@ -43,6 +44,7 @@
 
  private:
   friend class WebMVideoClientTest;
+  friend class WebMProjectionParserTest;
 
   // WebMParserClient implementation.
   WebMParserClient* OnListStart(int id) override;
@@ -62,10 +64,14 @@
   int64_t display_height_;
   int64_t display_unit_;
   int64_t alpha_mode_;
+  int64_t stereo_mode_;
 
   WebMColourParser colour_parser_;
   bool colour_parsed_ = false;
 
+  WebMProjectionParser projection_parser_;
+  bool projection_parsed_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(WebMVideoClient);
 };
 
diff --git a/media/formats/webm/webm_video_client_unittest.cc b/media/formats/webm/webm_video_client_unittest.cc
index 76b782b..85fdd3ec 100644
--- a/media/formats/webm/webm_video_client_unittest.cc
+++ b/media/formats/webm/webm_video_client_unittest.cc
@@ -13,6 +13,14 @@
 
 namespace {
 const gfx::Size kCodedSize(321, 243);
+
+MATCHER(UnexpectedStereoMode, "") {
+  return CONTAINS_STRING(arg, "Unexpected value for StereoMode: 0x");
+}
+
+MATCHER(UnexpectedMultipleValues, "") {
+  return CONTAINS_STRING(arg, "Multiple values for id");
+}
 }
 
 static const struct CodecTestParams {
@@ -47,6 +55,10 @@
 
   void OnListEnd(int id) { webm_video_client_.OnListEnd(id); }
 
+  bool OnUInt(int id, int64_t val) {
+    return webm_video_client_.OnUInt(id, val);
+  }
+
   testing::StrictMock<MockMediaLog> media_log_;
   WebMVideoClient webm_video_client_;
 
@@ -149,6 +161,17 @@
       << expected_config.AsHumanReadableString() << ")";
 }
 
+TEST_F(WebMVideoClientTest, InvalidStereoMode) {
+  EXPECT_MEDIA_LOG(UnexpectedStereoMode());
+  OnUInt(kWebMIdStereoMode, 15);
+}
+
+TEST_F(WebMVideoClientTest, MultipleStereoMode) {
+  OnUInt(kWebMIdStereoMode, 1);
+  EXPECT_MEDIA_LOG(UnexpectedMultipleValues());
+  OnUInt(kWebMIdStereoMode, 1);
+}
+
 INSTANTIATE_TEST_SUITE_P(All,
                          WebMVideoClientTest,
                          ::testing::ValuesIn(kCodecTestParams));
diff --git a/media/renderers/win/media_engine_notify_impl.cc b/media/renderers/win/media_engine_notify_impl.cc
index e68adcd..da71066f 100644
--- a/media/renderers/win/media_engine_notify_impl.cc
+++ b/media/renderers/win/media_engine_notify_impl.cc
@@ -62,9 +62,16 @@
 
 #undef ENUM_TO_STRING
 
-PipelineStatus MediaEngineStatusToPipelineStatus(
-    MF_MEDIA_ENGINE_ERR media_engine_status) {
-  switch (media_engine_status) {
+PipelineStatus MediaEngineErrorToPipelineStatus(
+    MF_MEDIA_ENGINE_ERR media_engine_error,
+    HRESULT hr) {
+  // HRESULT 0x8004CD12 is DRM_E_TEE_INVALID_HWDRM_STATE, which can happen
+  // during OS sleep/resume, or moving video to different graphics adapters.
+  // This is not an error, so special case it here.
+  if (hr == static_cast<HRESULT>(0x8004CD12))
+    return PipelineStatus::PIPELINE_ERROR_HARDWARE_CONTEXT_RESET;
+
+  switch (media_engine_error) {
     case MF_MEDIA_ENGINE_ERR_NOERROR:
       return PipelineStatus::PIPELINE_OK;
     case MF_MEDIA_ENGINE_ERR_ABORTED:
@@ -123,9 +130,9 @@
       // |param1| - A member of the MF_MEDIA_ENGINE_ERR enumeration.
       // |param2| - An HRESULT error code, or zero.
       MF_MEDIA_ENGINE_ERR error = static_cast<MF_MEDIA_ENGINE_ERR>(param1);
-      LOG(ERROR) << __func__ << ": error=" << error
-                 << ", hr=" << PrintHr(param2);
-      error_cb_.Run(MediaEngineStatusToPipelineStatus(error));
+      HRESULT hr = param2;
+      LOG(ERROR) << __func__ << ": error=" << error << ", hr=" << PrintHr(hr);
+      error_cb_.Run(MediaEngineErrorToPipelineStatus(error, hr));
       break;
     }
     case MF_MEDIA_ENGINE_EVENT_ENDED:
diff --git a/media/renderers/win/media_foundation_renderer.cc b/media/renderers/win/media_foundation_renderer.cc
index f37f9d8b..f6293593 100644
--- a/media/renderers/win/media_foundation_renderer.cc
+++ b/media/renderers/win/media_foundation_renderer.cc
@@ -339,9 +339,10 @@
   }
 
   waiting_for_mf_cdm_ = false;
+  cdm_proxy_ = std::move(cdm_proxy);
+  content_protection_manager_->SetCdmProxy(cdm_proxy_);
+  mf_source_->SetCdmProxy(cdm_proxy_);
 
-  content_protection_manager_->SetCdmProxy(cdm_proxy);
-  mf_source_->SetCdmProxy(cdm_proxy);
   HRESULT hr = SetSourceOnMediaEngine();
   if (FAILED(hr)) {
     DLOG(ERROR) << "Failed to set source on media engine: " << PrintHr(hr);
@@ -562,6 +563,9 @@
   DVLOG_FUNC(1) << "status=" << status;
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
+  if (status == PIPELINE_ERROR_HARDWARE_CONTEXT_RESET && cdm_proxy_)
+    cdm_proxy_->OnHardwareContextReset();
+
   renderer_client_->OnError(status);
   StopSendingStatistics();
 }
diff --git a/media/renderers/win/media_foundation_renderer.h b/media/renderers/win/media_foundation_renderer.h
index 14880978..768fa19f 100644
--- a/media/renderers/win/media_foundation_renderer.h
+++ b/media/renderers/win/media_foundation_renderer.h
@@ -12,6 +12,7 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequenced_task_runner.h"
 #include "base/timer/timer.h"
@@ -141,6 +142,8 @@
 
   bool waiting_for_mf_cdm_ = false;
   CdmContext* cdm_context_ = nullptr;
+  scoped_refptr<MediaFoundationCdmProxy> cdm_proxy_;
+
   Microsoft::WRL::ComPtr<MediaFoundationProtectionManager>
       content_protection_manager_;
 
diff --git a/media/renderers/win/media_foundation_renderer_unittest.cc b/media/renderers/win/media_foundation_renderer_unittest.cc
index b5ebb75..b4ca5ff 100644
--- a/media/renderers/win/media_foundation_renderer_unittest.cc
+++ b/media/renderers/win/media_foundation_renderer_unittest.cc
@@ -48,6 +48,7 @@
   MOCK_METHOD0(RefreshTrustedInput, HRESULT());
   MOCK_METHOD2(ProcessContentEnabler,
                HRESULT(IUnknown* request, IMFAsyncResult* result));
+  MOCK_METHOD0(OnHardwareContextReset, void());
 
  protected:
   ~MockMediaFoundationCdmProxy() override;
diff --git a/media/test/data/README.md b/media/test/data/README.md
index d96170b2..0127023e 100644
--- a/media/test/data/README.md
+++ b/media/test/data/README.md
@@ -1207,6 +1207,12 @@
 ffmpeg -i red.webm -i green.webm -i blue.webm -i a300hz.webm -i a500hz.webm -map 0 -map 1 -map 2 -map 3 -map 4  multitrack-3video-2audio.webm
 ```
 
+### Spherical metadata WebM files
+
+#### bear-spherical-metadata.webm
+bear_silent.webm video injected with "stereo_mode=SIDE_BY_SIDE_LEFT_EYE_FIRST", "projectionType=EQUIRECTANGULAR", 
+and projection pose_yaw, pose_pitch, and pose_roll = 10, 20, and 30 respectively.
+
 ### Opus pre-skip and end-trimming test clips
 https://people.xiph.org/~greg/opus_testvectors/
 
diff --git a/media/test/data/bear-spherical-metadata.webm b/media/test/data/bear-spherical-metadata.webm
new file mode 100644
index 0000000..8d15ad92
--- /dev/null
+++ b/media/test/data/bear-spherical-metadata.webm
Binary files differ
diff --git a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
index 6a3f529..29e3390e 100644
--- a/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
+++ b/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
@@ -105,7 +105,10 @@
  public:
   using Proxy = typename Interface::Proxy_;
 
-  AssociatedInterfacePtrState() {}
+  AssociatedInterfacePtrState() = default;
+  AssociatedInterfacePtrState(const AssociatedInterfacePtrState&) = delete;
+  AssociatedInterfacePtrState& operator=(const AssociatedInterfacePtrState&) =
+      delete;
   ~AssociatedInterfacePtrState() = default;
 
   Proxy* instance() {
@@ -125,7 +128,7 @@
         info.PassHandle(), info.version(),
         std::make_unique<typename Interface::ResponseValidator_>(),
         std::move(runner), Interface::Name_);
-    proxy_.reset(new Proxy(endpoint_client()));
+    proxy_ = std::make_unique<Proxy>(endpoint_client());
   }
 
   // After this method is called, the object is in an invalid state and
@@ -138,8 +141,6 @@
 
  private:
   std::unique_ptr<Proxy> proxy_;
-
-  DISALLOW_COPY_AND_ASSIGN(AssociatedInterfacePtrState);
 };
 
 }  // namespace internal
diff --git a/mojo/public/cpp/bindings/lib/message_quota_checker.cc b/mojo/public/cpp/bindings/lib/message_quota_checker.cc
index 7cd5d1e..dedb408 100644
--- a/mojo/public/cpp/bindings/lib/message_quota_checker.cc
+++ b/mojo/public/cpp/bindings/lib/message_quota_checker.cc
@@ -10,10 +10,12 @@
 #include "base/debug/activity_tracker.h"
 #include "base/debug/alias.h"
 #include "base/debug/dump_without_crashing.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/no_destructor.h"
 #include "base/rand_util.h"
 #include "base/synchronization/lock.h"
+#include "base/types/pass_key.h"
 #include "mojo/public/c/system/quota.h"
 #include "mojo/public/cpp/bindings/features.h"
 #include "mojo/public/cpp/bindings/mojo_buildflags.h"
@@ -179,7 +181,8 @@
   return MaybeCreateImpl(config);
 }
 
-MessageQuotaChecker::MessageQuotaChecker(const Configuration* config)
+MessageQuotaChecker::MessageQuotaChecker(const Configuration* config,
+                                         base::PassKey<MessageQuotaChecker>)
     : config_(config), creation_time_(base::TimeTicks::Now()) {}
 MessageQuotaChecker::~MessageQuotaChecker() = default;
 
@@ -210,7 +213,8 @@
   if (base::RandInt(0, config.sample_rate - 1) != 0)
     return nullptr;
 
-  return new MessageQuotaChecker(&config);
+  return base::MakeRefCounted<MessageQuotaChecker>(
+      &config, base::PassKey<MessageQuotaChecker>());
 }
 
 absl::optional<size_t> MessageQuotaChecker::GetCurrentMessagePipeQuota() {
diff --git a/mojo/public/cpp/bindings/lib/message_quota_checker.h b/mojo/public/cpp/bindings/lib/message_quota_checker.h
index c9b02195..40cb6c0 100644
--- a/mojo/public/cpp/bindings/lib/message_quota_checker.h
+++ b/mojo/public/cpp/bindings/lib/message_quota_checker.h
@@ -13,6 +13,7 @@
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
 #include "base/time/time.h"
+#include "base/types/pass_key.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -79,10 +80,17 @@
     double decayed_average_ = 0.0;
   };
 
+  // Exposed for use in tests.
+  struct Configuration;
+
   // Returns a new instance if this invocation has been sampled for quota
   // checking.
   static scoped_refptr<MessageQuotaChecker> MaybeCreate();
 
+  // Public for base::MakeRefCounted(). Use MaybeCreate().
+  MessageQuotaChecker(const Configuration* config,
+                      base::PassKey<MessageQuotaChecker>);
+
   // Call before writing a message to |message_pipe_|.
   void BeforeWrite();
 
@@ -99,14 +107,12 @@
 
   // Test support.
   size_t GetCurrentQuotaStatusForTesting();
-  struct Configuration;
   static Configuration GetConfigurationForTesting();
   static scoped_refptr<MessageQuotaChecker> MaybeCreateForTesting(
       const Configuration& config);
 
  private:
   friend class base::RefCountedThreadSafe<MessageQuotaChecker>;
-  explicit MessageQuotaChecker(const Configuration* config);
   ~MessageQuotaChecker();
   static Configuration GetConfiguration();
   static scoped_refptr<MessageQuotaChecker> MaybeCreateImpl(
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
index 6039e764..f6b62b0b 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -14,9 +14,11 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_util.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/types/pass_key.h"
 #include "mojo/public/cpp/bindings/interface_endpoint_client.h"
 #include "mojo/public/cpp/bindings/interface_endpoint_controller.h"
 #include "mojo/public/cpp/bindings/lib/may_auto_lock.h"
@@ -299,21 +301,26 @@
 
 struct MultiplexRouter::Task {
  public:
+  enum Type { MESSAGE, NOTIFY_ERROR };
+
   // Doesn't take ownership of |message| but takes its contents.
   static std::unique_ptr<Task> CreateMessageTask(
       MessageWrapper message_wrapper) {
-    Task* task = new Task(MESSAGE);
+    auto task = std::make_unique<Task>(MESSAGE, base::PassKey<Task>());
     task->message_wrapper = std::move(message_wrapper);
-    return base::WrapUnique(task);
+    return task;
   }
   static std::unique_ptr<Task> CreateNotifyErrorTask(
       InterfaceEndpoint* endpoint) {
-    Task* task = new Task(NOTIFY_ERROR);
+    auto task = std::make_unique<Task>(NOTIFY_ERROR, base::PassKey<Task>());
     task->endpoint_to_notify = endpoint;
-    return base::WrapUnique(task);
+    return task;
   }
 
-  ~Task() {}
+  explicit Task(Type in_type, base::PassKey<Task>) : type(in_type) {}
+  Task(const Task&) = delete;
+  Task& operator=(const Task&) = delete;
+  ~Task() = default;
 
   bool IsMessageTask() const { return type == MESSAGE; }
   bool IsNotifyErrorTask() const { return type == NOTIFY_ERROR; }
@@ -321,13 +328,7 @@
   MessageWrapper message_wrapper;
   scoped_refptr<InterfaceEndpoint> endpoint_to_notify;
 
-  enum Type { MESSAGE, NOTIFY_ERROR };
   Type type;
-
- private:
-  explicit Task(Type in_type) : type(in_type) {}
-
-  DISALLOW_COPY_AND_ASSIGN(Task);
 };
 
 // static
@@ -444,8 +445,11 @@
         id |= kInterfaceIdNamespaceMask;
     } while (base::Contains(endpoints_, id));
 
-    InterfaceEndpoint* endpoint = new InterfaceEndpoint(this, id);
-    endpoints_[id] = endpoint;
+    auto endpoint_ref = base::MakeRefCounted<InterfaceEndpoint>(this, id);
+    // Raw pointer use is safe because the InterfaceEndpoint will remain alive
+    // as long as a reference to it exists in the `endpoints_` map.
+    InterfaceEndpoint* endpoint = endpoint_ref.get();
+    endpoints_[id] = std::move(endpoint_ref);
     if (encountered_error_)
       UpdateEndpointStateMayRemove(endpoint, PEER_ENDPOINT_CLOSED);
     endpoint->set_handle_created();
@@ -1136,8 +1140,11 @@
 
   InterfaceEndpoint* endpoint = FindEndpoint(id);
   if (!endpoint) {
-    endpoint = new InterfaceEndpoint(this, id);
-    endpoints_[id] = endpoint;
+    auto endpoint_ref = base::MakeRefCounted<InterfaceEndpoint>(this, id);
+    // Raw pointer use is safe because the InterfaceEndpoint will remain alive
+    // as long as a reference to it exists in the `endpoints_` map.
+    endpoint = endpoint_ref.get();
+    endpoints_[id] = std::move(endpoint_ref);
     if (inserted)
       *inserted = true;
   }
diff --git a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
index 7b1712c..874d6d52 100644
--- a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
+++ b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
@@ -296,11 +296,11 @@
 }
 
 ScopedInterfaceEndpointHandle::ScopedInterfaceEndpointHandle()
-    : state_(new State) {}
+    : state_(base::MakeRefCounted<State>()) {}
 
 ScopedInterfaceEndpointHandle::ScopedInterfaceEndpointHandle(
     ScopedInterfaceEndpointHandle&& other)
-    : state_(new State) {
+    : state_(base::MakeRefCounted<State>()) {
   state_.swap(other.state_);
 }
 
@@ -355,7 +355,7 @@
 ScopedInterfaceEndpointHandle::ScopedInterfaceEndpointHandle(
     InterfaceId id,
     scoped_refptr<AssociatedGroupController> group_controller)
-    : state_(new State(id, std::move(group_controller))) {
+    : state_(base::MakeRefCounted<State>(id, std::move(group_controller))) {
   DCHECK(!IsValidInterfaceId(state_->id()) || state_->group_controller());
 }
 
@@ -367,7 +367,7 @@
 
 void ScopedInterfaceEndpointHandle::ResetInternal(
     const absl::optional<DisconnectReason>& reason) {
-  scoped_refptr<State> new_state(new State);
+  auto new_state = base::MakeRefCounted<State>();
   state_->Close(reason);
   state_.swap(new_state);
 }
diff --git a/mojo/public/cpp/bindings/lib/sync_event_watcher.cc b/mojo/public/cpp/bindings/lib/sync_event_watcher.cc
index ab69ade..97356dc 100644
--- a/mojo/public/cpp/bindings/lib/sync_event_watcher.cc
+++ b/mojo/public/cpp/bindings/lib/sync_event_watcher.cc
@@ -5,9 +5,11 @@
 #include "mojo/public/cpp/bindings/sync_event_watcher.h"
 
 #include <algorithm>
+#include <utility>
 
 #include "base/check_op.h"
 #include "base/containers/stack_container.h"
+#include "base/memory/scoped_refptr.h"
 
 namespace mojo {
 
@@ -16,7 +18,7 @@
     : event_(event),
       callback_(std::move(callback)),
       registry_(SyncHandleRegistry::current()),
-      destroyed_(new base::RefCountedData<bool>(false)) {}
+      destroyed_(base::MakeRefCounted<base::RefCountedData<bool>>(false)) {}
 
 SyncEventWatcher::~SyncEventWatcher() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/mojo/public/cpp/bindings/lib/sync_handle_registry.cc b/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
index 32c2d72..c4629591 100644
--- a/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
+++ b/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
@@ -10,10 +10,12 @@
 #include "base/auto_reset.h"
 #include "base/check_op.h"
 #include "base/containers/contains.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/no_destructor.h"
 #include "base/stl_util.h"
 #include "base/threading/sequence_local_storage_slot.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "base/types/pass_key.h"
 #include "mojo/public/c/system/core.h"
 
 namespace mojo {
@@ -39,14 +41,21 @@
 
   // SyncMessageFilter can be used on threads without sequence-local storage
   // being available. Those receive a unique, standalone SyncHandleRegistry.
-  if (!base::SequencedTaskRunnerHandle::IsSet())
-    return new SyncHandleRegistry();
+  if (!base::SequencedTaskRunnerHandle::IsSet()) {
+    return base::MakeRefCounted<SyncHandleRegistry>(
+        base::PassKey<SyncHandleRegistry>());
+  }
 
-  if (!*g_current_sync_handle_watcher)
-    g_current_sync_handle_watcher->emplace(new SyncHandleRegistry());
+  if (!*g_current_sync_handle_watcher) {
+    g_current_sync_handle_watcher->emplace(
+        base::MakeRefCounted<SyncHandleRegistry>(
+            base::PassKey<SyncHandleRegistry>()));
+  }
   return *g_current_sync_handle_watcher->GetValuePointer();
 }
 
+SyncHandleRegistry::SyncHandleRegistry(base::PassKey<SyncHandleRegistry>) {}
+
 bool SyncHandleRegistry::RegisterHandle(const Handle& handle,
                                         MojoHandleSignals handle_signals,
                                         HandleCallback callback) {
@@ -160,8 +169,6 @@
   return false;
 }
 
-SyncHandleRegistry::SyncHandleRegistry() = default;
-
 SyncHandleRegistry::~SyncHandleRegistry() = default;
 
 }  // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc b/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
index 53d8db15..a475c75 100644
--- a/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
+++ b/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
@@ -5,6 +5,7 @@
 #include "mojo/public/cpp/bindings/sync_handle_watcher.h"
 
 #include "base/check_op.h"
+#include "base/memory/scoped_refptr.h"
 
 namespace mojo {
 
@@ -18,7 +19,7 @@
       registered_(false),
       register_request_count_(0),
       registry_(SyncHandleRegistry::current()),
-      destroyed_(new base::RefCountedData<bool>(false)) {}
+      destroyed_(base::MakeRefCounted<base::RefCountedData<bool>>(false)) {}
 
 SyncHandleWatcher::~SyncHandleWatcher() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/mojo/public/cpp/bindings/sync_handle_registry.h b/mojo/public/cpp/bindings/sync_handle_registry.h
index 69ab2d9..6069cd9 100644
--- a/mojo/public/cpp/bindings/sync_handle_registry.h
+++ b/mojo/public/cpp/bindings/sync_handle_registry.h
@@ -16,6 +16,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/sequence_checker.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/types/pass_key.h"
 #include "mojo/public/cpp/system/core.h"
 #include "mojo/public/cpp/system/wait_set.h"
 
@@ -53,6 +54,12 @@
   // Returns a sequence-local object.
   static scoped_refptr<SyncHandleRegistry> current();
 
+  // Exposed for base::MakeRefCounted.
+  explicit SyncHandleRegistry(base::PassKey<SyncHandleRegistry>);
+
+  SyncHandleRegistry(const SyncHandleRegistry&) = delete;
+  SyncHandleRegistry& operator=(const SyncHandleRegistry&) = delete;
+
   // Registers a |Handle| to be watched for |handle_signals|. If any such
   // signals are satisfied during a Wait(), the Wait() is woken up and
   // |callback| is run.
@@ -79,7 +86,6 @@
  private:
   friend class base::RefCounted<SyncHandleRegistry>;
 
-  SyncHandleRegistry();
   ~SyncHandleRegistry();
 
   WaitSet wait_set_;
@@ -92,8 +98,6 @@
   bool in_nested_wait_ = false;
 
   SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(SyncHandleRegistry);
 };
 
 }  // namespace mojo
diff --git a/net/cert/cert_verify_proc_blocklist.inc b/net/cert/cert_verify_proc_blocklist.inc
index 51999c8..3dfca04 100644
--- a/net/cert/cert_verify_proc_blocklist.inc
+++ b/net/cert/cert_verify_proc_blocklist.inc
@@ -363,6 +363,10 @@
         {0xc5, 0x62, 0x17, 0xb7, 0xa8, 0x28, 0xc7, 0x34, 0x1c, 0x0a, 0xe7,
          0xa5, 0x90, 0xd8, 0x79, 0x0d, 0x4d, 0xef, 0x53, 0x66, 0x52, 0xe6,
          0x0a, 0xe5, 0xb8, 0xbd, 0xfa, 0x26, 0x97, 0x8f, 0xe0, 0x9c},
+        // 06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem
+        {0xe4, 0x7c, 0x5c, 0xd2, 0xdc, 0x8b, 0xab, 0xb4, 0xe5, 0x3f, 0x8a,
+         0x49, 0x83, 0x92, 0x02, 0x75, 0xef, 0x6f, 0xfa, 0xac, 0xb0, 0x89,
+         0xe8, 0x7a, 0x2c, 0x1f, 0xbe, 0x5a, 0x58, 0x5f, 0x05, 0xed},
 };
 
 // Hashes of SubjectPublicKeyInfos known to be used for interception by a
@@ -388,4 +392,8 @@
     {0xc5, 0x62, 0x17, 0xb7, 0xa8, 0x28, 0xc7, 0x34, 0x1c, 0x0a, 0xe7, 0xa5,
      0x90, 0xd8, 0x79, 0x0d, 0x4d, 0xef, 0x53, 0x66, 0x52, 0xe6, 0x0a, 0xe5,
      0xb8, 0xbd, 0xfa, 0x26, 0x97, 0x8f, 0xe0, 0x9c},
+    // 06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem
+    {0xe4, 0x7c, 0x5c, 0xd2, 0xdc, 0x8b, 0xab, 0xb4, 0xe5, 0x3f, 0x8a, 0x49,
+     0x83, 0x92, 0x02, 0x75, 0xef, 0x6f, 0xfa, 0xac, 0xb0, 0x89, 0xe8, 0x7a,
+     0x2c, 0x1f, 0xbe, 0x5a, 0x58, 0x5f, 0x05, 0xed},
 };
diff --git a/net/data/ssl/blocklist/06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem b/net/data/ssl/blocklist/06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem
new file mode 100644
index 0000000..ffc0c30
--- /dev/null
+++ b/net/data/ssl/blocklist/06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem
@@ -0,0 +1,128 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            58:77:d3:0c:6f:0f:3c:36:7f:8c:34:f2:86:fd:a5:28:43:bb:b9:f3
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN = Information Security Certification Authority, O = ISCA, C = KZ
+        Validity
+            Not Before: Feb 28 06:30:37 2020 GMT
+            Not After : Feb 28 06:30:37 2040 GMT
+        Subject: CN = Information Security Certification Authority, O = ISCA, C = KZ
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                RSA Public-Key: (4096 bit)
+                Modulus:
+                    00:e4:7b:b0:35:11:f4:da:c7:02:ab:9f:ca:bb:51:
+                    bf:c4:69:85:fb:de:c2:60:45:f3:c9:ba:cf:51:bc:
+                    8b:75:b3:7a:98:99:a8:28:4b:00:dd:2c:4a:80:04:
+                    61:22:37:06:28:2b:d0:9a:b9:1b:47:48:9a:47:fd:
+                    97:12:da:07:a4:d2:26:56:f9:8c:50:a1:d4:8d:86:
+                    43:26:88:be:6f:f3:bf:51:71:d2:0b:86:5c:a8:05:
+                    cb:ad:31:52:a5:62:f0:2b:9b:7a:f4:27:59:9e:3c:
+                    98:7c:28:bf:ca:c1:89:77:41:e9:03:c4:3c:3d:b3:
+                    3c:23:0f:2c:e2:10:c3:ac:9d:a8:0e:e9:47:ee:48:
+                    08:a9:91:a6:0f:08:b9:22:47:6e:57:47:a8:c3:66:
+                    18:d9:7b:e7:f8:86:dc:61:85:59:5e:94:2a:7a:1c:
+                    37:39:84:a3:94:81:f5:2a:83:b7:be:81:b8:39:4e:
+                    cb:ae:9f:63:66:d3:9a:89:94:36:c7:c5:b1:50:cc:
+                    eb:7e:4e:31:2c:48:bd:f6:53:d3:f5:27:3f:4d:4f:
+                    17:c4:58:34:13:c0:f4:7b:a4:5c:c9:33:aa:ed:ec:
+                    0e:e0:60:e6:23:38:22:03:56:e6:c5:70:91:63:01:
+                    2a:2d:b6:5c:3d:38:41:e9:a8:e9:af:2c:f2:aa:ba:
+                    01:47:f8:85:ed:26:ae:35:db:8f:83:b2:cf:1d:29:
+                    34:61:10:6e:8e:ed:d2:da:8a:9e:72:68:c5:b1:79:
+                    9c:67:71:ef:30:fb:d7:b9:af:0d:3f:af:9d:be:a4:
+                    ab:e9:66:38:ed:9a:c8:e5:cb:c3:8c:dd:a2:58:97:
+                    b0:35:6d:e6:b7:b9:e4:b6:68:a5:85:2d:5d:52:a7:
+                    0b:00:b1:af:eb:38:53:88:8b:33:0a:d0:75:a6:06:
+                    84:fa:b7:3e:9d:dc:4c:0e:c9:0d:a0:45:41:ed:e3:
+                    78:fa:88:83:f3:7a:2c:a3:a4:17:d5:f8:3c:49:81:
+                    22:d3:9a:49:a6:0c:a6:de:f2:37:0a:df:dd:28:c5:
+                    d9:c4:5a:ab:75:de:28:a6:a3:e5:57:26:c9:2a:0b:
+                    d9:c5:79:85:12:14:f9:a5:1f:84:f1:e3:f6:8f:f3:
+                    bd:df:e0:32:08:b6:9a:5e:42:8b:81:d1:ae:06:2e:
+                    ea:39:aa:b4:cc:4a:57:0b:72:e9:aa:0c:b7:ec:e4:
+                    c1:31:57:89:0f:59:e4:10:e7:cf:3b:0e:ba:81:8e:
+                    6b:91:41:96:97:ad:40:3a:57:d2:5b:44:49:9a:96:
+                    85:14:93:c9:e0:09:7a:47:5e:71:f8:39:ff:8d:6d:
+                    a1:55:b6:c5:c2:bc:ec:03:70:51:ca:35:7a:c6:80:
+                    63:18:c1
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+            X509v3 Subject Key Identifier: 
+                D8:77:D3:0C:6F:0F:3C:36:7F:8C:34:F2:86:FD:A5:28:43:BB:B9:F3
+            X509v3 Authority Key Identifier: 
+                keyid:D8:77:D3:0C:6F:0F:3C:36:7F:8C:34:F2:86:FD:A5:28:43:BB:B9:F3
+                DirName:/CN=Information Security Certification Authority/O=ISCA/C=KZ
+                serial:58:77:D3:0C:6F:0F:3C:36:7F:8C:34:F2:86:FD:A5:28:43:BB:B9:F3
+
+    Signature Algorithm: sha256WithRSAEncryption
+         47:00:fe:22:9e:43:ec:8e:0b:9c:8c:63:ad:98:8f:1e:e5:bd:
+         fd:35:dd:d4:5b:5c:fe:25:cb:bd:73:14:3a:53:21:e2:0e:14:
+         ed:d2:4b:81:6a:ca:29:82:92:6b:a9:76:1e:32:bc:e5:57:7b:
+         f2:b4:7d:1d:d4:15:2b:5a:e8:77:a0:5c:1e:49:9a:62:f4:b6:
+         15:19:dc:90:97:81:1e:1f:f5:0c:f9:05:9a:ab:24:a1:1a:53:
+         17:88:43:39:54:e6:34:c6:61:70:fb:ee:eb:cb:fc:5d:55:37:
+         54:14:3e:03:14:94:73:49:18:4f:29:3d:f4:ae:08:8c:37:7e:
+         ad:fb:d1:7c:0e:6d:81:cc:ed:61:cd:81:08:ea:58:1c:51:d2:
+         dd:f6:d0:81:76:a3:aa:ac:4e:16:4c:15:09:35:18:c5:02:78:
+         d6:43:55:b8:c3:4a:f1:60:eb:21:64:96:db:51:4a:58:82:ae:
+         38:41:84:a2:ce:60:1c:82:a7:4b:2d:29:cb:7b:91:de:5f:7c:
+         ad:1a:30:81:81:0b:3f:85:eb:83:2b:bf:f8:f5:37:cd:87:f9:
+         45:62:4c:79:ca:eb:39:a5:0d:23:7e:a3:95:0c:2f:de:68:f8:
+         bf:7d:93:e8:1a:62:f3:78:84:d9:e9:f4:28:fe:02:01:4f:f4:
+         eb:39:a4:1b:e3:c4:2b:29:de:e9:ef:03:01:23:f7:1e:6f:0d:
+         6b:9b:82:72:9c:0a:02:c1:a8:ac:54:87:4d:6e:81:59:58:aa:
+         01:66:c0:73:58:e4:5f:84:cb:48:8e:69:6f:51:eb:ef:b2:76:
+         6f:65:d8:cb:cb:b6:77:8e:a5:5f:c0:2a:85:79:75:0e:47:83:
+         4c:ba:05:e1:3c:19:16:fb:fe:e6:11:2f:06:88:ad:eb:10:a7:
+         f2:ab:5f:89:f1:5c:1b:4c:52:34:dc:fc:b1:58:80:6e:1d:03:
+         cc:34:29:c9:f8:20:00:41:49:69:c4:c7:b1:fe:7f:4b:d3:f4:
+         ea:b4:b4:39:e9:f6:a2:e2:ea:ef:eb:0e:02:d8:a7:53:7b:34:
+         bc:15:8f:8e:43:2b:62:5b:8c:45:c6:11:78:08:b1:d9:1d:7d:
+         cb:52:32:2c:fe:0e:7d:0b:3c:9f:09:5e:b3:40:54:d2:e5:8d:
+         10:d1:33:75:1a:e5:d9:a9:e7:98:aa:5c:88:61:2c:d4:4f:f4:
+         8f:3a:f8:1c:38:80:df:c9:01:c6:02:24:c4:54:5d:2e:3c:99:
+         e2:31:ec:c6:e5:fa:7e:c6:5a:5e:7f:7c:35:7b:32:1a:0e:be:
+         fb:aa:60:65:8b:7c:33:25:cc:bc:1d:44:de:f2:85:08:58:d5:
+         49:81:82:4a:b3:88:82:03
+-----BEGIN CERTIFICATE-----
+MIIGCzCCA/OgAwIBAgIUWHfTDG8PPDZ/jDTyhv2lKEO7ufMwDQYJKoZIhvcNAQEL
+BQAwUzE1MDMGA1UEAxMsSW5mb3JtYXRpb24gU2VjdXJpdHkgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkxDTALBgNVBAoTBElTQ0ExCzAJBgNVBAYTAktaMB4XDTIwMDIy
+ODA2MzAzN1oXDTQwMDIyODA2MzAzN1owUzE1MDMGA1UEAxMsSW5mb3JtYXRpb24g
+U2VjdXJpdHkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAoTBElTQ0Ex
+CzAJBgNVBAYTAktaMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5Huw
+NRH02scCq5/Ku1G/xGmF+97CYEXzybrPUbyLdbN6mJmoKEsA3SxKgARhIjcGKCvQ
+mrkbR0iaR/2XEtoHpNImVvmMUKHUjYZDJoi+b/O/UXHSC4ZcqAXLrTFSpWLwK5t6
+9CdZnjyYfCi/ysGJd0HpA8Q8PbM8Iw8s4hDDrJ2oDulH7kgIqZGmDwi5IkduV0eo
+w2YY2Xvn+IbcYYVZXpQqehw3OYSjlIH1KoO3voG4OU7Lrp9jZtOaiZQ2x8WxUMzr
+fk4xLEi99lPT9Sc/TU8XxFg0E8D0e6RcyTOq7ewO4GDmIzgiA1bmxXCRYwEqLbZc
+PThB6ajpryzyqroBR/iF7SauNduPg7LPHSk0YRBuju3S2oqecmjFsXmcZ3HvMPvX
+ua8NP6+dvqSr6WY47ZrI5cvDjN2iWJewNW3mt7nktmilhS1dUqcLALGv6zhTiIsz
+CtB1pgaE+rc+ndxMDskNoEVB7eN4+oiD83oso6QX1fg8SYEi05pJpgym3vI3Ct/d
+KMXZxFqrdd4opqPlVybJKgvZxXmFEhT5pR+E8eP2j/O93+AyCLaaXkKLgdGuBi7q
+Oaq0zEpXC3Lpqgy37OTBMVeJD1nkEOfPOw66gY5rkUGWl61AOlfSW0RJmpaFFJPJ
+4Al6R15x+Dn/jW2hVbbFwrzsA3BRyjV6xoBjGMECAwEAAaOB1jCB0zAPBgNVHRMB
+Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU2HfTDG8PPDZ/jDTy
+hv2lKEO7ufMwgZAGA1UdIwSBiDCBhYAU2HfTDG8PPDZ/jDTyhv2lKEO7ufOhV6RV
+MFMxNTAzBgNVBAMTLEluZm9ybWF0aW9uIFNlY3VyaXR5IENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5MQ0wCwYDVQQKEwRJU0NBMQswCQYDVQQGEwJLWoIUWHfTDG8PPDZ/
+jDTyhv2lKEO7ufMwDQYJKoZIhvcNAQELBQADggIBAEcA/iKeQ+yOC5yMY62Yjx7l
+vf013dRbXP4ly71zFDpTIeIOFO3SS4FqyimCkmupdh4yvOVXe/K0fR3UFSta6Heg
+XB5JmmL0thUZ3JCXgR4f9Qz5BZqrJKEaUxeIQzlU5jTGYXD77uvL/F1VN1QUPgMU
+lHNJGE8pPfSuCIw3fq370XwObYHM7WHNgQjqWBxR0t320IF2o6qsThZMFQk1GMUC
+eNZDVbjDSvFg6yFklttRSliCrjhBhKLOYByCp0stKct7kd5ffK0aMIGBCz+F64Mr
+v/j1N82H+UViTHnK6zmlDSN+o5UML95o+L99k+gaYvN4hNnp9Cj+AgFP9Os5pBvj
+xCsp3unvAwEj9x5vDWubgnKcCgLBqKxUh01ugVlYqgFmwHNY5F+Ey0iOaW9R6++y
+dm9l2MvLtneOpV/AKoV5dQ5Hg0y6BeE8GRb7/uYRLwaIresQp/KrX4nxXBtMUjTc
+/LFYgG4dA8w0Kcn4IABBSWnEx7H+f0vT9Oq0tDnp9qLi6u/rDgLYp1N7NLwVj45D
+K2JbjEXGEXgIsdkdfctSMiz+Dn0LPJ8JXrNAVNLljRDRM3Ua5dmp55iqXIhhLNRP
+9I86+Bw4gN/JAcYCJMRUXS48meIx7Mbl+n7GWl5/fDV7MhoOvvuqYGWLfDMlzLwd
+RN7yhQhY1UmBgkqziIID
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/blocklist/README.md b/net/data/ssl/blocklist/README.md
index 405688b1..3c59983 100644
--- a/net/data/ssl/blocklist/README.md
+++ b/net/data/ssl/blocklist/README.md
@@ -307,6 +307,7 @@
   * [61c0fc2e38b5b6f9071b42cee54a9013d858b6697c68b460948551b3249576a1.pem](61c0fc2e38b5b6f9071b42cee54a9013d858b6697c68b460948551b3249576a1.pem)
   * [1df696f021ab1c3ace9a376b07ed7256a40214cd3396d7934087614924e2d7ef.pem](1df696f021ab1c3ace9a376b07ed7256a40214cd3396d7934087614924e2d7ef.pem)
   * [0230a604d99220e5612ee7862ab9f7a6e18e4f1ac4c9e27075788cc5220169ab.pem](0230a604d99220e5612ee7862ab9f7a6e18e4f1ac4c9e27075788cc5220169ab.pem)
+  * [06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem](06fd20629c143b9eab28d2799caefc5d23fde267d16c631e3f5b8b4bab3f68e6.pem)
 
 ### revoked.badssl.com
 
diff --git a/services/network/cookie_settings.cc b/services/network/cookie_settings.cc
index e118d54..3e0c5b6 100644
--- a/services/network/cookie_settings.cc
+++ b/services/network/cookie_settings.cc
@@ -89,6 +89,15 @@
          url.SchemeIsCryptographic();
 }
 
+bool CookieSettings::IsCookieAccessible(
+    const net::CanonicalCookie& cookie,
+    const GURL& url,
+    const GURL& site_for_cookies,
+    const absl::optional<url::Origin>& top_frame_origin) const {
+  // TODO(https://crbug.com/1203706): Rewrite this to look at the cookie itself.
+  return IsFullCookieAccessAllowed(url, site_for_cookies, top_frame_origin);
+}
+
 bool CookieSettings::ShouldAlwaysAllowCookies(
     const GURL& url,
     const GURL& first_party_url) const {
diff --git a/services/network/cookie_settings.h b/services/network/cookie_settings.h
index 2ac08aa..8a1ff73 100644
--- a/services/network/cookie_settings.h
+++ b/services/network/cookie_settings.h
@@ -8,6 +8,7 @@
 #include "base/component_export.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/cookie_settings_base.h"
+#include "net/cookies/canonical_cookie.h"
 #include "services/network/public/cpp/session_cookie_delete_predicate.h"
 
 class GURL;
@@ -86,6 +87,15 @@
       const GURL& site_for_cookies,
       const absl::optional<url::Origin>& top_frame_origin) const;
 
+  // Returns true if the given cookie is accessible according to user
+  // cookie-blocking settings. Assumes that the cookie is otherwise accessible
+  // (i.e. that the cookie is otherwise valid with no other exclusion reasons).
+  bool IsCookieAccessible(
+      const net::CanonicalCookie& cookie,
+      const GURL& url,
+      const GURL& site_for_cookies,
+      const absl::optional<url::Origin>& top_frame_origin) const;
+
  private:
   // Returns whether third-party cookie blocking should be bypassed (i.e. always
   // allow the cookie regardless of cookie content settings and third-party
diff --git a/services/network/network_service_network_delegate.cc b/services/network/network_service_network_delegate.cc
index 2719cea..de2ce3c9 100644
--- a/services/network/network_service_network_delegate.cc
+++ b/services/network/network_service_network_delegate.cc
@@ -216,11 +216,9 @@
     bool allowed_from_caller) {
   bool allowed =
       allowed_from_caller &&
-      network_context_->cookie_manager()
-          ->cookie_settings()
-          .IsCookieAccessAllowed(request.url(),
-                                 request.site_for_cookies().RepresentativeUrl(),
-                                 request.isolation_info().top_frame_origin());
+      network_context_->cookie_manager()->cookie_settings().IsCookieAccessible(
+          cookie, request.url(), request.site_for_cookies().RepresentativeUrl(),
+          request.isolation_info().top_frame_origin());
   if (!allowed)
     return false;
   URLLoader* url_loader = URLLoader::ForRequest(request);
diff --git a/services/network/restricted_cookie_manager.cc b/services/network/restricted_cookie_manager.cc
index 6b5e12b..b1ab2b4 100644
--- a/services/network/restricted_cookie_manager.cc
+++ b/services/network/restricted_cookie_manager.cc
@@ -210,8 +210,9 @@
     // not deleted. This check prevents the site from observing their cookies
     // being deleted at a later time, which can happen due to eviction or due to
     // the user explicitly deleting all cookies.
-    if (!restricted_cookie_manager_->cookie_settings()->IsCookieAccessAllowed(
-            url_, site_for_cookies_.RepresentativeUrl(), top_frame_origin_)) {
+    if (!restricted_cookie_manager_->cookie_settings()->IsCookieAccessible(
+            change.cookie, url_, site_for_cookies_.RepresentativeUrl(),
+            top_frame_origin_)) {
       return;
     }
 
@@ -399,8 +400,8 @@
   }
 
   // TODO(morlovich): Try to validate site_for_cookies as well.
-  bool blocked = !cookie_settings_->IsCookieAccessAllowed(
-      url, site_for_cookies.RepresentativeUrl(), top_frame_origin);
+  bool blocked = !cookie_settings_->IsCookieAccessible(
+      cookie, url, site_for_cookies.RepresentativeUrl(), top_frame_origin);
 
   net::CookieInclusionStatus status;
   if (blocked)
diff --git a/sql/database.cc b/sql/database.cc
index 0a005ea..b5107b3 100644
--- a/sql/database.cc
+++ b/sql/database.cc
@@ -17,9 +17,6 @@
 #include "base/format_macros.h"
 #include "base/location.h"
 #include "base/logging.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
 #include "base/no_destructor.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/single_thread_task_runner.h"
@@ -259,18 +256,6 @@
   enable_mmap_by_default_ = false;
 }
 
-void Database::RecordEvent(Events event, size_t count) {
-  for (size_t i = 0; i < count; ++i) {
-    UMA_HISTOGRAM_ENUMERATION("Sqlite.Stats2", event, EVENT_MAX_VALUE);
-  }
-
-  if (stats_histogram_) {
-    for (size_t i = 0; i < count; ++i) {
-      stats_histogram_->Add(event);
-    }
-  }
-}
-
 bool Database::Open(const base::FilePath& path) {
   TRACE_EVENT1("sql", "Database::Open", "path", path.MaybeAsASCII());
   return OpenInternal(AsUTF8ForSQL(path), RETRY_ON_POISON);
@@ -332,10 +317,8 @@
     }
 
     int rc = sqlite3_close(db_);
-    if (rc != SQLITE_OK) {
-      base::UmaHistogramSparse("Sqlite.CloseFailure", rc);
+    if (rc != SQLITE_OK)
       DLOG(DCHECK) << "sqlite3_close failed: " << GetErrorMessage();
-    }
   }
   db_ = nullptr;
 }
@@ -663,29 +646,21 @@
   // TODO(shess): Move all cases to the view implementation.
   int64_t mmap_ofs = 0;
   if (mmap_alt_status_) {
-    if (!GetMmapAltStatus(&mmap_ofs)) {
-      RecordOneEvent(EVENT_MMAP_STATUS_FAILURE_READ);
+    if (!GetMmapAltStatus(&mmap_ofs))
       return 0;
-    }
   } else {
     // If [meta] doesn't exist, yet, it's a new database, assume the best.
     // sql::MetaTable::Init() will preload kMmapSuccess.
-    if (!MetaTable::DoesTableExist(this)) {
-      RecordOneEvent(EVENT_MMAP_META_MISSING);
+    if (!MetaTable::DoesTableExist(this))
       return kMmapEverything;
-    }
 
-    if (!MetaTable::GetMmapStatus(this, &mmap_ofs)) {
-      RecordOneEvent(EVENT_MMAP_META_FAILURE_READ);
+    if (!MetaTable::GetMmapStatus(this, &mmap_ofs))
       return 0;
-    }
   }
 
   // Database read failed in the past, don't memory map.
-  if (mmap_ofs == MetaTable::kMmapFailure) {
-    RecordOneEvent(EVENT_MMAP_FAILED);
+  if (mmap_ofs == MetaTable::kMmapFailure)
     return 0;
-  }
 
   if (mmap_ofs != MetaTable::kMmapSuccess) {
     // Continue reading from previous offset.
@@ -700,10 +675,8 @@
     // to limit checking to 20MB per run of Chromium.
     sqlite3_file* file = nullptr;
     sqlite3_int64 db_size = 0;
-    if (SQLITE_OK != GetSqlite3FileAndSize(db_, &file, &db_size)) {
-      RecordOneEvent(EVENT_MMAP_VFS_FAILURE);
+    if (SQLITE_OK != GetSqlite3FileAndSize(db_, &file, &db_size))
       return 0;
-    }
 
     // Read the data left, or |g_reads_allowed|, whichever is smaller.
     // |g_reads_allowed| limits the total amount of I/O to spend verifying data
@@ -751,19 +724,12 @@
       }
 
       if (mmap_alt_status_) {
-        if (!SetMmapAltStatus(mmap_ofs)) {
-          RecordOneEvent(EVENT_MMAP_STATUS_FAILURE_UPDATE);
+        if (!SetMmapAltStatus(mmap_ofs))
           return 0;
-        }
       } else {
-        if (!MetaTable::SetMmapStatus(this, mmap_ofs)) {
-          RecordOneEvent(EVENT_MMAP_META_FAILURE_UPDATE);
+        if (!MetaTable::SetMmapStatus(this, mmap_ofs))
           return 0;
-        }
       }
-
-      if (mmap_ofs == MetaTable::kMmapFailure)
-        RecordOneEvent(EVENT_MMAP_FAILED_NEW);
     }
   }
 
@@ -862,7 +828,6 @@
 
   const char* kMain = "main";
   int rc = BackupDatabase(null_db.db_, db_, kMain);
-  base::UmaHistogramSparse("Sqlite.RazeDatabase", rc);
 
   // The destination database was locked.
   if (rc == SQLITE_BUSY) {
@@ -885,13 +850,11 @@
 
     rc = file->pMethods->xTruncate(file, 0);
     if (rc != SQLITE_OK) {
-      base::UmaHistogramSparse("Sqlite.RazeDatabaseTruncate", rc);
       DLOG(DCHECK) << "Failed to truncate file.";
       return false;
     }
 
     rc = BackupDatabase(null_db.db_, db_, kMain);
-    base::UmaHistogramSparse("Sqlite.RazeDatabase2", rc);
 
     DCHECK_EQ(rc, SQLITE_DONE) << "Failed retrying Raze().";
   }
@@ -915,7 +878,6 @@
     }
 
     rc = BackupDatabase(null_db.db_, db_, kMain);
-    base::UmaHistogramSparse("Sqlite.RazeDatabase2", rc);
 
     DCHECK_EQ(rc, SQLITE_DONE) << "Failed retrying Raze().";
   }
@@ -1463,14 +1425,6 @@
 
   EnsureSqliteInitialized();
 
-  // Setup the stats histograms immediately rather than allocating lazily.
-  // Databases which won't exercise all of these probably shouldn't exist.
-  if (!histogram_tag_.empty()) {
-    stats_histogram_ = base::LinearHistogram::FactoryGet(
-        "Sqlite.Stats2." + histogram_tag_, 1, EVENT_MAX_VALUE,
-        EVENT_MAX_VALUE + 1, base::HistogramBase::kUmaTargetedHistogramFlag);
-  }
-
   // If |poisoned_| is set, it means an error handler called
   // RazeAndClose().  Until regular Close() is called, the caller
   // should be treating the database as open, but is_open() currently
@@ -1499,10 +1453,6 @@
     // available, fetch manually.
     err = sqlite3_extended_errcode(db_);
 
-    // Histogram failures specific to initial open for debugging
-    // purposes.
-    base::UmaHistogramSparse("Sqlite.OpenFailure", err);
-
     OnSqliteError(err, nullptr, "-- sqlite3_open()");
     bool was_poisoned = poisoned_;
     Close();
@@ -1540,7 +1490,6 @@
   // be razed.
   err = ExecuteAndReturnErrorCode("PRAGMA auto_vacuum");
   if (err != SQLITE_OK) {
-    base::UmaHistogramSparse("Sqlite.OpenProbeFailure", err);
     OnSqliteError(err, nullptr, "PRAGMA auto_vacuum");
 
     // Retry or bail out if the error handler poisoned the handle.
@@ -1679,29 +1628,11 @@
   histogram_tag_ = tag;
 }
 
-void Database::AddTaggedHistogram(const std::string& name, int sample) const {
-  if (histogram_tag_.empty())
-    return;
-
-  // TODO(shess): The histogram macros create a bit of static storage
-  // for caching the histogram object.  This code shouldn't execute
-  // often enough for such caching to be crucial.  If it becomes an
-  // issue, the object could be cached alongside histogram_prefix_.
-  std::string full_histogram_name = name + "." + histogram_tag_;
-  base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
-      full_histogram_name, base::HistogramBase::kUmaTargetedHistogramFlag);
-  if (histogram)
-    histogram->Add(sample);
-}
-
 int Database::OnSqliteError(int err,
                             sql::Statement* stmt,
                             const char* sql) const {
   TRACE_EVENT0("sql", "Database::OnSqliteError");
 
-  base::UmaHistogramSparse("Sqlite.Error", err);
-  AddTaggedHistogram("Sqlite.Error", err);
-
   // Always log the error.
   if (!sql && stmt)
     sql = stmt->GetSQLStatement();
diff --git a/sql/database.h b/sql/database.h
index 93906e65..fc9f9676 100644
--- a/sql/database.h
+++ b/sql/database.h
@@ -33,7 +33,6 @@
 
 namespace base {
 class FilePath;
-class HistogramBase;
 namespace trace_event {
 class ProcessMemoryDump;
 }  // namespace trace_event
@@ -164,66 +163,9 @@
   bool has_error_callback() const { return !error_callback_.is_null(); }
   void reset_error_callback() { error_callback_.Reset(); }
 
-  // Set this to enable additional per-database histogramming.  Must be called
-  // before Open().
+  // Developer-friendly database ID used in logging output and memory dumps.
   void set_histogram_tag(const std::string& tag);
 
-  // Record a sparse UMA histogram sample under
-  // |name|+"."+|histogram_tag_|.  If |histogram_tag_| is empty, no
-  // histogram is recorded.
-  void AddTaggedHistogram(const std::string& name, int sample) const;
-
-  // Track various API calls and results.  Values correspond to UMA
-  // histograms, do not modify, or add or delete other than directly
-  // before EVENT_MAX_VALUE.
-  enum Events {
-    // Number of statements run, either with sql::Statement or Execute*().
-    EVENT_STATEMENT_RUN_DEPRECATED = 0,
-
-    // Number of rows returned by statements run.
-    EVENT_STATEMENT_ROWS_DEPRECATED,
-
-    // Number of statements successfully run (all steps returned SQLITE_DONE or
-    // SQLITE_ROW).
-    EVENT_STATEMENT_SUCCESS_DEPRECATED,
-
-    // Number of statements run by Execute() or ExecuteAndReturnErrorCode().
-    EVENT_EXECUTE_DEPRECATED,
-
-    // Number of rows changed by autocommit statements.
-    EVENT_CHANGES_AUTOCOMMIT_DEPRECATED,
-
-    // Number of rows changed by statements in transactions.
-    EVENT_CHANGES_DEPRECATED,
-
-    // Count actual SQLite transaction statements (not including nesting).
-    EVENT_BEGIN_DEPRECATED,
-    EVENT_COMMIT_DEPRECATED,
-    EVENT_ROLLBACK_DEPRECATED,
-
-    // Track success and failure in GetAppropriateMmapSize().
-    // GetAppropriateMmapSize() should record at most one of these per run.  The
-    // case of mapping everything is not recorded.
-    EVENT_MMAP_META_MISSING,                    // No meta table present.
-    EVENT_MMAP_META_FAILURE_READ,               // Failed reading meta table.
-    EVENT_MMAP_META_FAILURE_UPDATE,             // Failed updating meta table.
-    EVENT_MMAP_VFS_FAILURE,                     // Failed to access VFS.
-    EVENT_MMAP_FAILED,                          // Failure from past run.
-    EVENT_MMAP_FAILED_NEW,                      // Read error in this run.
-    EVENT_MMAP_SUCCESS_NEW_DEPRECATED,          // Read to EOF in this run.
-    EVENT_MMAP_SUCCESS_PARTIAL_DEPRECATED,      // Read but did not reach EOF.
-    EVENT_MMAP_SUCCESS_NO_PROGRESS_DEPRECATED,  // Read quota exhausted.
-
-    EVENT_MMAP_STATUS_FAILURE_READ,    // Failure reading MmapStatus view.
-    EVENT_MMAP_STATUS_FAILURE_UPDATE,  // Failure updating MmapStatus view.
-
-    // Leave this at the end.
-    // TODO(shess): |EVENT_MAX| causes compile fail on Windows.
-    EVENT_MAX_VALUE,
-  };
-  void RecordEvent(Events event, size_t count);
-  void RecordOneEvent(Events event) { RecordEvent(event, 1); }
-
   // Run "PRAGMA integrity_check" and post each line of
   // results into |messages|.  Returns the success of running the
   // statement - per the SQLite documentation, if no errors are found the
@@ -795,12 +737,9 @@
 
   ErrorCallback error_callback_;
 
-  // Tag for auxiliary histograms.
+  // Developer-friendly database ID used in logging output and memory dumps.
   std::string histogram_tag_;
 
-  // Linear histogram for RecordEvent().
-  base::HistogramBase* stats_histogram_ = nullptr;
-
   // Stores the dump provider object when db is open.
   std::unique_ptr<DatabaseMemoryDumpProvider> memory_dump_provider_;
 
diff --git a/sql/initialization.cc b/sql/initialization.cc
index 58a1ed7a..7579fc5 100644
--- a/sql/initialization.cc
+++ b/sql/initialization.cc
@@ -4,47 +4,13 @@
 
 #include "sql/initialization.h"
 
-#include "base/bind.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/no_destructor.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/synchronization/lock.h"
 #include "base/trace_event/trace_event.h"
-#include "build/build_config.h"
 #include "third_party/sqlite/sqlite3.h"
 
 namespace sql {
 
-namespace {
-
-#if !defined(OS_IOS)
-void RecordSqliteMemory10Min() {
-  const int32_t used =
-      base::saturated_cast<int32_t>(sqlite3_memory_used() / 1024);
-  UMA_HISTOGRAM_COUNTS_1M("Sqlite.MemoryKB.TenMinutes", used);
-}
-
-void RecordSqliteMemoryHour() {
-  const int32_t used =
-      base::saturated_cast<int32_t>(sqlite3_memory_used() / 1024);
-  UMA_HISTOGRAM_COUNTS_1M("Sqlite.MemoryKB.OneHour", used);
-}
-
-void RecordSqliteMemoryDay() {
-  const int32_t used =
-      base::saturated_cast<int32_t>(sqlite3_memory_used() / 1024);
-  UMA_HISTOGRAM_COUNTS_1M("Sqlite.MemoryKB.OneDay", used);
-}
-
-void RecordSqliteMemoryWeek() {
-  const int32_t used =
-      base::saturated_cast<int32_t>(sqlite3_memory_used() / 1024);
-  UMA_HISTOGRAM_COUNTS_1M("Sqlite.MemoryKB.OneWeek", used);
-}
-#endif  // !defined(OS_IOS)
-
-}  // anonymous namespace
-
 void EnsureSqliteInitialized() {
   // sqlite3_initialize() uses double-checked locking and thus can have
   // data races.
@@ -55,27 +21,6 @@
   if (first_call) {
     TRACE_EVENT0("sql", "EnsureSqliteInitialized");
     sqlite3_initialize();
-
-#if !defined(OS_IOS)
-    // Schedule callback to record memory footprint histograms at 10m, 1h, and
-    // 1d. There may not be a registered task runner in tests.
-    // TODO(crbug.com/861889): Disable very long critical tasks on iOS until
-    // 861889 is fixed.
-    if (base::SequencedTaskRunnerHandle::IsSet()) {
-      base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE, base::BindOnce(&RecordSqliteMemory10Min),
-          base::TimeDelta::FromMinutes(10));
-      base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE, base::BindOnce(&RecordSqliteMemoryHour),
-          base::TimeDelta::FromHours(1));
-      base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE, base::BindOnce(&RecordSqliteMemoryDay),
-          base::TimeDelta::FromDays(1));
-      base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
-          FROM_HERE, base::BindOnce(&RecordSqliteMemoryWeek),
-          base::TimeDelta::FromDays(7));
-    }
-#endif  // !defined(OS_IOS)
     first_call = false;
   }
 }
diff --git a/sql/meta_table.cc b/sql/meta_table.cc
index 03bd25a..96b7d63 100644
--- a/sql/meta_table.cc
+++ b/sql/meta_table.cc
@@ -7,8 +7,6 @@
 #include <stdint.h>
 
 #include "base/check_op.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_util.h"
 #include "sql/database.h"
 #include "sql/statement.h"
 #include "sql/transaction.h"
@@ -20,37 +18,6 @@
 const char kCompatibleVersionKey[] = "last_compatible_version";
 const char kMmapStatusKey[] = "mmap_status";
 
-// Used to track success/failure of deprecation checks.
-enum DeprecationEventType {
-  // Database has info, but no meta table.  This is probably bad.
-  DEPRECATION_DATABASE_NOT_EMPTY = 0,
-
-  // No meta, unable to query sqlite_master.  This is probably bad.
-  DEPRECATION_DATABASE_UNKNOWN,
-
-  // Failure querying meta table, corruption or similar problem likely.
-  DEPRECATION_FAILED_VERSION,
-
-  // Version key not found in meta table.  Some sort of update error likely.
-  DEPRECATION_NO_VERSION,
-
-  // Version was out-dated, database successfully razed.  Should only
-  // happen once per long-idle user, low volume expected.
-  DEPRECATION_RAZED,
-
-  // Version was out-dated, database raze failed.  This user's
-  // database will be stuck.
-  DEPRECATION_RAZE_FAILED,
-
-  // Always keep this at the end.
-  DEPRECATION_EVENT_MAX,
-};
-
-void RecordDeprecationEvent(DeprecationEventType deprecation_event) {
-  UMA_HISTOGRAM_ENUMERATION("Sqlite.DeprecationVersionResult",
-                            deprecation_event, DEPRECATION_EVENT_MAX);
-}
-
 }  // namespace
 
 namespace sql {
@@ -99,47 +66,22 @@
   DCHECK_GT(deprecated_version, 0);
   DCHECK_EQ(0, db->transaction_nesting());
 
-  if (!DoesTableExist(db)) {
-    sql::Statement s(db->GetUniqueStatement(
-        "SELECT COUNT(*) FROM sqlite_master"));
-    if (s.Step()) {
-      if (s.ColumnInt(0) != 0) {
-        RecordDeprecationEvent(DEPRECATION_DATABASE_NOT_EMPTY);
-      }
-      // NOTE(shess): Empty database at first run is expected, so
-      // don't histogram that case.
-    } else {
-      RecordDeprecationEvent(DEPRECATION_DATABASE_UNKNOWN);
-    }
+  if (!DoesTableExist(db))
     return;
-  }
 
   // TODO(shess): Share sql with PrepareGetStatement().
   sql::Statement s(db->GetUniqueStatement(
                        "SELECT value FROM meta WHERE key=?"));
   s.BindCString(0, kVersionKey);
-  if (!s.Step()) {
-    if (!s.Succeeded()) {
-      RecordDeprecationEvent(DEPRECATION_FAILED_VERSION);
-    } else {
-      RecordDeprecationEvent(DEPRECATION_NO_VERSION);
-    }
+  if (!s.Step())
     return;
-  }
 
   int version = s.ColumnInt(0);
   s.Clear();  // Clear potential automatic transaction for Raze().
   if (version <= deprecated_version) {
-    if (db->Raze()) {
-      RecordDeprecationEvent(DEPRECATION_RAZED);
-    } else {
-      RecordDeprecationEvent(DEPRECATION_RAZE_FAILED);
-    }
+    db->Raze();
     return;
   }
-
-  // NOTE(shess): Successfully getting a version which is not
-  // deprecated is expected, so don't histogram that case.
 }
 
 bool MetaTable::Init(Database* db, int version, int compatible_version) {
@@ -158,8 +100,10 @@
 
   if (!DoesTableExist(db)) {
     if (!db_->Execute("CREATE TABLE meta"
-        "(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR)"))
+                      "(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value "
+                      "LONGVARCHAR)")) {
       return false;
+    }
 
     // Newly-created databases start out with mmap'ed I/O, but have no place to
     // store the setting.  Set here so that later opens don't need to validate.
@@ -170,8 +114,6 @@
     // there, we should create an index.
     SetVersionNumber(version);
     SetCompatibleVersionNumber(compatible_version);
-  } else {
-    db_->AddTaggedHistogram("Sqlite.Version", GetVersionNumber());
   }
   return transaction.Commit();
 }
diff --git a/sql/recovery.cc b/sql/recovery.cc
index 67d1116..47223c09 100644
--- a/sql/recovery.cc
+++ b/sql/recovery.cc
@@ -6,11 +6,16 @@
 
 #include <stddef.h>
 
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/check_op.h"
 #include "base/files/file_path.h"
 #include "base/format_macros.h"
 #include "base/logging.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
+#include "base/notreached.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "sql/database.h"
@@ -20,127 +25,6 @@
 
 namespace sql {
 
-namespace {
-
-// This enum must match the numbering for Sqlite.RecoveryEvents in
-// histograms.xml.  Do not reorder or remove items, only add new items before
-// RECOVERY_EVENT_MAX.
-enum RecoveryEventType {
-  // Init() completed successfully.
-  RECOVERY_SUCCESS_INIT = 0,
-
-  // Failed to open temporary database to recover into.
-  RECOVERY_FAILED_OPEN_TEMPORARY,
-
-  // Failed to initialize recover vtable system.
-  RECOVERY_FAILED_VIRTUAL_TABLE_INIT,
-
-  // System SQLite doesn't support vtable.
-  // This is deprecated. Chrome doesn't support using the system SQLite anymore.
-  DEPRECATED_RECOVERY_FAILED_VIRTUAL_TABLE_SYSTEM_SQLITE,
-
-  // Failed attempting to enable writable_schema.
-  RECOVERY_FAILED_WRITABLE_SCHEMA,
-
-  // Failed to attach the corrupt database to the temporary database.
-  RECOVERY_FAILED_ATTACH,
-
-  // Backup() successfully completed.
-  RECOVERY_SUCCESS_BACKUP,
-
-  // Failed sqlite3_backup_init().  Error code in Sqlite.RecoveryHandle.
-  RECOVERY_FAILED_BACKUP_INIT,
-
-  // Failed sqlite3_backup_step().  Error code in Sqlite.RecoveryStep.
-  RECOVERY_FAILED_BACKUP_STEP,
-
-  // AutoRecoverTable() successfully completed.
-  RECOVERY_SUCCESS_AUTORECOVER,
-
-  // The target table contained a type which the code is not equipped
-  // to handle.  This should only happen if things are fubar.
-  RECOVERY_FAILED_AUTORECOVER_UNRECOGNIZED_TYPE,
-
-  // The target table does not exist.
-  RECOVERY_FAILED_AUTORECOVER_MISSING_TABLE,
-
-  // The recovery virtual table creation failed.
-  RECOVERY_FAILED_AUTORECOVER_CREATE,
-
-  // Copying data from the recovery table to the target table failed.
-  RECOVERY_FAILED_AUTORECOVER_INSERT,
-
-  // Dropping the recovery virtual table failed.
-  RECOVERY_FAILED_AUTORECOVER_DROP,
-
-  // SetupMeta() successfully completed.
-  RECOVERY_SUCCESS_SETUP_META,
-
-  // Failure creating recovery meta table.
-  RECOVERY_FAILED_META_CREATE,
-
-  // GetMetaVersionNumber() successfully completed.
-  RECOVERY_SUCCESS_META_VERSION,
-
-  // Failed in querying recovery meta table.
-  RECOVERY_FAILED_META_QUERY,
-
-  // No version key in recovery meta table.
-  RECOVERY_FAILED_META_NO_VERSION,
-
-  // Automatically recovered entire database successfully.
-  RECOVERY_SUCCESS_AUTORECOVERDB,
-
-  // Database was so broken recovery couldn't be entered.
-  RECOVERY_FAILED_AUTORECOVERDB_BEGIN,
-
-  // Failed to schema from corrupt database.
-  RECOVERY_FAILED_AUTORECOVERDB_SCHEMASELECT,
-
-  // Failed to create copy of schema in recovery database.
-  RECOVERY_FAILED_AUTORECOVERDB_SCHEMACREATE,
-
-  // Failed querying tables to recover.  Should be impossible.
-  RECOVERY_FAILED_AUTORECOVERDB_NAMESELECT,
-
-  // Failed to recover an individual table.
-  RECOVERY_FAILED_AUTORECOVERDB_TABLE,
-
-  // Failed to recover [sqlite_sequence] table.
-  RECOVERY_FAILED_AUTORECOVERDB_SEQUENCE,
-
-  // Failed to recover triggers or views or virtual tables.
-  RECOVERY_FAILED_AUTORECOVERDB_AUX,
-
-  // After SQLITE_NOTADB failure setting up for recovery, Delete() failed.
-  RECOVERY_FAILED_AUTORECOVERDB_NOTADB_DELETE,
-
-  // After SQLITE_NOTADB failure setting up for recovery, Delete() succeeded
-  // then Open() failed.
-  RECOVERY_FAILED_AUTORECOVERDB_NOTADB_REOPEN,
-
-  // After SQLITE_NOTADB failure setting up for recovery, Delete() and Open()
-  // succeeded, then querying the database failed.
-  RECOVERY_FAILED_AUTORECOVERDB_NOTADB_QUERY,
-
-  // After SQLITE_NOTADB failure setting up for recovery, the database was
-  // successfully deleted.
-  RECOVERY_SUCCESS_AUTORECOVERDB_NOTADB_DELETE,
-
-  // Failed to find required [meta.version] information.
-  RECOVERY_FAILED_AUTORECOVERDB_META_VERSION,
-
-  // Add new items before this one, always keep this one at the end.
-  RECOVERY_EVENT_MAX,
-};
-
-void RecordRecoveryEvent(RecoveryEventType recovery_event) {
-  UMA_HISTOGRAM_ENUMERATION("Sqlite.RecoveryEvents",
-                            recovery_event, RECOVERY_EVENT_MAX);
-}
-
-}  // namespace
-
 // static
 std::unique_ptr<Recovery> Recovery::Begin(Database* database,
                                           const base::FilePath& db_path) {
@@ -178,8 +62,7 @@
 
 // static
 void Recovery::Rollback(std::unique_ptr<Recovery> r) {
-  // TODO(shess): HISTOGRAM to track?  Or just have people crash out?
-  // Crash and dump?
+  // TODO(shess): Crash / crash and dump?
   r->Shutdown(POISON);
 }
 
@@ -230,15 +113,12 @@
   // possible to fall back to a memory database.  But it probably
   // implies that the SQLite tmpdir logic is busted, which could cause
   // a variety of other random issues in our code.
-  if (!recover_db_.OpenTemporary()) {
-    RecordRecoveryEvent(RECOVERY_FAILED_OPEN_TEMPORARY);
+  if (!recover_db_.OpenTemporary())
     return false;
-  }
 
   // Enable the recover virtual table for this connection.
   int rc = EnableRecoveryExtension(&recover_db_, InternalApiToken());
   if (rc != SQLITE_OK) {
-    RecordRecoveryEvent(RECOVERY_FAILED_VIRTUAL_TABLE_INIT);
     LOG(ERROR) << "Failed to initialize recover module: "
                << recover_db_.GetErrorMessage();
     return false;
@@ -246,19 +126,12 @@
 
   // Turn on |SQLITE_RecoveryMode| for the handle, which allows
   // reading certain broken databases.
-  if (!recover_db_.Execute("PRAGMA writable_schema=1")) {
-    RecordRecoveryEvent(RECOVERY_FAILED_WRITABLE_SCHEMA);
+  if (!recover_db_.Execute("PRAGMA writable_schema=1"))
     return false;
-  }
 
-  if (!recover_db_.AttachDatabase(db_path, "corrupt", InternalApiToken())) {
-    RecordRecoveryEvent(RECOVERY_FAILED_ATTACH);
-    base::UmaHistogramSparse("Sqlite.RecoveryAttachError",
-                             recover_db_.GetErrorCode());
+  if (!recover_db_.AttachDatabase(db_path, "corrupt", InternalApiToken()))
     return false;
-  }
 
-  RecordRecoveryEvent(RECOVERY_SUCCESS_INIT);
   return true;
 }
 
@@ -293,8 +166,7 @@
   // deletes the database file, the code could then re-open the file
   // and attempt the backup again.
   //
-  // For now, this code attempts a best effort and records histograms
-  // to inform future development.
+  // For now, this code attempts a best effort.
 
   // Backup the original db from the recovered db.
   const char* kMain = "main";
@@ -302,11 +174,7 @@
       sqlite3_backup_init(db_->db(InternalApiToken()), kMain,
                           recover_db_.db(InternalApiToken()), kMain);
   if (!backup) {
-    RecordRecoveryEvent(RECOVERY_FAILED_BACKUP_INIT);
-
     // Error code is in the destination database handle.
-    int err = sqlite3_extended_errcode(db_->db(InternalApiToken()));
-    base::UmaHistogramSparse("Sqlite.RecoveryHandle", err);
     LOG(ERROR) << "sqlite3_backup_init() failed: "
                << sqlite3_errmsg(db_->db(InternalApiToken()));
 
@@ -324,8 +192,6 @@
   DCHECK_GT(pages, 0);
 
   if (rc != SQLITE_DONE) {
-    RecordRecoveryEvent(RECOVERY_FAILED_BACKUP_STEP);
-    base::UmaHistogramSparse("Sqlite.RecoveryStep", rc);
     LOG(ERROR) << "sqlite3_backup_step() failed: "
                << sqlite3_errmsg(db_->db(InternalApiToken()));
   }
@@ -343,9 +209,8 @@
     return false;
   }
 
-  // TODO(shess): For now, leave the original database alone, pending
-  // results from Sqlite.RecoveryStep.  Some errors should probably
-  // route to RAZE_AND_POISON.
+  // TODO(shess): For now, leave the original database alone. Some errors should
+  // probably route to RAZE_AND_POISON.
   if (rc != SQLITE_DONE) {
     Shutdown(POISON);
     return false;
@@ -353,7 +218,6 @@
 
   // Clean up the recovery db, and terminate the main database
   // connection.
-  RecordRecoveryEvent(RECOVERY_SUCCESS_BACKUP);
   Shutdown(POISON);
   return true;
 }
@@ -440,7 +304,6 @@
       // - other -> "NUMERIC"
       // Just code those in as they come up.
       NOTREACHED() << " Unsupported type " << column_type;
-      RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVER_UNRECOGNIZED_TYPE);
       return false;
     }
 
@@ -462,7 +325,6 @@
 
   // Receiving no column information implies that the table doesn't exist.
   if (create_column_decls.empty()) {
-    RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVER_MISSING_TABLE);
     return false;
   }
 
@@ -487,13 +349,10 @@
   std::string recover_drop(base::StringPrintf(
       "DROP TABLE temp.recover_%s", table_name));
 
-  if (!db()->Execute(recover_create.c_str())) {
-    RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVER_CREATE);
+  if (!db()->Execute(recover_create.c_str()))
     return false;
-  }
 
   if (!db()->Execute(recover_insert.c_str())) {
-    RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVER_INSERT);
     ignore_result(db()->Execute(recover_drop.c_str()));
     return false;
   }
@@ -501,28 +360,19 @@
   *rows_recovered = db()->GetLastChangeCount();
 
   // TODO(shess): Is leaving the recover table around a breaker?
-  if (!db()->Execute(recover_drop.c_str())) {
-    RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVER_DROP);
-    return false;
-  }
-  RecordRecoveryEvent(RECOVERY_SUCCESS_AUTORECOVER);
-  return true;
+  return db()->Execute(recover_drop.c_str());
 }
 
 bool Recovery::SetupMeta() {
+  // clang-format off
   static const char kCreateSql[] =
-      "CREATE VIRTUAL TABLE temp.recover_meta USING recover"
-      "("
-      "corrupt.meta,"
-      "key TEXT NOT NULL,"
-      "value ANY"  // Whatever is stored.
+      "CREATE VIRTUAL TABLE temp.recover_meta USING recover("
+         "corrupt.meta,"
+         "key TEXT NOT NULL,"
+         "value ANY"  // Whatever is stored.
       ")";
-  if (!db()->Execute(kCreateSql)) {
-    RecordRecoveryEvent(RECOVERY_FAILED_META_CREATE);
-    return false;
-  }
-  RecordRecoveryEvent(RECOVERY_SUCCESS_SETUP_META);
-  return true;
+  // clang-format on
+  return db()->Execute(kCreateSql);
 }
 
 bool Recovery::GetMetaVersionNumber(int* version) {
@@ -534,16 +384,9 @@
   static const char kVersionSql[] =
       "SELECT value FROM temp.recover_meta WHERE key = 'version'";
   sql::Statement recovery_version(db()->GetUniqueStatement(kVersionSql));
-  if (!recovery_version.Step()) {
-    if (!recovery_version.Succeeded()) {
-      RecordRecoveryEvent(RECOVERY_FAILED_META_QUERY);
-    } else {
-      RecordRecoveryEvent(RECOVERY_FAILED_META_NO_VERSION);
-    }
+  if (!recovery_version.Step())
     return false;
-  }
 
-  RecordRecoveryEvent(RECOVERY_SUCCESS_META_VERSION);
   *version = recovery_version.ColumnInt(0);
   return true;
 }
@@ -574,16 +417,10 @@
       continue;
 
     sql.insert(prefix_len, "main.");
-    if (!db->Execute(sql.c_str())) {
-      RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_SCHEMACREATE);
+    if (!db->Execute(sql.c_str()))
       return false;
-    }
   }
-  if (!s.Succeeded()) {
-    RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_SCHEMASELECT);
-    return false;
-  }
-  return true;
+  return s.Succeeded();
 }
 
 }  // namespace
@@ -594,8 +431,7 @@
 //
 // TODO(shess): This conservatively uses Rollback() rather than Unrecoverable().
 // With Rollback(), it is expected that the database will continue to generate
-// errors.  Change the failure cases to Unrecoverable() if/when histogram
-// results indicate that everything is working reasonably.
+// errors. Change the failure cases to Unrecoverable().
 //
 // static
 std::unique_ptr<Recovery> Recovery::BeginRecoverDatabase(
@@ -608,15 +444,16 @@
     // against a database when exclusive locking is set.
     db->Poison();
 
-    // Histograms from Recovery::Begin() show all current failures are in
-    // attaching the corrupt database, with 2/3 being SQLITE_NOTADB.  Don't
-    // delete the database except for that specific failure case.
+    // When this code was written, histograms showed that most failures happened
+    // while attaching a corrupt database. In this case, a large proportion of
+    // attachment failures were SQLITE_NOTADB.
+    //
+    // We currently only delete the database in that specific failure case.
     {
       Database probe_db;
       if (!probe_db.OpenInMemory() ||
           probe_db.AttachDatabase(db_path, "corrupt", InternalApiToken()) ||
           probe_db.GetErrorCode() != SQLITE_NOTADB) {
-        RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_BEGIN);
         return nullptr;
       }
     }
@@ -624,29 +461,23 @@
     // The database has invalid data in the SQLite header, so it is almost
     // certainly not recoverable without manual intervention (and likely not
     // recoverable _with_ manual intervention).  Clear away the broken database.
-    if (!sql::Database::Delete(db_path)) {
-      RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_NOTADB_DELETE);
+    if (!sql::Database::Delete(db_path))
       return nullptr;
-    }
 
     // Windows deletion is complicated by file scanners and malware - sometimes
     // Delete() appears to succeed, even though the file remains.  The following
     // attempts to track if this happens often enough to cause concern.
     {
       Database probe_db;
-      if (!probe_db.Open(db_path)) {
-        RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_NOTADB_REOPEN);
+      if (!probe_db.Open(db_path))
         return nullptr;
-      }
-      if (!probe_db.Execute("PRAGMA auto_vacuum")) {
-        RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_NOTADB_QUERY);
+
+      if (!probe_db.Execute("PRAGMA auto_vacuum"))
         return nullptr;
-      }
     }
 
     // The rest of the recovery code could be run on the re-opened database, but
     // the database is empty, so there would be no point.
-    RecordRecoveryEvent(RECOVERY_SUCCESS_AUTORECOVERDB_NOTADB_DELETE);
     return nullptr;
   }
 
@@ -693,13 +524,11 @@
       const std::string name = s.ColumnString(0);
       size_t rows_recovered;
       if (!recovery->AutoRecoverTable(name.c_str(), &rows_recovered)) {
-        RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_TABLE);
         Recovery::Rollback(std::move(recovery));
         return nullptr;
       }
     }
     if (!s.Succeeded()) {
-      RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_NAMESELECT);
       Recovery::Rollback(std::move(recovery));
       return nullptr;
     }
@@ -710,7 +539,6 @@
     ignore_result(recovery->db()->Execute("DELETE FROM main.sqlite_sequence"));
     size_t rows_recovered;
     if (!recovery->AutoRecoverTable("sqlite_sequence", &rows_recovered)) {
-      RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_SEQUENCE);
       Recovery::Rollback(std::move(recovery));
       return nullptr;
     }
@@ -723,20 +551,16 @@
       "SELECT type, name, tbl_name, rootpage, sql "
       "FROM corrupt.sqlite_master WHERE type='view' OR type='trigger'";
   if (!recovery->db()->Execute(kCreateMetaItemsSql)) {
-    RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_AUX);
     Recovery::Rollback(std::move(recovery));
     return nullptr;
   }
 
-  RecordRecoveryEvent(RECOVERY_SUCCESS_AUTORECOVERDB);
   return recovery;
 }
 
 void Recovery::RecoverDatabase(Database* db, const base::FilePath& db_path) {
   std::unique_ptr<sql::Recovery> recovery = BeginRecoverDatabase(db, db_path);
 
-  // ignore_result() because BeginRecoverDatabase() and Recovered() already
-  // provide suitable histogram coverage.
   if (recovery)
     ignore_result(Recovery::Recovered(std::move(recovery)));
 }
@@ -750,12 +574,9 @@
   int version = 0;
   if (!recovery->SetupMeta() || !recovery->GetMetaVersionNumber(&version)) {
     sql::Recovery::Unrecoverable(std::move(recovery));
-    RecordRecoveryEvent(RECOVERY_FAILED_AUTORECOVERDB_META_VERSION);
     return;
   }
 
-  // ignore_result() because BeginRecoverDatabase() and Recovered() already
-  // provide suitable histogram coverage.
   ignore_result(Recovery::Recovered(std::move(recovery)));
 }
 
diff --git a/sql/recovery_unittest.cc b/sql/recovery_unittest.cc
index f402907..d5c541b 100644
--- a/sql/recovery_unittest.cc
+++ b/sql/recovery_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/test/metrics/histogram_tester.h"
 #include "sql/database.h"
 #include "sql/meta_table.h"
 #include "sql/statement.h"
@@ -902,7 +901,6 @@
   EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectTableIdSql, "|", ","));
 }
 
-// Test histograms recorded when the invalid database cannot be attached.
 TEST_F(SQLRecoveryTest, AttachFailure) {
   // Create a valid database, then write junk over the header.  This should lead
   // to SQLITE_NOTADB, which will cause ATTACH to fail.
@@ -911,11 +909,6 @@
   db_.Close();
   ASSERT_TRUE(OverwriteDatabaseHeader());
 
-  static const char kEventHistogramName[] = "Sqlite.RecoveryEvents";
-  const int kEventEnum = 5;  // RECOVERY_FAILED_ATTACH
-  static const char kErrorHistogramName[] = "Sqlite.RecoveryAttachError";
-  base::HistogramTester tester;
-
   {
     sql::test::ScopedErrorExpecter expecter;
     expecter.ExpectError(SQLITE_NOTADB);
@@ -925,14 +918,10 @@
 
     // Begin() should fail.
     std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
-    ASSERT_FALSE(recovery.get());
+    EXPECT_FALSE(recovery.get());
 
     ASSERT_TRUE(expecter.SawExpectedErrors());
   }
-
-  // Verify that the failure was in the right place with the expected code.
-  tester.ExpectBucketCount(kEventHistogramName, kEventEnum, 1);
-  tester.ExpectBucketCount(kErrorHistogramName, SQLITE_NOTADB, 1);
 }
 
 // Helper for SQLRecoveryTest.PageSize.  Creates a fresh db based on db_prefix,
diff --git a/storage/browser/database/database_quota_client_unittest.cc b/storage/browser/database/database_quota_client_unittest.cc
index 203e3541..117c506 100644
--- a/storage/browser/database/database_quota_client_unittest.cc
+++ b/storage/browser/database/database_quota_client_unittest.cc
@@ -27,6 +27,8 @@
 #include "storage/browser/database/database_tracker.h"
 #include "storage/browser/database/database_util.h"
 #include "storage/browser/quota/quota_client.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
+#include "storage/browser/quota/special_storage_policy.h"
 #include "storage/common/database/database_identifier.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -40,12 +42,15 @@
 static const blink::mojom::StorageType kTemp =
     blink::mojom::StorageType::kTemporary;
 
-// Mock tracker class the mocks up those methods of the tracker
-// that are used by the QuotaClient.
+// Mocks DatabaseTracker methods used by DatabaseQuotaClient.
 class MockDatabaseTracker : public DatabaseTracker {
  public:
   MockDatabaseTracker()
-      : DatabaseTracker(base::FilePath(), false, nullptr, nullptr) {}
+      : DatabaseTracker(base::FilePath(),
+                        /*is_incognito=*/false,
+                        /*special_storage_policy=*/nullptr,
+                        /*quota_manager_proxy=*/nullptr,
+                        DatabaseTracker::CreatePassKey()) {}
 
   bool GetOriginInfo(const std::string& origin_identifier,
                      OriginInfo* info) override {
diff --git a/storage/browser/database/database_tracker.cc b/storage/browser/database/database_tracker.cc
index 0203175..45a4dc9 100644
--- a/storage/browser/database/database_tracker.cc
+++ b/storage/browser/database/database_tracker.cc
@@ -8,17 +8,23 @@
 
 #include <algorithm>
 #include <memory>
+#include <string>
+#include <utility>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/files/file_enumerator.h"
+#include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/metrics/user_metrics.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
 #include "base/task/thread_pool.h"
 #include "base/time/time.h"
+#include "base/types/pass_key.h"
 #include "net/base/net_errors.h"
 #include "sql/database.h"
 #include "sql/meta_table.h"
@@ -32,6 +38,7 @@
 #include "storage/common/database/database_identifier.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
 #include "third_party/sqlite/sqlite3.h"
+#include "url/gurl.h"
 #include "url/origin.h"
 
 namespace storage {
@@ -73,10 +80,22 @@
 OriginInfo::OriginInfo(const std::string& origin_identifier, int64_t total_size)
     : origin_identifier_(origin_identifier), total_size_(total_size) {}
 
-DatabaseTracker::DatabaseTracker(const base::FilePath& profile_path,
-                                 bool is_incognito,
-                                 SpecialStoragePolicy* special_storage_policy,
-                                 QuotaManagerProxy* quota_manager_proxy)
+scoped_refptr<DatabaseTracker> DatabaseTracker::Create(
+    const base::FilePath& profile_path,
+    bool is_incognito,
+    scoped_refptr<SpecialStoragePolicy> special_storage_policy,
+    scoped_refptr<QuotaManagerProxy> quota_manager_proxy) {
+  return base::MakeRefCounted<DatabaseTracker>(
+      profile_path, is_incognito, std::move(special_storage_policy),
+      std::move(quota_manager_proxy), base::PassKey<DatabaseTracker>());
+}
+
+DatabaseTracker::DatabaseTracker(
+    const base::FilePath& profile_path,
+    bool is_incognito,
+    scoped_refptr<SpecialStoragePolicy> special_storage_policy,
+    scoped_refptr<QuotaManagerProxy> quota_manager_proxy,
+    base::PassKey<DatabaseTracker>)
     : is_incognito_(is_incognito),
       profile_path_(profile_path),
       db_dir_(is_incognito_
@@ -87,14 +106,14 @@
           .page_size = 4096,
           .cache_size = 500,
       })),
-      special_storage_policy_(special_storage_policy),
-      quota_manager_proxy_(quota_manager_proxy),
+      special_storage_policy_(std::move(special_storage_policy)),
+      quota_manager_proxy_(std::move(quota_manager_proxy)),
       task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
           {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
            base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
-  if (quota_manager_proxy) {
+  if (quota_manager_proxy_) {
     // TODO(crbug.com/1163048): Use mojo and switch to RegisterClient().
-    quota_manager_proxy->RegisterLegacyClient(
+    quota_manager_proxy_->RegisterLegacyClient(
         base::MakeRefCounted<DatabaseQuotaClient>(this),
         QuotaClientType::kDatabase, {blink::mojom::StorageType::kTemporary});
   }
diff --git a/storage/browser/database/database_tracker.h b/storage/browser/database/database_tracker.h
index b8cf349..48c4eae4 100644
--- a/storage/browser/database/database_tracker.h
+++ b/storage/browser/database/database_tracker.h
@@ -19,10 +19,12 @@
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/observer_list.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
+#include "base/types/pass_key.h"
 #include "net/base/completion_once_callback.h"
 #include "storage/browser/database/database_connections.h"
 #include "url/origin.h"
@@ -88,10 +90,21 @@
     virtual ~Observer() = default;
   };
 
+  static scoped_refptr<DatabaseTracker> Create(
+      const base::FilePath& profile_path,
+      bool is_incognito,
+      scoped_refptr<SpecialStoragePolicy> special_storage_policy,
+      scoped_refptr<QuotaManagerProxy> quota_manager_proxy);
+
+  // Exposed for base::MakeRefCounted. Users should call Create().
   DatabaseTracker(const base::FilePath& profile_path,
                   bool is_incognito,
-                  SpecialStoragePolicy* special_storage_policy,
-                  QuotaManagerProxy* quota_manager_proxy);
+                  scoped_refptr<SpecialStoragePolicy> special_storage_policy,
+                  scoped_refptr<QuotaManagerProxy> quota_manager_proxy,
+                  base::PassKey<DatabaseTracker>);
+
+  DatabaseTracker(const DatabaseTracker&) = delete;
+  DatabaseTracker& operator=(const DatabaseTracker&) = delete;
 
   void DatabaseOpened(const std::string& origin_identifier,
                       const std::u16string& database_name,
@@ -177,6 +190,12 @@
 
   base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); }
 
+ protected:
+  // Subclasses need PassKeys to call the constructor.
+  static base::PassKey<DatabaseTracker> CreatePassKey() {
+    return base::PassKey<DatabaseTracker>();
+  }
+
  private:
   friend class base::RefCountedThreadSafe<DatabaseTracker>;
   friend class DatabaseTracker_TestHelper_Test;
diff --git a/storage/browser/database/database_tracker_unittest.cc b/storage/browser/database/database_tracker_unittest.cc
index b4a517f4..748d04a3 100644
--- a/storage/browser/database/database_tracker_unittest.cc
+++ b/storage/browser/database/database_tracker_unittest.cc
@@ -205,13 +205,12 @@
     base::test::TaskEnvironment task_environment;
     base::ScopedTempDir temp_dir;
     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-    scoped_refptr<MockSpecialStoragePolicy> special_storage_policy =
-        new MockSpecialStoragePolicy;
+    auto special_storage_policy =
+        base::MakeRefCounted<MockSpecialStoragePolicy>();
     special_storage_policy->AddProtected(GURL(kOrigin2Url));
-    scoped_refptr<DatabaseTracker> tracker(
-        base::MakeRefCounted<DatabaseTracker>(
-            temp_dir.GetPath(), incognito_mode, special_storage_policy.get(),
-            nullptr));
+    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+        temp_dir.GetPath(), incognito_mode, std::move(special_storage_policy),
+        /*quota_manager_proxy=*/nullptr);
 
     base::RunLoop run_loop;
     tracker->task_runner()->PostTask(
@@ -312,13 +311,12 @@
     base::test::TaskEnvironment task_environment;
     base::ScopedTempDir temp_dir;
     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-    scoped_refptr<MockSpecialStoragePolicy> special_storage_policy =
-        new MockSpecialStoragePolicy;
+    auto special_storage_policy =
+        base::MakeRefCounted<MockSpecialStoragePolicy>();
     special_storage_policy->AddProtected(GURL(kOrigin2Url));
-    scoped_refptr<DatabaseTracker> tracker(
-        base::MakeRefCounted<DatabaseTracker>(
-            temp_dir.GetPath(), incognito_mode, special_storage_policy.get(),
-            nullptr));
+    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+        temp_dir.GetPath(), incognito_mode, std::move(special_storage_policy),
+        /*quota_manager_proxy=*/nullptr);
 
     base::RunLoop run_loop;
     tracker->task_runner()->PostTask(
@@ -465,12 +463,10 @@
     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
 
     // Initialize the tracker with a QuotaManagerProxy
-    scoped_refptr<TestQuotaManagerProxy> test_quota_proxy(
-        new TestQuotaManagerProxy);
-    scoped_refptr<DatabaseTracker> tracker(
-        base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(),
-                                              incognito_mode, nullptr,
-                                              test_quota_proxy.get()));
+    auto test_quota_proxy = base::MakeRefCounted<TestQuotaManagerProxy>();
+    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+        temp_dir.GetPath(), incognito_mode,
+        /*special_storage_policy=*/nullptr, test_quota_proxy);
     base::RunLoop run_loop;
     tracker->task_runner()->PostTask(
         FROM_HERE, base::BindLambdaForTesting([&]() {
@@ -595,13 +591,12 @@
     base::FilePath origin1_db_dir;
     base::FilePath origin2_db_dir;
     {
-      scoped_refptr<MockSpecialStoragePolicy> special_storage_policy =
-          new MockSpecialStoragePolicy;
+      auto special_storage_policy =
+          base::MakeRefCounted<MockSpecialStoragePolicy>();
       special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
-      scoped_refptr<DatabaseTracker> tracker(
-          base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), false,
-                                                special_storage_policy.get(),
-                                                nullptr));
+      scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+          temp_dir.GetPath(), false, std::move(special_storage_policy),
+          /*quota_manager_proxy=*/nullptr);
       base::RunLoop run_loop;
       tracker->task_runner()->PostTask(
           FROM_HERE, base::BindLambdaForTesting([&]() {
@@ -646,9 +641,9 @@
     }
 
     // At this point, the database tracker should be gone. Create a new one.
-    scoped_refptr<DatabaseTracker> tracker(
-        base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), false,
-                                              nullptr, nullptr));
+    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+        temp_dir.GetPath(), /*is_incognito=*/false,
+        /*special_storage_policy=*/nullptr, /*quota_manager_proxy=*/nullptr);
     base::RunLoop run_loop;
     tracker->task_runner()->PostTask(
         FROM_HERE, base::BindLambdaForTesting([&]() {
@@ -690,13 +685,12 @@
     base::FilePath origin1_db_dir;
     base::FilePath origin2_db_dir;
     {
-      scoped_refptr<MockSpecialStoragePolicy> special_storage_policy =
-          new MockSpecialStoragePolicy;
+      auto special_storage_policy =
+          base::MakeRefCounted<MockSpecialStoragePolicy>();
       special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
-      scoped_refptr<DatabaseTracker> tracker(
-          base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), false,
-                                                special_storage_policy.get(),
-                                                nullptr));
+      scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+          temp_dir.GetPath(), false, std::move(special_storage_policy),
+          /*quota_manager_proxy=*/nullptr);
       base::RunLoop run_loop;
       tracker->task_runner()->PostTask(
           FROM_HERE, base::BindLambdaForTesting([&]() {
@@ -743,9 +737,9 @@
     }
 
     // At this point, the database tracker should be gone. Create a new one.
-    scoped_refptr<DatabaseTracker> tracker(
-        base::MakeRefCounted<DatabaseTracker>(temp_dir.GetPath(), false,
-                                              nullptr, nullptr));
+    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+        temp_dir.GetPath(), false, /*special_storage_policy=*/nullptr,
+        /*quota_manager_proxy=*/nullptr);
     base::RunLoop run_loop;
     tracker->task_runner()->PostTask(
         FROM_HERE, base::BindLambdaForTesting([&]() {
@@ -780,9 +774,9 @@
     base::test::TaskEnvironment task_environment;
     base::ScopedTempDir temp_dir;
     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-    scoped_refptr<DatabaseTracker> tracker(
-        base::MakeRefCounted<DatabaseTracker>(
-            temp_dir.GetPath(), kUseInMemoryTrackerDatabase, nullptr, nullptr));
+    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+        temp_dir.GetPath(), kUseInMemoryTrackerDatabase,
+        /*special_storage_policy=*/nullptr, /*quota_manager_proxy=*/nullptr);
     base::RunLoop run_loop;
     tracker->task_runner()->PostTask(
         FROM_HERE, base::BindLambdaForTesting([&]() {
@@ -836,9 +830,9 @@
     base::test::TaskEnvironment task_environment;
     base::ScopedTempDir temp_dir;
     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-    scoped_refptr<DatabaseTracker> tracker(
-        base::MakeRefCounted<DatabaseTracker>(
-            temp_dir.GetPath(), kUseInMemoryTrackerDatabase, nullptr, nullptr));
+    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
+        temp_dir.GetPath(), kUseInMemoryTrackerDatabase,
+        /*special_storage_policy=*/nullptr, /*quota_manager_proxy=*/nullptr);
     base::RunLoop run_loop;
     tracker->task_runner()->PostTask(
         FROM_HERE, base::BindLambdaForTesting([&]() {
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index 05f81ce..8e0fca4d 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -12056,6 +12056,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -13772,6 +13794,29 @@
       },
       {
         "args": [
+          "--enable-features=ProcessHostOnUI",
+          "--test-launcher-print-test-stdio=always"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
+        "args": [
           "--test-launcher-print-test-stdio=always"
         ],
         "merge": {
@@ -15604,6 +15649,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -17209,6 +17276,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ],
+          "service_account": "chrome-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18813,6 +18902,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -20420,6 +20531,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -22042,6 +22175,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 49709b1..090333c1 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -53028,6 +53028,29 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -59909,6 +59932,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -61927,6 +61972,29 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "isolate_profile_data": true,
         "merge": {
           "args": [],
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index ad2cee67..c5e1edc 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -5636,6 +5636,49 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "context_lost_passthrough_tests",
+        "resultdb": {
+          "enable": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
@@ -5855,6 +5898,58 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle --force-online-connection-state-for-indicator --disable-wcg-for-test",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "maps_pixel_passthrough_test",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force-online-connection-state-for-indicator --disable-wcg-for-test",
           "--dont-restore-color-profile-after-test",
           "--test-machine-name",
@@ -5993,6 +6088,58 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle --force-online-connection-state-for-indicator --disable-wcg-for-test",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "pixel_skia_gold_passthrough_test",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force-online-connection-state-for-indicator --disable-wcg-for-test",
           "--dont-restore-color-profile-after-test",
           "--test-machine-name",
@@ -6045,6 +6192,50 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle --force-online-connection-state-for-indicator --disable-wcg-for-test",
+          "--dont-restore-color-profile-after-test"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "screenshot_sync_passthrough_tests",
+        "resultdb": {
+          "enable": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force-online-connection-state-for-indicator --disable-wcg-for-test",
           "--dont-restore-color-profile-after-test"
         ],
@@ -25887,6 +26078,49 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "context_lost_passthrough_tests",
+        "resultdb": {
+          "enable": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating"
         ],
         "isolate_name": "telemetry_gpu_integration_test",
@@ -26106,6 +26340,58 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle --force-online-connection-state-for-indicator --disable-wcg-for-test",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "maps_pixel_passthrough_test",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force-online-connection-state-for-indicator --disable-wcg-for-test",
           "--dont-restore-color-profile-after-test",
           "--test-machine-name",
@@ -26244,6 +26530,58 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle --force-online-connection-state-for-indicator --disable-wcg-for-test",
+          "--dont-restore-color-profile-after-test",
+          "--test-machine-name",
+          "${buildername}",
+          "--git-revision=${got_revision}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "pixel_skia_gold_passthrough_test",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force-online-connection-state-for-indicator --disable-wcg-for-test",
           "--dont-restore-color-profile-after-test",
           "--test-machine-name",
@@ -26296,6 +26634,50 @@
           "--browser=android-chromium",
           "--passthrough",
           "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle --force-online-connection-state-for-indicator --disable-wcg-for-test",
+          "--dont-restore-color-profile-after-test"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "screenshot_sync_passthrough_tests",
+        "resultdb": {
+          "enable": true
+        },
+        "should_retry_with_patch": false,
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "containment_type": "AUTO",
+          "dimension_sets": [
+            {
+              "device_os": "R",
+              "device_os_type": "userdebug",
+              "device_type": "flame",
+              "os": "Android",
+              "pool": "chromium.tests.gpu"
+            }
+          ],
+          "idempotent": false,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "--passthrough",
+          "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force-online-connection-state-for-indicator --disable-wcg-for-test",
           "--dont-restore-color-profile-after-test"
         ],
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 7a5e2ab..c55fbe4 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -10164,6 +10164,29 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -12247,6 +12270,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -14154,6 +14199,30 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04",
+              "pool": "chromium.tests.robocrop"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -16507,6 +16576,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -18539,6 +18630,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-14.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -20553,6 +20666,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-16.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 739ac15..a29a496 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -18522,6 +18522,28 @@
         "test_id_prefix": "ninja://content/test:content_browsertests/"
       },
       {
+        "args": [
+          "--enable-features=ProcessHostOnUI"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "process_host_on_ui_content_browsertests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 10
+        },
+        "test": "content_browsertests",
+        "test_id_prefix": "ninja://content/test:content_browsertests/"
+      },
+      {
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index aefd12f..d7a82cbb 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1901,6 +1901,24 @@
     },
   },
   'maps_pixel_passthrough_test': {
+    'modifications': {
+      'Android FYI Release (Pixel 4)': {
+        'args': [
+          # Pixel 4s are weird in that they can output in different color spaces
+          # simultaneously. The readback code for capturing a screenshot assumes
+          # only one color space, so disable wide color gamut for the test to
+          # work around the issue. See https://crbug.com/1166379 for more
+          # information.
+          '--extra-browser-args=--disable-wcg-for-test',
+        ],
+      },
+      'Optional Android Release (Pixel 4)': {
+        'args': [
+          # See above.
+          '--extra-browser-args=--disable-wcg-for-test',
+        ],
+      },
+    },
     'replacements': {
       # The V8 builders pass the V8 revision for ${got_revision}, so instead
       # use ${got_cr_revision}, which is only set on the V8 bots.
@@ -2401,6 +2419,24 @@
     },
   },
   'pixel_skia_gold_passthrough_test': {
+    'modifications': {
+      'Android FYI Release (Pixel 4)': {
+        'args': [
+          # Pixel 4s are weird in that they can output in different color spaces
+          # simultaneously. The readback code for capturing a screenshot assumes
+          # only one color space, so disable wide color gamut for the test to
+          # work around the issue. See https://crbug.com/1166379 for more
+          # information.
+          '--extra-browser-args=--disable-wcg-for-test',
+        ],
+      },
+      'Optional Android Release (Pixel 4)': {
+        'args': [
+          # See above.
+          '--extra-browser-args=--disable-wcg-for-test',
+        ],
+      },
+    },
     'replacements': {
       # The V8 builders pass the V8 revision for ${got_revision}, so instead
       # use ${got_cr_revision}, which is only set on the V8 bots.
@@ -2535,6 +2571,26 @@
       'android-asan',  # https://crbug.com/962650
     ],
   },
+  'screenshot_sync_passthrough_tests': {
+    'modifications': {
+      'Android FYI Release (Pixel 4)': {
+        'args': [
+          # Pixel 4s are weird in that they can output in different color spaces
+          # simultaneously. The readback code for capturing a screenshot assumes
+          # only one color space, so disable wide color gamut for the test to
+          # work around the issue. See https://crbug.com/1166379 for more
+          # information.
+          '--extra-browser-args=--disable-wcg-for-test',
+        ],
+      },
+      'Optional Android Release (Pixel 4)': {
+        'args': [
+          # See above.
+          '--extra-browser-args=--disable-wcg-for-test',
+        ],
+      },
+    },
+  },
   'screenshot_sync_tests': {
     'remove_from': [
       'Fuchsia x64' # https://crbug.com/1203236
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 466f222..0016dec 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -4715,6 +4715,18 @@
       },
     },
 
+    'process_host_on_ui_gtests': {
+      'process_host_on_ui_content_browsertests': {
+        'args': [
+          '--enable-features=ProcessHostOnUI',
+        ],
+        'swarming': {
+          'shards': 10,
+        },
+        'test': 'content_browsertests',
+      },
+    },
+
     # TODO(dpranke): These are run on the p/chromium waterfall; they should
     # probably be run on other builders, and we should get rid of the p/chromium
     # waterfall.
@@ -5827,6 +5839,7 @@
       'linux_specific_xr_gtests',
       'non_android_and_cast_and_chromeos_chromium_gtests',
       'non_android_chromium_gtests',
+      'process_host_on_ui_gtests',
       'vr_platform_specific_chromium_gtests',
       'weblayer_gtests',
     ],
@@ -6630,6 +6643,7 @@
       'gpu_common_and_optional_telemetry_tests',
       'gpu_mediapipe_passthrough_telemetry_tests',
       'gpu_mediapipe_validating_telemetry_tests',
+      'gpu_passthrough_telemetry_tests',
       'gpu_validating_telemetry_tests',
       'gpu_webcodecs_telemetry_test',
       'gpu_webgl_conformance_gles_passthrough_telemetry_tests',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index c37197f..5a801a17 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -6782,6 +6782,27 @@
             ]
         }
     ],
+    "SafeBrowsingBetterTelemetryAcrossReports": [
+        {
+            "platforms": [
+                "android",
+                "android_weblayer",
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "SafeBrowsingBetterTelemetryAcrossReports"
+                    ]
+                }
+            ]
+        }
+    ],
     "SafeBrowsingCSDRequestWithToken": [
         {
             "platforms": [
@@ -8088,6 +8109,25 @@
             ]
         }
     ],
+    "V8FastApiCalls": [
+        {
+            "platforms": [
+                "linux",
+                "windows",
+                "android",
+                "mac",
+                "chromeos_lacros"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "V8TurboFastApiCalls"
+                    ]
+                }
+            ]
+        }
+    ],
     "V8OffThreadFinalization": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index 60e45ff..ece6ab8 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -23,7 +23,6 @@
   generate_java = true
   sources = [
     "ad_tagging/ad_evidence.mojom",
-    "ad_tagging/ad_frame.mojom",
     "app_banner/app_banner.mojom",
     "appcache/appcache.mojom",
     "appcache/appcache_info.mojom",
diff --git a/third_party/blink/public/mojom/ad_tagging/ad_frame.mojom b/third_party/blink/public/mojom/ad_tagging/ad_frame.mojom
deleted file mode 100644
index efa9971..0000000
--- a/third_party/blink/public/mojom/ad_tagging/ad_frame.mojom
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module blink.mojom;
-
-// Enumeration of ad frame types.
-enum AdFrameType {
-  // Frame is not an ad.
-  kNonAd,
-  // Frame is an ad whose parent frame is an ad.
-  kChildAd,
-  // Frame is an ad whose parent frame is not an ad.
-  kRootAd
-};
-
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom
index 9603700..eb6dabb 100644
--- a/third_party/blink/public/mojom/frame/frame.mojom
+++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -21,7 +21,6 @@
 import "services/network/public/mojom/web_sandbox_flags.mojom";
 import "services/viz/public/mojom/compositing/frame_sink_id.mojom";
 import "skia/public/mojom/skcolor.mojom";
-import "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom";
 import "third_party/blink/public/mojom/blob/blob.mojom";
 import "third_party/blink/public/mojom/blob/blob_url_store.mojom";
 import "third_party/blink/public/mojom/messaging/transferable_message.mojom";
@@ -996,9 +995,9 @@
   SetReplicatedOrigin(url.mojom.Origin origin,
     bool is_potentially_trustworthy_unique_origin);
 
-  // Update the replicated ad frame type. Used when the frame is determined to
-  // be an ad frame.
-  SetReplicatedAdFrameType(blink.mojom.AdFrameType ad_frame_type);
+  // Update the replicated ad status. Used when the frame is tagged or untagged
+  // as an ad frame by Ad Tagging.
+  SetReplicatedIsAdSubframe(bool is_ad_subframe);
 
   // Sets the replicated name and unique name for the frame. Used when the
   // name of a frame changes.
diff --git a/third_party/blink/public/mojom/frame/frame_replication_state.mojom b/third_party/blink/public/mojom/frame/frame_replication_state.mojom
index b2418b7..774781d 100644
--- a/third_party/blink/public/mojom/frame/frame_replication_state.mojom
+++ b/third_party/blink/public/mojom/frame/frame_replication_state.mojom
@@ -5,7 +5,6 @@
 module blink.mojom;
 
 import "services/network/public/mojom/web_sandbox_flags.mojom";
-import "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom";
 import "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom";
 import "third_party/blink/public/mojom/frame/frame_policy.mojom";
 import "third_party/blink/public/mojom/frame/tree_scope_type.mojom";
@@ -103,8 +102,6 @@
   // long as a the frame has staying on the same eTLD+1.
   bool has_received_user_gesture_before_nav = false;
 
-  // Whether this frame is an ad frame. Once a frame becomes an ad, it stays as
-  // an ad throughout its lifetime, even if it later navigates to a non-ad
-  // document.
-  blink.mojom.AdFrameType ad_frame_type = blink.mojom.AdFrameType.kNonAd;
+  // Whether this frame is an ad frame.
+  bool is_ad_subframe = false;
 };
diff --git a/third_party/blink/public/web/web_image.h b/third_party/blink/public/web/web_image.h
index 3a4cfc5..413b5ef 100644
--- a/third_party/blink/public/web/web_image.h
+++ b/third_party/blink/public/web/web_image.h
@@ -56,7 +56,9 @@
 
   // Decodes the given image data. If the image has multiple frames,
   // then the frame whose size is desired_size is returned. Otherwise,
-  // the first frame is returned.
+  // the first frame is returned. If the image contains EXIF data that changes
+  // the orientation, the returned image will be rotated such that the result is
+  // top-left oriented.
   BLINK_EXPORT static SkBitmap FromData(const WebData&,
                                         const gfx::Size& desired_size);
 
diff --git a/third_party/blink/public/web/web_remote_frame.h b/third_party/blink/public/web/web_remote_frame.h
index c05190b0..2b7f665 100644
--- a/third_party/blink/public/web/web_remote_frame.h
+++ b/third_party/blink/public/web/web_remote_frame.h
@@ -7,7 +7,6 @@
 
 #include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
 #include "third_party/blink/public/common/tokens/tokens.h"
-#include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-shared.h"
 #include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom-shared.h"
 #include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom-shared.h"
 #include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom-shared.h"
@@ -117,8 +116,7 @@
   virtual void SetReplicatedInsecureNavigationsSet(
       const WebVector<unsigned>&) = 0;
 
-  virtual void SetReplicatedAdFrameType(
-      blink::mojom::AdFrameType ad_frame_type) = 0;
+  virtual void SetReplicatedIsAdSubframe(bool is_ad_subframe) = 0;
 
   virtual void DidStartLoading() = 0;
 
diff --git a/third_party/blink/renderer/controller/oom_intervention_impl_test.cc b/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
index 88fd3fb..4753070 100644
--- a/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
+++ b/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
@@ -278,8 +278,13 @@
   frame_test_helpers::PumpPendingRequestsForFrameToLoad(
       non_ad_iframe->ToWebLocalFrame());
 
+  blink::FrameAdEvidence ad_evidence(/*parent_is_ad=*/false);
+  ad_evidence.set_created_by_ad_script(
+      mojom::FrameCreationStackEvidence::kCreatedByAdScript);
+  ad_evidence.set_is_complete();
+
   auto* local_adframe = To<LocalFrame>(WebFrame::ToCoreFrame(*ad_iframe));
-  local_adframe->SetIsAdSubframe(blink::mojom::AdFrameType::kRootAd);
+  local_adframe->SetAdEvidence(ad_evidence);
   auto* local_non_adframe =
       To<LocalFrame>(WebFrame::ToCoreFrame(*non_ad_iframe));
 
diff --git a/third_party/blink/renderer/core/aom/accessible_node.cc b/third_party/blink/renderer/core/aom/accessible_node.cc
index 17ca9cc8..3fc7a16 100644
--- a/third_party/blink/renderer/core/aom/accessible_node.cc
+++ b/third_party/blink/renderer/core/aom/accessible_node.cc
@@ -938,6 +938,7 @@
                                       "Reparenting is not supported yet.");
     return;
   }
+  child->document_ = GetAncestorDocument();
   child->parent_ = this;
 
   if (!GetExecutionContext()->GetSecurityOrigin()->CanAccess(
@@ -1038,6 +1039,16 @@
   return nullptr;
 }
 
+Document* AccessibleNode::GetAncestorDocument() {
+  if (element_)
+    return &(element_->GetDocument());
+
+  if (parent_)
+    return parent_->GetAncestorDocument();
+
+  return nullptr;
+}
+
 void AccessibleNode::SetStringProperty(AOMStringProperty property,
                                        const AtomicString& value) {
   for (auto& item : string_properties_) {
diff --git a/third_party/blink/renderer/core/aom/accessible_node.h b/third_party/blink/renderer/core/aom/accessible_node.h
index b148bf1e..19b89e0 100644
--- a/third_party/blink/renderer/core/aom/accessible_node.h
+++ b/third_party/blink/renderer/core/aom/accessible_node.h
@@ -351,6 +351,7 @@
 
   // Called when an accessible node is removed from document.
   void DetachedFromDocument();
+  Document* GetAncestorDocument();
 
   // EventTarget
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/core/app_history/app_history.cc b/third_party/blink/renderer/core/app_history/app_history.cc
index 8d3aa88..658946f 100644
--- a/third_party/blink/renderer/core/app_history/app_history.cc
+++ b/third_party/blink/renderer/core/app_history/app_history.cc
@@ -23,10 +23,7 @@
 
 class NavigateReaction final : public ScriptFunction {
  public:
-  enum class ResolveType {
-    kFulfill,
-    kReject,
-  };
+  enum class ResolveType { kFulfill, kReject, kDetach };
   static void React(ScriptState* script_state,
                     ScriptPromise promise,
                     ScriptPromiseResolver* resolver) {
@@ -34,6 +31,12 @@
                  CreateFunction(script_state, resolver, ResolveType::kReject));
   }
 
+  static void CleanupWithoutResolving(ScriptState* script_state,
+                                      ScriptPromiseResolver* resolver) {
+    ScriptPromise::CastUndefined(script_state)
+        .Then(CreateFunction(script_state, resolver, ResolveType::kDetach));
+  }
+
   NavigateReaction(ScriptState* script_state,
                    ScriptPromiseResolver* resolver,
                    ResolveType type)
@@ -74,6 +77,11 @@
 
   ScriptValue Call(ScriptValue value) final {
     DCHECK(window_);
+    if (type_ == ResolveType::kDetach) {
+      resolver_->Detach();
+      window_ = nullptr;
+      return ScriptValue();
+    }
     AppHistory::appHistory(*window_)->DispatchEvent(*InitEvent(value));
     if (resolver_) {
       if (type_ == ResolveType::kFulfill)
@@ -241,6 +249,7 @@
   base::AutoReset<Member<ScriptPromiseResolver>> promise(
       &navigate_method_call_promise_resolver_,
       MakeGarbageCollected<ScriptPromiseResolver>(script_state));
+  base::AutoReset<bool> did_react(&did_react_to_promise_, false);
   base::AutoReset<ScriptValue> event_info(&navigate_event_info_,
                                           options->navigateInfo());
   WebFrameLoadType frame_load_type = options->replace()
@@ -263,6 +272,14 @@
                                       "Navigation was aborted");
     return ScriptPromise();
   }
+
+  // The spec assumes it's ok to leave a promise permanently unresolved, but
+  // ScriptPromiseResolver requires either resolution or explicit detach.
+  // Do the detach on a microtask so that we can still return the promise.
+  if (!did_react_to_promise_) {
+    NavigateReaction::CleanupWithoutResolving(
+        script_state, navigate_method_call_promise_resolver_);
+  }
   if (navigate_serialized_state_)
     current()->GetItem()->SetAppHistoryState(navigate_serialized_state_);
   return navigate_method_call_promise_resolver_->Promise();
@@ -338,6 +355,8 @@
                              event_type != NavigateEventType::kCrossDocument)) {
     if (promise.IsEmpty())
       promise = ScriptPromise::CastUndefined(script_state);
+    if (navigate_method_call_promise_resolver_)
+      did_react_to_promise_ = true;
     NavigateReaction::React(script_state, promise,
                             navigate_method_call_promise_resolver_);
   } else {
@@ -349,6 +368,8 @@
         script_state,
         MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError,
                                            "Navigation was aborted"));
+    if (navigate_method_call_promise_resolver_)
+      did_react_to_promise_ = true;
     NavigateReaction::React(script_state, promise,
                             navigate_method_call_promise_resolver_);
   }
diff --git a/third_party/blink/renderer/core/app_history/app_history.h b/third_party/blink/renderer/core/app_history/app_history.h
index 0114a43..429ab44 100644
--- a/third_party/blink/renderer/core/app_history/app_history.h
+++ b/third_party/blink/renderer/core/app_history/app_history.h
@@ -94,6 +94,7 @@
   Member<ScriptPromiseResolver> navigate_method_call_promise_resolver_;
   scoped_refptr<SerializedScriptValue> navigate_serialized_state_;
 
+  bool did_react_to_promise_ = false;
   ScriptValue navigate_event_info_;
 };
 
diff --git a/third_party/blink/renderer/core/exported/web_image.cc b/third_party/blink/renderer/core/exported/web_image.cc
index bb0e680..ed31955 100644
--- a/third_party/blink/renderer/core/exported/web_image.cc
+++ b/third_party/blink/renderer/core/exported/web_image.cc
@@ -79,7 +79,17 @@
   ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(index);
   if (!frame || decoder->Failed())
     return {};
-  return frame->Bitmap();
+
+  if (decoder->Orientation().Orientation() == ImageOrientationEnum::kDefault)
+    return frame->Bitmap();
+
+  cc::PaintImage paint_image(Image::ResizeAndOrientImage(
+      cc::PaintImage::CreateFromBitmap(frame->Bitmap()),
+      decoder->Orientation()));
+
+  SkBitmap bitmap;
+  paint_image.GetSwSkImage()->asLegacyBitmap(&bitmap);
+  return bitmap;
 }
 
 SkBitmap WebImage::DecodeSVG(const WebData& data,
diff --git a/third_party/blink/renderer/core/frame/ad_tracker_test.cc b/third_party/blink/renderer/core/frame/ad_tracker_test.cc
index fa6c51724..372c808 100644
--- a/third_party/blink/renderer/core/frame/ad_tracker_test.cc
+++ b/third_party/blink/renderer/core/frame/ad_tracker_test.cc
@@ -173,6 +173,16 @@
   String url_to_wait_for_;
 };
 
+void SetIsAdSubframe(LocalFrame* frame) {
+  DCHECK(frame);
+  blink::FrameAdEvidence ad_evidence(frame->Parent() &&
+                                     frame->Parent()->IsAdSubframe());
+  ad_evidence.set_created_by_ad_script(
+      mojom::FrameCreationStackEvidence::kCreatedByAdScript);
+  ad_evidence.set_is_complete();
+  frame->SetAdEvidence(ad_evidence);
+}
+
 }  // namespace
 
 class AdTrackerTest : public testing::Test {
@@ -435,7 +445,7 @@
   main_resource_->Complete("<body><iframe></iframe></body>");
   auto* child_frame =
       To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild());
-  child_frame->SetIsAdSubframe(blink::mojom::AdFrameType::kRootAd);
+  SetIsAdSubframe(child_frame);
 
   // Now run unknown script in the child's context. It should be considered an
   // ad based on context alone.
@@ -523,7 +533,7 @@
       "<body><iframe src='ad_frame.html'></iframe></body>");
   auto* child_frame =
       To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild());
-  child_frame->SetIsAdSubframe(blink::mojom::AdFrameType::kRootAd);
+  SetIsAdSubframe(child_frame);
 
   // Load a resource from the frame. It should be detected as an ad resource due
   // to its context.
@@ -562,7 +572,7 @@
   // Verify that the new frame is considered created by ad script then set it
   // as an ad subframe. This emulates the embedder tagging a frame as an ad.
   EXPECT_TRUE(child_frame->IsSubframeCreatedByAdScript());
-  child_frame->SetIsAdSubframe(blink::mojom::AdFrameType::kRootAd);
+  SetIsAdSubframe(child_frame);
 
   // Create a new sibling frame to the ad frame. The ad context calls the non-ad
   // context's (top frame) appendChild.
@@ -757,7 +767,7 @@
   // Verify that the new frame is considered created by ad script then set it
   // as an ad subframe. This emulates the SubresourceFilterAgent's tagging.
   EXPECT_TRUE(child_frame->IsSubframeCreatedByAdScript());
-  child_frame->SetIsAdSubframe(blink::mojom::AdFrameType::kRootAd);
+  SetIsAdSubframe(child_frame);
 
   vanilla_page.Complete("<img src=vanilla_img.jpg></img>");
   vanilla_image.Complete("");
@@ -979,7 +989,7 @@
   if (IsAdRun()) {
     auto* subframe =
         To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild());
-    subframe->SetIsAdSubframe(blink::mojom::AdFrameType::kRootAd);
+    SetIsAdSubframe(subframe);
   }
 
   frame.Complete(kPageWithVanillaExternalStylesheet);
@@ -1062,7 +1072,7 @@
   if (IsAdRun()) {
     auto* subframe =
         To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild());
-    subframe->SetIsAdSubframe(blink::mojom::AdFrameType::kRootAd);
+    SetIsAdSubframe(subframe);
   }
 
   frame.Complete(kPageWithStyleTagLoadingVanillaResources);
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc
index a190fd8..8bf6b4b 100644
--- a/third_party/blink/renderer/core/frame/frame.cc
+++ b/third_party/blink/renderer/core/frame/frame.cc
@@ -337,14 +337,6 @@
   UpdateInheritedEffectiveTouchActionIfPossible();
 }
 
-bool Frame::IsAdSubframe() const {
-  return ad_frame_type_ != mojom::blink::AdFrameType::kNonAd;
-}
-
-bool Frame::IsAdRoot() const {
-  return ad_frame_type_ == mojom::blink::AdFrameType::kRootAd;
-}
-
 void Frame::UpdateInertIfPossible() {
   if (auto* frame_owner_element =
           DynamicTo<HTMLFrameOwnerElement>(owner_.Get())) {
@@ -415,7 +407,6 @@
     : tree_node_(this),
       page_(&page),
       owner_(owner),
-      ad_frame_type_(mojom::blink::AdFrameType::kNonAd),
       client_(client),
       window_proxy_manager_(window_proxy_manager),
       parent_(parent),
diff --git a/third_party/blink/renderer/core/frame/frame.h b/third_party/blink/renderer/core/frame/frame.h
index 4249885..5ce7bc9 100644
--- a/third_party/blink/renderer/core/frame/frame.h
+++ b/third_party/blink/renderer/core/frame/frame.h
@@ -33,12 +33,12 @@
 #include "base/unguessable_token.h"
 #include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/frame/frame_ad_evidence.h"
 #include "third_party/blink/public/common/frame/user_activation_state.h"
 #include "third_party/blink/public/common/frame/user_activation_update_source.h"
 #include "third_party/blink/public/common/permissions_policy/document_policy_features.h"
 #include "third_party/blink/public/common/permissions_policy/permissions_policy_features.h"
 #include "third_party/blink/public/common/tokens/tokens.h"
-#include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/input/scroll_direction.mojom-blink-forward.h"
@@ -230,10 +230,7 @@
 
   // Whether the frame is considered to be an ad subframe by Ad Tagging. Returns
   // true for both root and child ad subframes.
-  bool IsAdSubframe() const;
-
-  // Whether the frame is considered to be a root ad subframe by Ad Tagging.
-  bool IsAdRoot() const;
+  virtual bool IsAdSubframe() const = 0;
 
   // Called to make a frame inert or non-inert. A frame is inert when there
   // is a modal dialog displayed within an ancestor frame, and this frame
@@ -436,19 +433,6 @@
 
   bool visible_to_hit_testing_ = true;
 
-  // Type of frame detected by heuristics checking if the frame was created
-  // for advertising purposes. It's per-frame (as opposed to per-document)
-  // because when an iframe is created on behalf of ad script that same frame is
-  // not typically reused for non-ad purposes.
-  //
-  // For LocalFrame, it might be (1) calculated directly in the renderer based
-  // on script in the stack in the case of an initial synchronous commit, or (2)
-  // replicated from the browser process, or (3) signaled from the browser
-  // process at ready-to-commit time. For RemoteFrame, it might be (1)
-  // replicated from the browser process or (2) signaled from the browser
-  // process at ready-to-commit time.
-  mojom::blink::AdFrameType ad_frame_type_;
-
  private:
   // Inserts the given frame as a child of this frame, so that it is the next
   // child after |previous_sibling|, or first child if |previous_sibling| is
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 69df2007..932b271 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -50,7 +50,6 @@
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/input/web_input_event_attribution.h"
 #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
-#include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-blink.h"
 #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
 #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-blink.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
@@ -2389,13 +2388,45 @@
   return Owner()->ContentFrame() != this;
 }
 
-void LocalFrame::SetIsAdSubframe(blink::mojom::AdFrameType ad_frame_type) {
-  DCHECK(!IsMainFrame());
+bool LocalFrame::IsAdSubframe() const {
+  return ad_evidence_ && ad_evidence_->IndicatesAdSubframe();
+}
 
-  if (ad_frame_type_ == ad_frame_type)
+bool LocalFrame::IsAdRoot() const {
+  return IsAdSubframe() && !ad_evidence_->parent_is_ad();
+}
+
+void LocalFrame::SetAdEvidence(const blink::FrameAdEvidence& ad_evidence) {
+  DCHECK(!IsMainFrame());
+  DCHECK(ad_evidence.is_complete());
+
+  // Once set, `is_subframe_created_by_ad_script_` should not be unset.
+  DCHECK(!is_subframe_created_by_ad_script_ ||
+         ad_evidence.created_by_ad_script() ==
+             blink::mojom::FrameCreationStackEvidence::kCreatedByAdScript);
+  is_subframe_created_by_ad_script_ =
+      ad_evidence.created_by_ad_script() ==
+      blink::mojom::FrameCreationStackEvidence::kCreatedByAdScript;
+
+  if (ad_evidence_.has_value()) {
+    // Check that replacing with the new ad evidence doesn't violate invariants.
+    // The parent frame's ad status should not change as it can only change due
+    // to a cross-document commit, which would remove this child frame.
+    DCHECK_EQ(ad_evidence_->parent_is_ad(), ad_evidence.parent_is_ad());
+
+    // The most restrictive filter list result cannot become less restrictive,
+    // by definition.
+    DCHECK_LE(ad_evidence_->most_restrictive_filter_list_result(),
+              ad_evidence.most_restrictive_filter_list_result());
+  }
+
+  bool was_ad_subframe = IsAdSubframe();
+  bool is_ad_subframe = ad_evidence.IndicatesAdSubframe();
+  ad_evidence_ = ad_evidence;
+
+  if (was_ad_subframe == is_ad_subframe)
     return;
 
-  bool is_ad_subframe = ad_frame_type != blink::mojom::AdFrameType::kNonAd;
   if (auto* document = GetDocument()) {
     // TODO(fdoray): It is possible for the document not to be installed when
     // this method is called. Consider inheriting frame bit in the graph instead
@@ -2405,7 +2436,6 @@
       document_resource_coordinator->SetIsAdFrame(is_ad_subframe);
   }
 
-  ad_frame_type_ = ad_frame_type;
   UpdateAdHighlight();
   frame_scheduler_->SetIsAdFrame(is_ad_subframe);
 
@@ -2417,21 +2447,6 @@
   }
 }
 
-void LocalFrame::SetAdEvidence(const blink::FrameAdEvidence& ad_evidence) {
-  DCHECK(!IsMainFrame());
-
-  if (ad_evidence_.has_value()) {
-    // Check that replacing with the new ad evidence doesn't violate invariants.
-    DCHECK_EQ(ad_evidence_->parent_is_ad(), ad_evidence.parent_is_ad());
-    DCHECK_LE(ad_evidence_->is_complete(), ad_evidence.is_complete());
-    DCHECK_LE(ad_evidence_->created_by_ad_script(),
-              ad_evidence.created_by_ad_script());
-    DCHECK_LE(ad_evidence_->most_restrictive_filter_list_result(),
-              ad_evidence.most_restrictive_filter_list_result());
-  }
-  ad_evidence_ = ad_evidence;
-}
-
 void LocalFrame::UpdateAdHighlight() {
   if (IsMainFrame())
     return;
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index 3a0e6b9..75933390 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -195,7 +195,6 @@
   void DidChangeVisibilityState() override;
   void HookBackForwardCacheEviction() override;
   void RemoveBackForwardCacheEviction() override;
-
   void SetTextDirection(base::i18n::TextDirection direction) override;
   // This sets the is_inert_ flag and also recurses through this frame's
   // subtree, updating the inert bit on all descendant frames.
@@ -206,6 +205,7 @@
       ScrollGranularity granularity,
       Frame* child) override;
   void DidFocus() override;
+  bool IsAdSubframe() const override;
 
   // Triggers eviction of this frame by notifying the browser side.
   void EvictFromBackForwardCache(mojom::blink::RendererEvictionReason reason);
@@ -502,11 +502,8 @@
   // be removed.
   bool IsProvisional() const;
 
-  // Called by the embedder according to whether the evidence indicates the
-  // frame is an ad subframe. Called on creation of the initial empty document
-  // or, for LocalFrames created on behalf of OOPIF, just before commit
-  // (ReadyToCommitNavigation time).
-  void SetIsAdSubframe(blink::mojom::AdFrameType ad_frame_type);
+  // Whether the frame is considered to be a root ad subframe by Ad Tagging.
+  bool IsAdRoot() const;
 
   // Called by the embedder on creation of the initial empty document and, for
   // all other documents, just before commit (ReadyToCommitNavigation time).
@@ -1114,10 +1111,8 @@
   absl::optional<blink::FrameAdEvidence> ad_evidence_;
 
   // True if this frame is a subframe that had a script tagged as an ad on the
-  // v8 stack at the time of creation. This is not currently propagated when a
-  // frame navigates cross-origin.
-  // TODO(crbug.com/1145634): propagate this bit for a frame that navigates
-  // cross-origin.
+  // v8 stack at the time of creation. This is updated in `SetAdEvidence()`,
+  // allowing the bit to be propagated when a frame navigates cross-origin.
   bool is_subframe_created_by_ad_script_ = false;
 };
 
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 76e3c4d..b03fd6c9 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -3169,6 +3169,7 @@
   CheckDoesNotNeedLayout();
 #if DCHECK_IS_ON()
   frame_->GetDocument()->GetLayoutView()->AssertLaidOut();
+  frame_->GetDocument()->GetLayoutView()->AssertFragmentTree();
 #endif
 
   if (Lifecycle().GetState() < DocumentLifecycle::kLayoutClean)
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc
index 17ea803..0f51e15 100644
--- a/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -618,9 +618,12 @@
   }
 }
 
-void RemoteFrame::SetReplicatedAdFrameType(
-    mojom::blink::AdFrameType ad_frame_type) {
-  ad_frame_type_ = ad_frame_type;
+bool RemoteFrame::IsAdSubframe() const {
+  return is_ad_subframe_;
+}
+
+void RemoteFrame::SetReplicatedIsAdSubframe(bool is_ad_subframe) {
+  is_ad_subframe_ = is_ad_subframe;
 }
 
 void RemoteFrame::SetReplicatedName(const String& name,
diff --git a/third_party/blink/renderer/core/frame/remote_frame.h b/third_party/blink/renderer/core/frame/remote_frame.h
index 9b2d915c..40984523 100644
--- a/third_party/blink/renderer/core/frame/remote_frame.h
+++ b/third_party/blink/renderer/core/frame/remote_frame.h
@@ -85,6 +85,7 @@
   void DidFocus() override;
   void AddResourceTimingFromChild(
       mojom::blink::ResourceTimingInfoPtr timing) override;
+  bool IsAdSubframe() const override;
 
   // ChildFrameCompositor:
   const scoped_refptr<cc::Layer>& GetCcLayer() override;
@@ -156,8 +157,7 @@
   void SetReplicatedOrigin(
       const scoped_refptr<const SecurityOrigin>& origin,
       bool is_potentially_trustworthy_unique_origin) override;
-  void SetReplicatedAdFrameType(
-      mojom::blink::AdFrameType ad_frame_type) override;
+  void SetReplicatedIsAdSubframe(bool is_ad_subframe) override;
   void SetReplicatedName(const String& name,
                          const String& unique_name) override;
   void DispatchLoadEventForFrameOwner() override;
@@ -282,6 +282,9 @@
   // Will be nullptr when this RemoteFrame's parent is not a LocalFrame.
   std::unique_ptr<ChildFrameCompositingHelper> compositing_helper_;
 
+  // Whether the frame is considered to be an ad subframe by Ad Tagging.
+  bool is_ad_subframe_;
+
   mojo::AssociatedRemote<mojom::blink::RemoteFrameHost>
       remote_frame_host_remote_;
   mojo::AssociatedReceiver<mojom::blink::RemoteFrame> receiver_{this};
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 934a69e..8a4bb57 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -859,15 +859,6 @@
     const blink::FrameAdEvidence& ad_evidence) {
   DCHECK(GetFrame());
   GetFrame()->SetAdEvidence(ad_evidence);
-
-  // TODO(alexmt): Remove when AdFrameType is replaced.
-  blink::mojom::AdFrameType ad_frame_type = blink::mojom::AdFrameType::kNonAd;
-  if (ad_evidence.IndicatesAdSubframe()) {
-    ad_frame_type = ad_evidence.parent_is_ad()
-                        ? blink::mojom::AdFrameType::kChildAd
-                        : blink::mojom::AdFrameType::kRootAd;
-  }
-  GetFrame()->SetIsAdSubframe(ad_frame_type);
 }
 
 const absl::optional<blink::FrameAdEvidence>& WebLocalFrameImpl::AdEvidence() {
diff --git a/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc b/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc
index 999fb678..d0515ec 100644
--- a/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_remote_frame_impl.cc
@@ -360,10 +360,9 @@
   GetFrame()->SetInsecureNavigationsSet(set);
 }
 
-void WebRemoteFrameImpl::SetReplicatedAdFrameType(
-    mojom::blink::AdFrameType ad_frame_type) {
+void WebRemoteFrameImpl::SetReplicatedIsAdSubframe(bool is_ad_subframe) {
   DCHECK(GetFrame());
-  GetFrame()->SetReplicatedAdFrameType(ad_frame_type);
+  GetFrame()->SetReplicatedIsAdSubframe(is_ad_subframe);
 }
 
 void WebRemoteFrameImpl::DidStartLoading() {
diff --git a/third_party/blink/renderer/core/frame/web_remote_frame_impl.h b/third_party/blink/renderer/core/frame/web_remote_frame_impl.h
index de4ed32..b224a36 100644
--- a/third_party/blink/renderer/core/frame/web_remote_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_remote_frame_impl.h
@@ -93,8 +93,7 @@
   void SetReplicatedInsecureRequestPolicy(
       mojom::blink::InsecureRequestPolicy) override;
   void SetReplicatedInsecureNavigationsSet(const WebVector<unsigned>&) override;
-  void SetReplicatedAdFrameType(
-      mojom::blink::AdFrameType ad_frame_type) override;
+  void SetReplicatedIsAdSubframe(bool is_ad_subframe) override;
   void DidStartLoading() override;
   bool IsIgnoredForHitTest() const override;
   void UpdateUserActivationState(
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc b/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc
index a3f993a2..47a8bcc 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc
@@ -170,15 +170,17 @@
     // canvases per render task.
     measure_current_task_ = !(task_counter_++ % kSamplingProbabilityInv);
 
-    if (context->Host() && context->Host()->GetTopExecutionContext() &&
-        context->Host()
-            ->GetTopExecutionContext()
-            ->IsInRequestAnimationFrame()) {
-      call_type_ = CallType::kAnimation;
-    } else {
-      // TODO(crbug.com/1206028): Add support for CallType::kUserInput
-      call_type_ = CallType::kOther;
+    if (LIKELY(!measure_current_task_))
+      return;
+
+    call_type_ = CallType::kOther;
+    if (context->Host()) {
+      ExecutionContext* ec = context->Host()->GetTopExecutionContext();
+      if (ec && ec->IsInRequestAnimationFrame()) {
+        call_type_ = CallType::kAnimation;
+      }
     }
+    // TODO(crbug.com/1206028): Add support for CallType::kUserInput
   }
 
   if (LIKELY(!measure_current_task_))
diff --git a/third_party/blink/renderer/core/html/subresource_redirect_test.cc b/third_party/blink/renderer/core/html/subresource_redirect_test.cc
index 51a4258..3faba368 100644
--- a/third_party/blink/renderer/core/html/subresource_redirect_test.cc
+++ b/third_party/blink/renderer/core/html/subresource_redirect_test.cc
@@ -86,7 +86,8 @@
       // Scroll down until the image is visible.
       GetDocument().View()->LayoutViewport()->SetScrollOffset(
           ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic);
-      Compositor().BeginFrame();
+      if (Compositor().NeedsBeginFrame())
+        Compositor().BeginFrame();
       test::RunPendingTasks();
       image_resource.Complete(ReadTestImage());
     }
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index bcfaa3b..e6093e2 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -426,6 +426,31 @@
 
 #if DCHECK_IS_ON()
 
+void LayoutObject::AssertFragmentTree(bool display_locked) const {
+  NOT_DESTROYED();
+  for (const LayoutObject* layout_object = this; layout_object;) {
+    // If display-locked, fragments may not be removed from the tree even after
+    // the |LayoutObject| was destroyed, but still they should be consistent.
+    if (!display_locked && layout_object->ChildLayoutBlockedByDisplayLock()) {
+      layout_object->AssertFragmentTree(
+          /* display_locked */ true);
+      layout_object = layout_object->NextInPreOrderAfterChildren(this);
+      continue;
+    }
+
+    // Check the direct children of the fragment. Grand-children and further
+    // descendants will be checked by descendant LayoutObjects.
+    if (const auto* box = DynamicTo<LayoutBox>(layout_object)) {
+      for (const NGPhysicalBoxFragment& fragment : box->PhysicalFragments()) {
+        DCHECK_EQ(box, fragment.OwnerLayoutBox());
+        fragment.AssertFragmentTreeChildren(
+            /* allow_destroyed */ display_locked);
+      }
+    }
+    layout_object = layout_object->NextInPreOrder(this);
+  }
+}
+
 void LayoutObject::AssertClearedPaintInvalidationFlags() const {
   NOT_DESTROYED();
   if (!PaintInvalidationStateIsDirty() || ChildPrePaintBlockedByDisplayLock())
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 5a19438..d6323b2 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -506,6 +506,13 @@
     }
   }
 
+  // This function checks if the fragment tree is consistent with the
+  // |LayoutObject| tree. This consistency is critical, as sometimes we traverse
+  // the fragment tree, sometimes the |LayoutObject| tree, or mix the
+  // traversals. Also we rely on the consistency to avoid using fragments whose
+  // |LayoutObject| were destroyed.
+  void AssertFragmentTree(bool display_locked = false) const;
+
   void AssertClearedPaintInvalidationFlags() const;
 
   void AssertSubtreeClearedPaintInvalidationFlags() const {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 0564522..1f4715c 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -1341,8 +1341,13 @@
     }
 
     DCHECK(!child_box);
-
     LogicalSize logical_size = converter.ToLogical(child_fragment.Size());
+
+    // TODO(layout-dev): This should really be checking if there are any
+    // descendants that take up block space rather than if it has overflow. In
+    // other words, we would still want to clamp a zero height fragmentainer if
+    // it had content with zero inline size and non-zero block size. This would
+    // likely require us to store an extra flag on NGPhysicalBoxFragment.
     if (child_fragment.HasLayoutOverflow()) {
       // Don't clamp the fragmentainer to a block size of 1 if it is truly a
       // zero-height column.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
index 567daf48..80ec1f9 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -1638,6 +1638,41 @@
     DCHECK(!has_list_markers);
   }
 }
+
+void NGPhysicalBoxFragment::AssertFragmentTreeSelf() const {
+  DCHECK(!IsInlineBox());
+  DCHECK(OwnerLayoutBox());
+  DCHECK_EQ(this, PostLayout());
+}
+
+void NGPhysicalBoxFragment::AssertFragmentTreeChildren(
+    bool allow_destroyed) const {
+  if (const NGFragmentItems* items = Items()) {
+    for (NGInlineCursor cursor(*this, *items); cursor; cursor.MoveToNext()) {
+      const NGFragmentItem& item = *cursor.Current();
+      if (item.IsLayoutObjectDestroyedOrMoved()) {
+        DCHECK(allow_destroyed);
+        DCHECK(!item.BoxFragment() ||
+               item.BoxFragment()->IsLayoutObjectDestroyedOrMoved());
+        continue;
+      }
+      if (const auto* box = item.BoxFragment()) {
+        DCHECK(!box->IsLayoutObjectDestroyedOrMoved());
+        if (!box->IsInlineBox())
+          box->AssertFragmentTreeSelf();
+      }
+    }
+  }
+
+  for (const NGLink& child : Children()) {
+    if (child->IsLayoutObjectDestroyedOrMoved()) {
+      DCHECK(allow_destroyed);
+      continue;
+    }
+    if (const auto* box = DynamicTo<NGPhysicalBoxFragment>(child.fragment))
+      box->AssertFragmentTreeSelf();
+  }
+}
 #endif
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
index 1d3a998..92a67a12 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
@@ -431,6 +431,8 @@
 
 #if DCHECK_IS_ON()
   void InvalidateInkOverflow();
+  void AssertFragmentTreeSelf() const;
+  void AssertFragmentTreeChildren(bool allow_destroyed = false) const;
 #endif
 
  private:
diff --git a/third_party/blink/renderer/core/layout/subtree_layout_scope.cc b/third_party/blink/renderer/core/layout/subtree_layout_scope.cc
index fafe6b6f..e2ae3b7 100644
--- a/third_party/blink/renderer/core/layout/subtree_layout_scope.cc
+++ b/third_party/blink/renderer/core/layout/subtree_layout_scope.cc
@@ -55,6 +55,7 @@
     // these objects to be dirty.
     if (!DisplayLockUtilities::LockedAncestorPreventingLayout(*layout_object))
       layout_object->AssertLaidOut();
+    layout_object->AssertFragmentTree();
   }
 #endif
 }
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 1f52a3c..00fa51e 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -3824,10 +3824,12 @@
   }
   LocalFrame* parent_frame = iframe->GetDocument().GetFrame();
   LocalFrame* child_frame = To<LocalFrame>(iframe->ContentFrame());
-  bool parent_is_ad = parent_frame && parent_frame->IsAdSubframe();
-  child_frame->SetIsAdSubframe(parent_is_ad
-                                   ? blink::mojom::AdFrameType::kChildAd
-                                   : blink::mojom::AdFrameType::kRootAd);
+  blink::FrameAdEvidence ad_evidence(parent_frame &&
+                                     parent_frame->IsAdSubframe());
+  ad_evidence.set_created_by_ad_script(
+      mojom::FrameCreationStackEvidence::kCreatedByAdScript);
+  ad_evidence.set_is_complete();
+  child_frame->SetAdEvidence(ad_evidence);
 }
 
 ReadableStream* Internals::createReadableStream(
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 0ea3ecf..4f440b6 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -2546,7 +2546,7 @@
     // We don't retrieve the element's value attribute on purpose. The value
     // attribute might be sanitized and might be different from what is actually
     // displayed inside the <select> element on screen.
-    return select_element->InnerElement().innerText();
+    return select_element->InnerElement().GetInnerTextWithoutUpdate();
   }
 
   if (IsAtomicTextField()) {
@@ -3047,7 +3047,7 @@
 String AXNodeObject::TextFromDescendants(AXObjectSet& visited,
                                          bool recursive) const {
   if (!CanHaveChildren())
-    return recursive ? String() : GetElement()->innerText();
+    return recursive ? String() : GetElement()->GetInnerTextWithoutUpdate();
 
   StringBuilder accumulated_text;
   AXObject* previous = nullptr;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 44450298..fe301c0 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -126,13 +126,20 @@
   return node ? node : GetClosestNodeForLayoutObject(layout_object->Parent());
 }
 
-// Return true if display locked, false otherwise.
+// Return true if display locked or inside slot recalc, false otherwise.
 // Also returns false if not a safe time to perform the check.
 bool IsDisplayLocked(const Node* node) {
   if (!node)
     return false;
-  if (node->GetDocument().IsFlatTreeTraversalForbidden())
+  // The NearestLockedExclusiveAncestor() function will attempt to do
+  // a flat tree traversal of ancestors. If we're in a flat tree traversal
+  // forbidden scope, return false. Additionally, flat tree traversal
+  // might call AssignedSlot, so if we're in a slot assignment recalc
+  // forbidden scope, return false.
+  if (node->GetDocument().IsFlatTreeTraversalForbidden() ||
+      node->GetDocument().IsSlotAssignmentRecalcForbidden()) {
     return false;  // Cannot safely perform this check now.
+  }
   return DisplayLockUtilities::NearestLockedExclusiveAncestor(*node);
 }
 
diff --git a/third_party/blink/renderer/modules/media/webmediaplayer_util.cc b/third_party/blink/renderer/modules/media/webmediaplayer_util.cc
index 9618f34..38f3e101 100644
--- a/third_party/blink/renderer/modules/media/webmediaplayer_util.cc
+++ b/third_party/blink/renderer/modules/media/webmediaplayer_util.cc
@@ -106,6 +106,7 @@
     case media::PIPELINE_ERROR_DECODE:
     case media::PIPELINE_ERROR_ABORT:
     case media::PIPELINE_ERROR_INVALID_STATE:
+    case media::PIPELINE_ERROR_HARDWARE_CONTEXT_RESET:
     case media::CHUNK_DEMUXER_ERROR_APPEND_FAILED:
     case media::CHUNK_DEMUXER_ERROR_EOS_STATUS_DECODE_ERROR:
     case media::AUDIO_RENDERER_ERROR:
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
index 7eae8a58..7893222e 100644
--- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
+++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.cc
@@ -243,173 +243,6 @@
   }
 }
 
-// Returns true if the fraction n/d is an integer or a half-value. The
-// denominator 'd' must be strictly positive.
-bool IsIntegerOrHalfValue(int n, int d) {
-  int rem = n % d;
-  if (rem == 0)
-    return true;
-  if (d % 2 != 0)
-    return false;
-  int half_d = d / 2;
-  return rem == half_d || rem == -half_d;
-}
-
-// Validates the 'clap' (clean aperture) property in |image| and stores the
-// width, height, leftmost pixel, and topmost line of the clean aperture in the
-// output parameters. Returns whether the 'clap' property is valid.
-bool ValidateClapProperty(const avifImage* image,
-                          int& clap_width,
-                          int& clap_height,
-                          int& clap_leftmost,
-                          int& clap_topmost) {
-  // Although the fields in the CleanApertureBox are encoded as
-  // 'unsigned int(32)', apparently they should be interpreted as 32-bit
-  // signed integers. See also the "Clean Aperture ('clap')" section in the
-  // QuickTime File Format Specification.
-  const int clap_width_n = static_cast<int>(image->clap.widthN);
-  const int clap_width_d = static_cast<int>(image->clap.widthD);
-  const int clap_height_n = static_cast<int>(image->clap.heightN);
-  const int clap_height_d = static_cast<int>(image->clap.heightD);
-  const int horiz_off_n = static_cast<int>(image->clap.horizOffN);
-  const int horiz_off_d = static_cast<int>(image->clap.horizOffD);
-  const int vert_off_n = static_cast<int>(image->clap.vertOffN);
-  const int vert_off_d = static_cast<int>(image->clap.vertOffD);
-  // ISO/IEC 14496-12:2020, Section 12.1.4.1:
-  //   For horizOff and vertOff, D shall be strictly positive and N may be
-  //   positive or negative. For cleanApertureWidth and cleanApertureHeight,
-  //   N shall be positive and D shall be strictly positive.
-  //
-  // For cleanApertureWidth and cleanApertureHeight, we additionally require
-  // that N be nonzero. Restricting to nonempty clean apertures preserves the
-  // property that AVIF image size is at least 1x1, whether the image has a
-  // 'clap' property or not.
-  if (clap_width_d <= 0 || clap_height_d <= 0 || horiz_off_d <= 0 ||
-      vert_off_d <= 0) {
-    DVLOG(1) << "Some clean aperture denominator is not strictly positive";
-    return false;
-  }
-  if (clap_width_n <= 0 || clap_height_n <= 0) {
-    DVLOG(1) << "Clean aperture width or height numerator is not strictly "
-                "positive";
-    return false;
-  }
-
-  // ISO/IEC 23000-22:2019/DAM 2:2021, Section 7.3.6.7:
-  //   The clean aperture property is restricted according to the chroma
-  //   sampling format of the input image (4:4:4, 4:2:2:, 4:2:0, or 4:0:0) as
-  //   follows:
-  //   - when the image is 4:0:0 (monochrome) or 4:4:4, the horizontal and
-  //     vertical cropped offsets and widths shall be integers;
-  //   - when the image is 4:2:2 the horizontal cropped offset and width
-  //     shall be even numbers and the vertical values shall be integers;
-  //   - when the image is 4:2:0 both the horizontal and vertical cropped
-  //     offsets and widths shall be even numbers.
-  //
-  // These requirements don't seem correct or complete. So we follow the
-  // spirit but not the letter of these requirements. Our requirements are as
-  // follows:
-  //   - cleanApertureWidth and cleanApertureHeight shall be integers;
-  //   - horizOff and vertOff shall be integers or half-values[1];
-  //   - The leftmost pixel and the topmost line of the clean aperture[2]
-  //     shall be integers;
-  //   - If chroma is subsampled horizontally (i.e., 4:2:2 and 4:2:0), the
-  //     leftmost pixel of the clean aperture shall be even numbers;
-  //   - If chroma is subsampled vertically (i.e., 4:2:0), the topmost line
-  //     of the clean aperture shall be even numbers.
-  //
-  //  [1] For example, to crop 16x16 to 15x15, horizOff and vertOff must be
-  //      half-values.
-  //  [2] Defined at the end of ISO/IEC 14496-12:2020, Section 12.1.4.1.
-  //
-  //  See also https://github.com/MPEGGroup/MIAF/issues/8.
-  if (clap_width_n % clap_width_d != 0 || clap_height_n % clap_height_d != 0) {
-    DVLOG(1) << "Clean aperture width or height is not an integer";
-    return false;
-  }
-  clap_width = clap_width_n / clap_width_d;
-  clap_height = clap_height_n / clap_height_d;
-  if (!IsIntegerOrHalfValue(horiz_off_n, horiz_off_d) ||
-      !IsIntegerOrHalfValue(vert_off_n, vert_off_d)) {
-    DVLOG(1) << "Clean aperture horizontal or vertical offset is not an "
-                "integer or half-value";
-    return false;
-  }
-  // horizOff * 2
-  const int64_t horiz_off_2 =
-      static_cast<int64_t>(horiz_off_n) * 2 / horiz_off_d;
-  // vertOff * 2
-  const int64_t vert_off_2 = static_cast<int64_t>(vert_off_n) * 2 / vert_off_d;
-  if (image->width > INT_MAX || image->height > INT_MAX) {
-    DVLOG(1) << "Image width or height is greater than INT_MAX";
-    return false;
-  }
-  const int width = static_cast<int>(image->width);
-  const int height = static_cast<int>(image->height);
-  // Picture center of the image is at pcX and pcY, defined as follows:
-  //   pcX = horizOff + (width - 1)/2
-  //   pcY = vertOff + (height - 1)/2
-  //
-  // pcX * 2
-  const int64_t center_x_2 = horiz_off_2 + (width - 1);
-  // pcY * 2
-  const int64_t center_y_2 = vert_off_2 + (height - 1);
-  // The leftmost and rightmost pixels of the clean aperture fall at:
-  //   pcX - (cleanApertureWidth - 1)/2
-  //   pcX + (cleanApertureWidth - 1)/2
-  //
-  // Leftmost pixel * 2
-  const int64_t leftmost_2 = center_x_2 - (clap_width - 1);
-  // Rightmost pixel * 2
-  const int64_t rightmost_2 = center_x_2 + (clap_width - 1);
-  if (leftmost_2 < 0 || rightmost_2 > 2 * (width - 1)) {
-    DVLOG(1) << "Leftmost or rightmost pixel of clean aperture is out of the "
-                "image's bounds";
-    return false;
-  }
-  // The topmost and bottommost lines of the clean aperture fall at:
-  //   pcY - (cleanApertureHeight - 1)/2
-  //   pcY + (cleanApertureHeight - 1)/2
-  //
-  // Topmost line * 2
-  const int64_t topmost_2 = center_y_2 - (clap_height - 1);
-  // Bottommost line * 2
-  const int64_t bottommost_2 = center_y_2 + (clap_height - 1);
-  if (topmost_2 < 0 || bottommost_2 > 2 * (height - 1)) {
-    DVLOG(1) << "Topmost or bottommost line of clean aperture is out of the "
-                "image's bounds";
-    return false;
-  }
-  if (leftmost_2 % 2 != 0) {
-    DVLOG(1) << "Leftmost pixel of clean aperture is not an integer: "
-             << leftmost_2 << " / 2";
-    return false;
-  }
-  clap_leftmost = static_cast<int>(leftmost_2 / 2);
-  if (topmost_2 % 2 != 0) {
-    DVLOG(1) << "Topmost line of clean aperture is not an integer: "
-             << topmost_2 << " / 2";
-    return false;
-  }
-  clap_topmost = static_cast<int>(topmost_2 / 2);
-  if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV422 ||
-      image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420) {
-    if (clap_leftmost % 2 != 0) {
-      DVLOG(1) << "Leftmost pixel of clean aperture is not an even number: "
-               << clap_leftmost;
-      return false;
-    }
-  }
-  if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420) {
-    if (clap_topmost % 2 != 0) {
-      DVLOG(1) << "Topmost line of clean aperture is not an even number: "
-               << clap_topmost;
-      return false;
-    }
-  }
-  return true;
-}
-
 }  // namespace
 
 namespace blink {
@@ -524,8 +357,8 @@
       SetFailed();
     return;
   }
-  const auto* image = decoded_image_;
 
+  const auto* image = decoder_->image;
   DCHECK(!image->alphaPlane);
   static_assert(cc::YUVIndex::kY == static_cast<cc::YUVIndex>(AVIF_CHAN_Y), "");
   static_assert(cc::YUVIndex::kU == static_cast<cc::YUVIndex>(AVIF_CHAN_U), "");
@@ -663,16 +496,6 @@
   return color_transform_.get();
 }
 
-// static
-bool AVIFImageDecoder::ValidateClapPropertyForTesting(const avifImage* image,
-                                                      int& clap_width,
-                                                      int& clap_height,
-                                                      int& clap_leftmost,
-                                                      int& clap_topmost) {
-  return ValidateClapProperty(image, clap_width, clap_height, clap_leftmost,
-                              clap_topmost);
-}
-
 void AVIFImageDecoder::ParseMetadata() {
   if (!UpdateDemuxer())
     SetFailed();
@@ -715,7 +538,8 @@
       SetFailed();
     return;
   }
-  const auto* image = decoded_image_;
+
+  const auto* image = decoder_->image;
 
   ImageFrame& buffer = frame_buffer_cache_[index];
   DCHECK_EQ(buffer.GetStatus(), ImageFrame::kFrameEmpty);
@@ -841,8 +665,8 @@
     decoder_->ignoreXMP = AVIF_TRUE;
     decoder_->ignoreExif = AVIF_TRUE;
 
-    // Turn off libavif's 'clap' (clean aperture) property validation. (We do
-    // our own validation.)
+    // Turn off libavif's 'clap' (clean aperture) property validation. (We
+    // ignore the 'clap' property.)
     decoder_->strictFlags &= ~AVIF_STRICT_CLAP_VALID;
 
     avif_io_.destroy = nullptr;
@@ -885,8 +709,6 @@
 
   DCHECK_GT(decoder_->imageCount, 0);
   decoded_frame_count_ = decoder_->imageCount;
-  container_width_ = container->width;
-  container_height_ = container->height;
   bit_depth_ = container->depth;
   decode_to_half_float_ =
       ImageIsHighBitDepth() &&
@@ -991,24 +813,7 @@
                                                  &yuv_color_space_) &&
       // TODO(crbug.com/911246): Support color space transforms for YUV decodes.
       !ColorTransform();
-
-  unsigned width = container->width;
-  unsigned height = container->height;
-  // If the image is cropped, pass the size of the cropped image (the clean
-  // aperture) to SetSize().
-  if (container->transformFlags & AVIF_TRANSFORM_CLAP) {
-    int clap_width;
-    int clap_height;
-    if (!ValidateClapProperty(container, clap_width, clap_height,
-                              clap_leftmost_, clap_topmost_)) {
-      DVLOG(1) << "Ignore the 'clap' property and show the full image";
-      ignore_clap_ = true;
-    } else {
-      width = clap_width;
-      height = clap_height;
-    }
-  }
-  return SetSize(width, height);
+  return SetSize(container->width, container->height);
 }
 
 avifResult AVIFImageDecoder::DecodeImage(size_t index) {
@@ -1021,10 +826,9 @@
 
   const auto* image = decoder_->image;
   // Frame size must be equal to container size.
-  if (image->width != container_width_ || image->height != container_height_) {
-    DVLOG(1) << "Frame size " << image->width << "x" << image->height
-             << " differs from container size " << container_width_ << "x"
-             << container_height_;
+  if (IntSize(image->width, image->height) != Size()) {
+    DVLOG(1) << "Frame size " << IntSize(image->width, image->height)
+             << " differs from container size " << Size();
     return AVIF_RESULT_UNKNOWN_ERROR;
   }
   // Frame bit depth must be equal to container bit depth.
@@ -1037,10 +841,6 @@
     DVLOG(1) << "Frame YUV format must be equal to container YUV format";
     return AVIF_RESULT_UNKNOWN_ERROR;
   }
-
-  decoded_image_ = image;
-  if ((image->transformFlags & AVIF_TRANSFORM_CLAP) && !ignore_clap_)
-    CropDecodedImage();
   return AVIF_RESULT_OK;
 }
 
@@ -1056,36 +856,6 @@
       gfx::ColorTransform::Intent::INTENT_PERCEPTUAL);
 }
 
-void AVIFImageDecoder::CropDecodedImage() {
-  DCHECK_NE(decoded_image_, &cropped_image_);
-  cropped_image_ = *decoded_image_;
-  cropped_image_.width = Size().Width();
-  cropped_image_.height = Size().Height();
-  const size_t bytes_per_pixel = (cropped_image_.depth + 7) / 8;
-  cropped_image_.yuvPlanes[AVIF_CHAN_Y] +=
-      static_cast<size_t>(clap_topmost_) *
-          cropped_image_.yuvRowBytes[AVIF_CHAN_Y] +
-      static_cast<size_t>(clap_leftmost_) * bytes_per_pixel;
-  if (cropped_image_.yuvFormat != AVIF_PIXEL_FORMAT_YUV400) {
-    const int leftmost_uv = UVSize(clap_leftmost_, chroma_shift_x_);
-    const int topmost_uv = UVSize(clap_topmost_, chroma_shift_y_);
-    cropped_image_.yuvPlanes[AVIF_CHAN_U] +=
-        static_cast<size_t>(topmost_uv) *
-            cropped_image_.yuvRowBytes[AVIF_CHAN_U] +
-        static_cast<size_t>(leftmost_uv) * bytes_per_pixel;
-    cropped_image_.yuvPlanes[AVIF_CHAN_V] +=
-        static_cast<size_t>(topmost_uv) *
-            cropped_image_.yuvRowBytes[AVIF_CHAN_V] +
-        static_cast<size_t>(leftmost_uv) * bytes_per_pixel;
-  }
-  if (cropped_image_.alphaPlane) {
-    cropped_image_.alphaPlane +=
-        static_cast<size_t>(clap_topmost_) * cropped_image_.alphaRowBytes +
-        static_cast<size_t>(clap_leftmost_) * bytes_per_pixel;
-  }
-  decoded_image_ = &cropped_image_;
-}
-
 bool AVIFImageDecoder::RenderImage(const avifImage* image, ImageFrame* buffer) {
   const gfx::ColorSpace frame_cs = GetColorSpace(image);
   const bool is_mono = image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400;
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h
index 04320ac..8e83b88d 100644
--- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h
+++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder.h
@@ -49,15 +49,6 @@
 
   gfx::ColorTransform* GetColorTransformForTesting();
 
-  // Exposes the internal function ValidateClapProperty() for testing. Uses only
-  // the following members of |image|: image->clap, image->width, image->height,
-  // image->yuvFormat.
-  static bool ValidateClapPropertyForTesting(const avifImage* image,
-                                             int& clap_width,
-                                             int& clap_height,
-                                             int& clap_leftmost,
-                                             int& clap_topmost);
-
  private:
   struct AvifIOData {
     blink::SegmentReader* reader = nullptr;
@@ -86,15 +77,12 @@
 
   // Decodes the frame at index |index| and checks if the frame's size, bit
   // depth, and YUV format matches those reported by the container. The decoded
-  // frame is available in decoded_image_.
+  // frame is available in decoder_->image.
   avifResult DecodeImage(size_t index);
 
   // Updates or creates |color_transform_| for YUV-to-RGB conversion.
   void UpdateColorTransform(const gfx::ColorSpace& frame_cs, int bit_depth);
 
-  // Crops |decoded_image_|.
-  void CropDecodedImage();
-
   // Renders |image| in |buffer|. Returns whether |image| was rendered
   // successfully.
   bool RenderImage(const avifImage* image, ImageFrame* buffer);
@@ -104,13 +92,6 @@
   void ColorCorrectImage(ImageFrame* buffer);
 
   bool have_parsed_current_data_ = false;
-  // The image width and height (before cropping, if any) from the container.
-  //
-  // Note: container_width_, container_height_, decoder_->image->width, and
-  // decoder_->image->height are the width and height of the full image. Size()
-  // returns the size of the cropped image (the clean aperture).
-  uint32_t container_width_ = 0;
-  uint32_t container_height_ = 0;
   // The bit depth from the container.
   uint8_t bit_depth_ = 0;
   bool decode_to_half_float_ = false;
@@ -120,21 +101,6 @@
   avifPixelFormat avif_yuv_format_ = AVIF_PIXEL_FORMAT_NONE;
   size_t decoded_frame_count_ = 0;
   SkYUVColorSpace yuv_color_space_ = SkYUVColorSpace::kIdentity_SkYUVColorSpace;
-  // Whether the 'clap' (clean aperture) property should be ignored, e.g.
-  // because the 'clap' property is invalid or unsupported.
-  bool ignore_clap_ = false;
-  // The leftmost pixel and topmost line of the clean aperture. Used only when
-  // the image has a 'clap' (clean aperture) property.
-  int clap_leftmost_ = 0;
-  int clap_topmost_ = 0;
-  // A copy of decoder_->image with the width, height, and plane buffers
-  // adjusted to those of the clean aperture. Used only when the image has a
-  // 'clap' (clean aperture) property.
-  avifImage cropped_image_;
-  // Set by a successful DecodeImage() call to either decoder_->image or
-  // &cropped_image_ depending on whether the image has a 'clap' (clean
-  // aperture) property.
-  const avifImage* decoded_image_ = nullptr;
   std::unique_ptr<avifDecoder, void (*)(avifDecoder*)> decoder_{nullptr,
                                                                 nullptr};
   avifIO avif_io_ = {};
diff --git a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
index 8a72a545..3d08cf3 100644
--- a/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
+++ b/third_party/blink/renderer/platform/image-decoders/avif/avif_image_decoder_test.cc
@@ -482,20 +482,6 @@
          {gfx::Point(2, 2), SkColorSetARGB(255, 255, 0, 0)},
      }},
 #endif
-    {"/images/resources/avif/blue-and-magenta-crop.avif",
-     8,
-     ColorType::kRgbA,
-     ImageDecoder::kLosslessFormat,
-     ImageDecoder::kAlphaNotPremultiplied,
-     ColorBehavior::Tag(),
-     ImageOrientationEnum::kOriginTopLeft,
-     1,
-     {
-         // The clean aperture's size is 180x100.
-         {gfx::Point(0, 0), SkColorSetARGB(255, 0, 0, 255)},      // blue
-         {gfx::Point(90, 50), SkColorSetARGB(255, 255, 0, 255)},  // magenta
-         {gfx::Point(179, 99), SkColorSetARGB(255, 0, 0, 255)},   // blue
-     }},
     {"/images/resources/avif/red-full-range-angle-1-420-8bpc.avif",
      8,
      ColorType::kRgb,
@@ -897,54 +883,6 @@
   EXPECT_TRUE(decoder->IsSizeAvailable());
 }
 
-// Verifies that an invalid 'clap' (clean aperture) image property is handled by
-// ignoring the 'clap' property and showing the full image.
-TEST(StaticAVIFTests, InvalidClapPropertyHandling) {
-  // The first image has a valid 'clap' property. The full image has size
-  // 320x280. The clean aperture has size 180x100, located at (40, 80) of the
-  // full image.
-  constexpr int kClapX = 40;
-  constexpr int kClapY = 80;
-  constexpr int kClapWidth = 180;
-  constexpr int kClapHeight = 100;
-  std::unique_ptr<ImageDecoder> decoder1 = CreateAVIFDecoder();
-  decoder1->SetData(
-      ReadFile("/images/resources/avif/blue-and-magenta-crop.avif"), true);
-  ASSERT_TRUE(decoder1->IsSizeAvailable());
-  IntSize size1 = decoder1->Size();
-  ASSERT_EQ(size1.Width(), kClapWidth);
-  ASSERT_EQ(size1.Height(), kClapHeight);
-  ImageFrame* frame1 = decoder1->DecodeFrameBufferAtIndex(0);
-  ASSERT_TRUE(frame1);
-  EXPECT_EQ(ImageFrame::kFrameComplete, frame1->GetStatus());
-  EXPECT_FALSE(decoder1->Failed());
-  const SkBitmap& bitmap1 = frame1->Bitmap();
-
-  // The second image is the same as the first image except that the 'clap'
-  // property is invalid. In this case the full image is shown.
-  std::unique_ptr<ImageDecoder> decoder2 = CreateAVIFDecoder();
-  decoder2->SetData(
-      ReadFile("/images/resources/avif/blue-and-magenta-crop-invalid.avif"),
-      true);
-  ASSERT_TRUE(decoder2->IsSizeAvailable());
-  IntSize size2 = decoder2->Size();
-  ASSERT_EQ(size2.Width(), 320);
-  ASSERT_EQ(size2.Height(), 280);
-  ImageFrame* frame2 = decoder2->DecodeFrameBufferAtIndex(0);
-  ASSERT_TRUE(frame2);
-  EXPECT_EQ(ImageFrame::kFrameComplete, frame2->GetStatus());
-  EXPECT_FALSE(decoder2->Failed());
-  const SkBitmap& bitmap2 = frame2->Bitmap();
-
-  // Compare pixel data.
-  for (int row = 0; row < kClapHeight; ++row) {
-    for (int col = 0; col < kClapWidth; ++col) {
-      EXPECT_EQ(bitmap1.getColor(/*x=*/col, /*y=*/row),
-                bitmap2.getColor(/*x=*/kClapX + col, /*y=*/kClapY + row));
-    }
-  }
-}
-
 using StaticAVIFColorTests = ::testing::TestWithParam<StaticColorCheckParam>;
 
 INSTANTIATE_TEST_CASE_P(Parameterized,
@@ -1022,116 +960,4 @@
   }
 }
 
-struct AVIFClapPropertyParam {
-  uint32_t width;
-  uint32_t height;
-  avifPixelFormat yuv_format;
-  avifCleanApertureBox clap;
-
-  bool expected_result;
-  int expected_clap_width;
-  int expected_clap_height;
-  int expected_clap_leftmost;
-  int expected_clap_topmost;
-};
-
-AVIFClapPropertyParam kAVIFClapPropertyTestParams[] = {
-    //////////////////////////////////////////////////
-    // Negative tests:
-
-    // Zero or negative denominators.
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 0, 132, 1, 0, 1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, -1, 132, 1, 0, 1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 0, 0, 1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, -1, 0, 1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 1, 0, 0, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 1, 0, -1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 1, 0, 1, 0, 0}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 1, 0, 1, 0, -1}, false},
-    // Zero or negative clean aperture width or height.
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {-96, 1, 132, 1, 0, 1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {0, 1, 132, 1, 0, 1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, -132, 1, 0, 1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 0, 1, 0, 1, 0, 1}, false},
-    // Clean aperture width or height is not an integer.
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 5, 132, 1, 0, 1, 0, 1}, false},
-    {120, 160, AVIF_PIXEL_FORMAT_YUV420, {96, 1, 132, 5, 0, 1, 0, 1}, false},
-    // pcX = 103 + (722 - 1)/2 = 463.5
-    // pcY = -308 + (1024 - 1)/2 = 203.5
-    // leftmost = 463.5 - (385 - 1)/2 = 271.5 (not an integer)
-    // topmost = 203.5 - (330 - 1)/2 = 39
-    {722,
-     1024,
-     AVIF_PIXEL_FORMAT_YUV420,
-     {385, 1, 330, 1, 103, 1, -308, 1},
-     false},
-    // pcX = -308 + (1024 - 1)/2 = 203.5
-    // pcY = 103 + (722 - 1)/2 = 463.5
-    // leftmost = 203.5 - (330 - 1)/2 = 39
-    // topmost = 463.5 - (385 - 1)/2 = 271.5 (not an integer)
-    {1024,
-     722,
-     AVIF_PIXEL_FORMAT_YUV420,
-     {330, 1, 385, 1, -308, 1, 103, 1},
-     false},
-
-    //////////////////////////////////////////////////
-    // Positive tests:
-
-    // pcX = 0 + (120 - 1)/2 = 59.5
-    // pcY = 0 + (160 - 1)/2 = 79.5
-    // leftmost = 59.5 - (96 - 1)/2 = 12
-    // topmost = 79.5 - (132 - 1)/2 = 14
-    {120,
-     160,
-     AVIF_PIXEL_FORMAT_YUV420,
-     {96, 1, 132, 1, 0, 1, 0, 1},
-     true,
-     96,
-     132,
-     12,
-     14},
-    // pcX = -30 + (120 - 1)/2 = 29.5
-    // pcY = -40 + (160 - 1)/2 = 39.5
-    // leftmost = 29.5 - (60 - 1)/2 = 0
-    // topmost = 39.5 - (80 - 1)/2 = 0
-    {120,
-     160,
-     AVIF_PIXEL_FORMAT_YUV420,
-     {60, 1, 80, 1, -30, 1, -40, 1},
-     true,
-     60,
-     80,
-     0,
-     0},
-};
-
-using AVIFClapPropertyTest = ::testing::TestWithParam<AVIFClapPropertyParam>;
-
-INSTANTIATE_TEST_CASE_P(Parameterized,
-                        AVIFClapPropertyTest,
-                        ::testing::ValuesIn(kAVIFClapPropertyTestParams));
-
-TEST_P(AVIFClapPropertyTest, ValidateClapProperty) {
-  const AVIFClapPropertyParam& param = GetParam();
-  avifImage image;
-  image.width = param.width;
-  image.height = param.height;
-  image.yuvFormat = param.yuv_format;
-  image.clap = param.clap;
-  int clap_width = -1;
-  int clap_height = -1;
-  int clap_leftmost = -1;
-  int clap_topmost = -1;
-  EXPECT_EQ(AVIFImageDecoder::ValidateClapPropertyForTesting(
-                &image, clap_width, clap_height, clap_leftmost, clap_topmost),
-            param.expected_result);
-  if (param.expected_result) {
-    EXPECT_EQ(clap_width, param.expected_clap_width);
-    EXPECT_EQ(clap_height, param.expected_clap_height);
-    EXPECT_EQ(clap_leftmost, param.expected_clap_leftmost);
-    EXPECT_EQ(clap_topmost, param.expected_clap_topmost);
-  }
-}
-
 }  // namespace blink
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 0b1f54d..4381961 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -681,6 +681,39 @@
 crbug.com/882385 external/wpt/css/css-contain/quote-scoping-003.html [ Failure ]
 crbug.com/882385 external/wpt/css/css-contain/quote-scoping-004.html [ Failure ]
 
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-bg-001.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-bg-002.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-bg-003.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-bg-004.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-dir-001.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-dir-002.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-dir-003.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-dir-004.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-overflow-001.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-overflow-002.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-overflow-003.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-overflow-004.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-w-m-001.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-w-m-002.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-w-m-003.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-body-w-m-004.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-bg-001.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-bg-002.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-bg-003.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-bg-004.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-dir-001.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-dir-002.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-dir-003.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-dir-004.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-overflow-001.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-overflow-002.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-overflow-003.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-overflow-004.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-w-m-001.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-w-m-002.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-w-m-003.html [ Failure ]
+crbug.com/1215265 external/wpt/css/css-contain/contain-html-w-m-004.html [ Failure ]
+
 # [css-align]
 
 crbug.com/599828 external/wpt/css/css-flexbox/abspos/flex-abspos-staticpos-align-content-001.html [ Failure ]
@@ -2485,10 +2518,6 @@
 crbug.com/958381 [ Mac ] external/wpt/css/CSS2/tables/table-anonymous-objects-206.xht [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 external/wpt/css/css-contain/contain-body-overflow-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-dir-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-overflow-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-dir-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCSctpTransport-maxChannels.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCSctpTransport-maxChannels.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/getstats.html [ Timeout ]
@@ -2497,17 +2526,12 @@
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/simulcast/basic.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-dir-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-bg-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-bg-002.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-send.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-send.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-bg-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/simplecall.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/simplecall.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCDTMFSender-insertDTMF.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCDTMFSender-insertDTMF.https.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-bg-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/protocol/rtp-clockrate.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/rtp-clockrate.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc-extensions/RTCRtpSynchronizationSource-captureTimestamp.html [ Timeout ]
@@ -2516,63 +2540,30 @@
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc-extensions/RTCRtpSynchronizationSource-senderCaptureTimeOffset.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-extensions-senderCaptureTimeOffset/external/wpt/webrtc-extensions/RTCRtpSynchronizationSource-senderCaptureTimeOffset.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-extensions-senderCaptureTimeOffset/external/wpt/webrtc-extensions/RTCRtpSynchronizationSource-senderCaptureTimeOffset.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-overflow-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-overflow-001.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-bg-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-overflow-003.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCSctpTransport-events.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCSctpTransport-events.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-bg-003.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/getstats.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/getstats.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-overflow-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-dir-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCDataChannel-send.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCDataChannel-send.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-w-m-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-w-m-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-w-m-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/simulcast/getStats.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/simulcast/getStats.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCDataChannel-iceRestart.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCDataChannel-iceRestart.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-w-m-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-dir-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-overflow-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-bg-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-dir-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-w-m-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-w-m-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-overflow-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCPeerConnection-createDataChannel.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-createDataChannel.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-legacy.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-legacy.https.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-bg-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-w-m-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-dir-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-overflow-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-overflow-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-bg-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-dir-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-dir-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-overflow-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-bg-002.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCPeerConnection-iceConnectionState-disconnected.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-iceConnectionState-disconnected.https.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-w-m-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-bg-002.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-overflow-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-dir-004.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/simulcast/h264.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/simulcast/h264.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/protocol/dtls-fingerprint-validation.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/dtls-fingerprint-validation.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-overflow-004.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc-encoded-transform/RTCEncodedAudioFrame-serviceworker-failure.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc-encoded-transform/RTCEncodedAudioFrame-serviceworker-failure.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Timeout ]
@@ -2581,90 +2572,36 @@
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCDataChannel-send-blob-order.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/protocol/ice-state.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/ice-state.https.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-w-m-002.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCIceTransport.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCIceTransport.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-bg-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-w-m-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCDataChannel-bufferedAmount.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCDataChannel-bufferedAmount.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-dir-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-dir-001.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-w-m-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-dir-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-bg-003.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-overflow-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-dir-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-w-m-003.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-iceConnectionState-disconnected.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-iceConnectionState-disconnected.https.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-bg-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-bg-001.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc-stats/getStats-remote-candidate-address.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc-stats/getStats-remote-candidate-address.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-bg-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-w-m-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-overflow-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-w-m-004.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-iceRestart.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-iceRestart.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-bg-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-w-m-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-dir-002.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCDtlsTransport-state.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCDtlsTransport-state.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-bg-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-w-m-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-bg-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-overflow-004.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-overflow-002.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-dir-003.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCIceTransport.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCIceTransport.html [ Timeout ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-w-m-004.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/ice-state.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/ice-state.https.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-w-m-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-w-m-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-w-m-001.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-bg-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-bg-002.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-overflow-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-overflow-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-bg-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-dir-002.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-overflow-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-bg-003.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-dir-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-overflow-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-bg-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-dir-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-html-overflow-002.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-w-m-003.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/rtp-clockrate.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/rtp-clockrate.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-overflow-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-w-m-004.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-html-w-m-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-dir-003.html [ Failure ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/simplecall.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/simplecall.https.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Timeout ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-html-dir-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-dir-004.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-overflow-002.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-contain/contain-body-w-m-001.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/contain-body-dir-002.html [ Failure ]
-crbug.com/626703 virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-body-dir-002.html [ Failure ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/split.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDTMFSender-insertDTMF.https.html [ Timeout ]
@@ -6989,7 +6926,7 @@
 crbug.com/1209223 virtual/shared_array_buffer_on_desktop/external/wpt/xhr/formdata/constructor-formelement.html [ Failure ]
 crbug.com/1209223 [ Mac10.15 ] virtual/shared_array_buffer_on_desktop/http/tests/devtools/a11y-axe-core/sources/scope-pane-a11y-test.js [ Timeout ]
 crbug.com/1209223 virtual/synchronous_html_parser/external/wpt/html/semantics/forms/form-submission-0/newline-normalization.html [ Failure ]
-crbug.com/1209223 virtual/synchronous_html_parser/external/wpt/html/semantics/forms/the-textarea-element/wrapping-transformation.window.html [ Failure ]
+crbug.com/1167095 virtual/synchronous_html_parser/external/wpt/html/semantics/forms/the-textarea-element/wrapping-transformation.window.html [ Failure ]
 crbug.com/1209223 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-mandatory-getStats.https.html [ Failure ]
 crbug.com/1209223 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html [ Failure ]
 
@@ -6998,9 +6935,6 @@
 crbug.com/1213322 [ Mac ] external/wpt/html/browsers/the-window-object/named-access-on-the-window-object/window-named-properties.html [ Pass Failure ]
 crbug.com/1213322 [ Mac ] virtual/css-calc-infinity-and-nan/external/wpt/css/css-values/minmax-percentage-serialize.html [ Pass Failure ]
 
-# Sheriff on 2021-05-27
-crbug.com/1213718 virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/* [ Pass Failure ]
-
 # Do not retry slow tests that also timeouts
 crbug.com/1210687 [ Mac10.15 ] fast/events/open-window-from-another-frame.html [ Pass Timeout ]
 crbug.com/1210687 [ Mac10.15 ] http/tests/devtools/a11y-axe-core/sources/scope-pane-a11y-test.js [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 3c374a2..d2d710359 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1049,7 +1049,8 @@
               "accessibility/virtual-node-parent-removal.html",
               "accessibility/virtual-node-build-parent.html",
               "accessibility/virtual-node-build-parent-multiple.html",
-              "accessibility/virtual-node-removed-from-document.html"],
+              "accessibility/virtual-node-removed-from-document.html",
+              "accessibility/virtual-node-repair-document.html"],
     "args": ["--force-renderer-accessibility"]
   },
   {
diff --git a/third_party/blink/web_tests/accessibility/virtual-node-repair-document.html b/third_party/blink/web_tests/accessibility/virtual-node-repair-document.html
new file mode 100644
index 0000000..0c097ff
--- /dev/null
+++ b/third_party/blink/web_tests/accessibility/virtual-node-repair-document.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+
+<!--
+  Validate that removing an accessible node from document and adding
+  it back does not cause any exception.
+-->
+<script>
+test(function() {
+    var childAccessibleNode = new AccessibleNode();
+    childAccessibleNode.role = "button";
+    document.body.accessibleNode.appendChild(childAccessibleNode);
+
+    var axBody = accessibilityController.rootElement
+      .childAtIndex(0).childAtIndex(0);
+    var axChild = axBody.childAtIndex(0);
+    assert_equals(axChild.role, "AXRole: AXButton");
+
+    // Detach childAccessibleNode from document will also remove the
+    // accessible node's internal reference to document.
+    document.body.accessibleNode.removeChild(childAccessibleNode);
+
+    // Validate that adding childAccessibleNode back to document also
+    // restores its internal reference to document, otherwise
+    // exception will occur.
+    document.body.accessibleNode.appendChild(childAccessibleNode);
+    axChild = axBody.childAtIndex(0);
+    assert_equals(axChild.role, "AXRole: AXButton");
+
+});
+</script>
+
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-001.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-001.html
index 65e6f9c5..c055778f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-001.html
@@ -16,7 +16,10 @@
     background: orange;
     display: block;
 }
-p { direction: ltr; }
+p {
+    margin: 0;
+    direction: ltr;
+}
 body {
     margin: 0 auto 0 0;
     width: 200px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-002.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-002.html
index 12f8fed..31e188f8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-002.html
@@ -16,7 +16,10 @@
     background: orange;
     display: block;
 }
-p { direction: ltr; }
+p {
+    margin: 0;
+    direction: ltr;
+}
 body {
     margin: 0 auto 0 0;
     width: 200px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-003.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-003.html
index 07bd8846..cd01c6f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-003.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-003.html
@@ -16,7 +16,10 @@
     background: orange;
     display: block;
 }
-p { direction: ltr; }
+p {
+    margin: 0;
+    direction: ltr;
+}
 body {
     margin: 0 auto 0 0;
     width: 200px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-004.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-004.html
index b7bbc14..8b39b43 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-004.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-dir-004.html
@@ -16,7 +16,10 @@
     background: orange;
     display: block;
 }
-p { direction: ltr; }
+p {
+    margin: 0;
+    direction: ltr;
+}
 body {
     margin: 0 auto 0 0;
     width: 200px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-001.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-001.html
index 7eeae5e..c02c2e2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-001.html
@@ -16,7 +16,10 @@
     background: orange;
     display: block;
 }
-p { direction: ltr; }
+p {
+    margin: 0;
+    direction: ltr;
+}
 body {
     margin: 0 auto 0 0;
     width: 200px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-002.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-002.html
index ad4dd4e..7d23558 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-002.html
@@ -16,7 +16,10 @@
     background: orange;
     display: block;
 }
-p { direction: ltr; }
+p {
+    margin: 0;
+    direction: ltr;
+}
 body {
     margin: 0 auto 0 0;
     width: 200px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-003.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-003.html
index aadc031..125f4b7 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-003.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-003.html
@@ -16,7 +16,10 @@
     background: orange;
     display: block;
 }
-p { direction: ltr; }
+p {
+    margin: 0;
+    direction: ltr;
+}
 body {
     margin: 0 auto 0 0;
     width: 200px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-004.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-004.html
index 4b6d2d3d..af31f64 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-004.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-html-dir-004.html
@@ -16,7 +16,10 @@
     background: orange;
     display: block;
 }
-p { direction: ltr; }
+p {
+    margin: 0;
+    direction: ltr;
+}
 body {
     margin: 0 auto 0 0;
     width: 200px;
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01-ref.html
index 1393046..9365ff2c 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01-ref.html
@@ -1,9 +1,12 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate reference.
 </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -39,3 +42,4 @@
     (forced-color-adjust is set to none.)
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01.html
index 05d3623..7aeb12a 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -6,6 +7,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-01-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -39,3 +42,4 @@
     (forced-color-adjust is set to none.)
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02-ref.html
index c193353..992ced6 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02-ref.html
@@ -1,10 +1,13 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate reference.
   Tests that the backplate feature with a varying number of line breaks.
 </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -46,3 +49,4 @@
     four br tags indicates a new paragraph.
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02.html
index cf52153..1643a6e 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-02.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -7,6 +8,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-02-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -44,3 +47,4 @@
     four br tags indicates a new paragraph.
   </span>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03-ref.html
index b2ed549c..9a4ccff7 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03-ref.html
@@ -1,10 +1,13 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate reference.
   Tests the backplate feature behind lists.
 </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -55,3 +58,4 @@
       in forced colors mode.
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03.html
index 936332a..f8c8f34 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-03.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -7,6 +8,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-03-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -58,3 +61,4 @@
       in forced colors mode.
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04-ref.html
index 52a230ab..ddf54c6b8 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04-ref.html
@@ -1,10 +1,13 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate reference.
   Tests the backplate feature behind links.
 </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -44,3 +47,4 @@
     <a href="https://www.wikipedia.org/">LINK</a>
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04.html
index c9b8136f..be3ab4b 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-04.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -7,6 +8,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-04-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -44,3 +47,4 @@
     <a href="https://www.wikipedia.org/">LINK</a>
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05-ref.html
index d1ea443..28b6f18 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05-ref.html
@@ -1,10 +1,13 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate reference.
   Tests the backplate feature for display inline/relative position.
 </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -46,3 +49,4 @@
     <li>separately.</li>
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05.html
index 69ab33b..7d8f8057 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-05.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -7,6 +8,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-05-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -42,3 +45,4 @@
     <li>separately.</li>
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06-ref.html
index 8d5c988f..642bd72 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06-ref.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate reference.
@@ -7,6 +8,8 @@
   mode.
 </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -38,3 +41,4 @@
     This text should have a backplate in forced colors mode.
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06.html
index c45a25a54..49a8429 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-06.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -9,6 +10,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-06-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -39,3 +42,4 @@
     </span>
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08-ref.html
index 18df12e..6cefe66b 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08-ref.html
@@ -1,10 +1,13 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
     Forced colors mode - backplate reference.
     Tests backplate is drawn when text is located outside the cull rect.
   </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -52,3 +55,4 @@
   }
   onload = scroll;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08.html
index 829d7390..2049e3e 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-08.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -7,6 +8,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-08-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -44,3 +47,4 @@
   }
   onload = scroll;
 </script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09-ref.html
index 51aca00..2bbe08a 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09-ref.html
@@ -1,10 +1,13 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate reference.
   Tests that backplate is not drawn above floats.
 </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -32,3 +35,4 @@
     the floating image.
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09.html
index 4e9f517e..467a23c1 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-09.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -7,6 +8,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-09-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -27,3 +30,4 @@
     the floating image.
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10-ref.html
index b5b58bd..35eb521 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10-ref.html
@@ -1,10 +1,13 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate reference.
   Tests that backplates of overlapping inline boxes do not overlap.
 </title>
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -33,3 +36,4 @@
     </div>
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10.html
index cc7f977..db6c5ad 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-10.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -7,6 +8,8 @@
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-10-ref.html">
 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -28,3 +31,4 @@
     </div>
   </div>
 </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-11-ref.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-11-ref.html
index 29486d5..727afad 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-11-ref.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-11-ref.html
@@ -1,11 +1,15 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
   Tests that backplates are not painted behind hidden elements.
 </title>
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
   }
 </style>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-11.html b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-11.html
index b81b522..a43f79db 100644
--- a/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-11.html
+++ b/third_party/blink/web_tests/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-11.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<html class="reftest-wait">
 <meta charset="utf-8">
 <title>
   Forced colors mode - backplate.
@@ -6,6 +7,8 @@
 </title>
 <link rel="help" href="https://www.w3.org/TR/css-color-adjust-1/#forced">
 <link rel=match href="forced-colors-mode-backplate-11-ref.html">
+<script src="../../common/reftest-wait.js"></script>
+<link rel="preload" as="image" href="../resources/test-image.jpg" onload="takeScreenshot()" />
 <style>
   body {
     background-image: url("../resources/test-image.jpg");
@@ -18,3 +21,4 @@
 <div style="visibility: collapse;">
   No blackplate should be painted in forced colors mode.
 </div>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/charset-2.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/charset-2.html
new file mode 100644
index 0000000..5cb435f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/charset-2.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="windows-1250">
+<title>CSS modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css" assert { type: "css"};
+  test(() => {
+    assert_equals(styleSheet.rules[0].style.content, "\"œæ¹¿Ÿ\"");
+  }, "CSS module should be loaded as utf-8 even though document's encoding is windows-1250");
+</script>
+<script type="module">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/windows-1250.css&ct=text/css%3Bcharset=windows-1250" assert { type: "css"};
+  test(() => {
+    assert_not_equals(styleSheet.rules[0].style.content, "\"œæ¹¿Ÿ\"",
+                    'Should be decoded as UTF-8');
+  }, "CSS module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header, and this document's encoding is windows-1250");
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/charset.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/charset.html
new file mode 100644
index 0000000..8b72481
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/charset.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS modules: UTF-8 decoding</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script type="module" onerror="unreachable()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css&ct=text/css%3Bcharset=utf-8" assert { type: "css"};
+  test(() => {
+    assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+  }, "CSS module should be loaded as utf-8 when charset=utf8 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css&ct=text/css%3Bcharset=shift-jis" assert { type: "css"};
+  test(() => {
+    assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+  }, "CSS module should be loaded as utf-8 when charset=shift-jis is specified");
+</script>
+<script type="module" onerror="unreachable()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css&ct=text/css%3Bcharset=windows-1252" assert { type: "css"};
+  test(() => {
+    assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+  }, "CSS module should be loaded as utf-8 when charset=windows-1252 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/utf-8.css&ct=text/css%3Bcharset=utf-7" assert { type: "css"};;
+  test(() => {
+    assert_equals(styleSheet.rules[0].style.content, "\"śćążź\"");
+  }, "CSS module should be loaded as utf-8 when charset=utf-7 is specified");
+</script>
+<script type="module" onerror="unreachable()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/windows-1250.css&ct=text/css%3Bcharset=windows-1250" assert { type: "css"};
+  test(() => {
+    assert_not_equals(styleSheet.rules[0].style.content, "\"śćążź\"",
+                    'Should be decoded as UTF-8');
+  }, "CSS module should be loaded as utf-8 even if it is encoded in windows-1250 and served with a windows-1250 charset response header");
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/content-type-checking.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/content-type-checking.html
new file mode 100644
index 0000000..105c53c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/content-type-checking.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS modules: Content-Type</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function check(t, styleSheet) {
+  t.step(() => {
+    assert_equals(styleSheet.rules[0].cssText, "#test { background-color: rgb(255, 0, 0); }");
+    t.done();
+  });
+}
+const t1 = async_test("text/css");
+const t2 = async_test("application/css");
+const t3 = async_test("text/html+css");
+const t4 = async_test("text/css;boundary=something");
+const t5 = async_test("text/css;foo=bar");
+</script>
+<script type="module" onerror="t1.unreached_func()()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=text/css" assert { type: "css"};
+  check(t1, styleSheet);
+</script>
+<script type="module" onerror="t2.step_func_done()()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=application/css" assert { type: "css"};
+  t2.unreached_func("Should not have loaded with MIME type application/css")();
+</script>
+<script type="module" onerror="t3.step_func_done()()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=text/html+css" assert { type: "css"};
+  t3.unreached_func("Should not have loaded with MIME type text/html+css")();
+</script>
+<script type="module" onerror="t4.unreached_func()()">
+  import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=text/css;boundary=something" assert { type: "css"};
+  check(t4, styleSheet);
+</script>
+<script type="module" onerror="t5.unreached_func()()">
+import styleSheet from "../serve-with-content-type.py?fn=css-module/resources/basic.css&ct=text/css;foo=bar" assert { type: "css"};
+check(t5, styleSheet);
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html
new file mode 100644
index 0000000..e699ef9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+    <title>css-module-crossorigin</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+    <h1>css-module-crossorigin</h1>
+    <iframe id="import-WithCORS" src="resources/crossorigin-import-with-cors.sub.html"></iframe>
+    <iframe id="import-NoCORS" src="resources/crossorigin-import-without-cors.sub.html"></iframe>
+    <iframe id="import-parseerror-WithCors" src="resources/crossorigin-import-parse-error-with-cors.sub.html"></iframe>
+    <script>
+
+        var tests = [
+                { "obj": async_test("Imported CSS module, cross-origin with CORS"), "id": "import-WithCORS", "expected": "imported CSS: #test { background-color: rgb(255, 0, 0); }" },
+                { "obj": async_test("Imported CSS module, cross-origin, missing CORS ACAO header"), "id": "import-NoCORS", "expected": "error" },
+                { "obj": async_test("Imported CSS module with parse error, cross-origin, with CORS"), "id": "import-parseerror-WithCors", "expected": "imported CSS rules count: 0" },
+            ];
+
+        window.addEventListener("load", function () {
+            tests.forEach(function (test) {
+                var target = document.getElementById(test.id);
+                test.obj.step(function () {
+                    assert_equals(target.contentDocument._log, test.expected, "Unexpected _log value");
+                });
+                test.obj.done();
+            });
+        });
+
+    </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/credentials.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/credentials.sub.html
new file mode 100644
index 0000000..0da573d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/credentials.sub.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+document.cookie = 'milk=1';
+
+const setCookiePromise = fetch(
+    'http://{{domains[www2]}}:{{ports[http][0]}}/cookies/resources/set-cookie.py?name=milk&path=/html/semantics/scripting-1/the-script-element/css-module/',
+    {
+      mode: 'no-cors',
+      credentials: 'include',
+    });
+
+const windowLoadPromise = new Promise(resolve => {
+  window.addEventListener('load', () => {
+    resolve();
+  });
+});
+
+promise_test(t => {
+  const iframe = document.createElement('iframe');
+
+  return Promise.all([setCookiePromise, windowLoadPromise]).then(() => {
+    const messagePromise = new Promise(resolve => {
+      window.addEventListener('message', event => {
+        resolve();
+      });
+    });
+
+    iframe.src = 'resources/credentials-iframe.sub.html';
+    document.body.appendChild(iframe);
+
+    return messagePromise;
+  }).then(() => {
+    const w = iframe.contentWindow;
+
+    assert_equals(w.sameOriginNoneDescendant, true,
+                  'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is not specified and the target is same-origin');
+    assert_equals(w.sameOriginAnonymousDescendant, true,
+                  'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is same-origin');
+    assert_equals(w.sameOriginUseCredentialsDescendant, true,
+                  'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is same-origin');
+    assert_equals(w.crossOriginNoneDescendant, false,
+                  'Descendant CSS modules should not be loaded with the credentials when the crossOrigin attribute is not specified and the target is cross-origin');
+    assert_equals(w.crossOriginAnonymousDescendant, false,
+                  'Descendant CSS modules should not be loaded with the credentials when the crossOrigin attribute is specified with "anonymous" as its value and the target is cross-origin');
+    assert_equals(w.crossOriginUseCredentialsDescendant, true,
+                  'Descendant CSS modules should be loaded with the credentials when the crossOrigin attribute is specified with "use-credentials" as its value and the target is cross-origin');
+});
+}, 'CSS Modules should be loaded with or without the credentials based on the same-origin-ness and the crossOrigin attribute');
+</script>
+<body>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html
index 207d553..c2235be 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html
@@ -37,9 +37,13 @@
             iframe.src = "resources/css-module-at-import-iframe.html";
             iframe.onload = test.step_func_done(function () {
                 assert_equals(iframe.contentDocument.load_error, undefined);
+                assert_equals(iframe.contentDocument.adoptedStyleSheets[0].cssRules.length, 1, "Parser should skip @import rule");
                 assert_not_equals(getComputedStyle(iframe.contentDocument.querySelector('#test'))
                     .backgroundColor, "rgb(255, 0, 0)",
                     "CSS module @import should not succeed");
+                assert_equals(getComputedStyle(iframe.contentDocument.querySelector('#test2'))
+                    .backgroundColor, "rgb(0, 255, 0)",
+                    "Rule after @import should still be applied");
             });
             document.body.appendChild(iframe);
         }, "An @import CSS Module should not load, but should not throw an exception");
@@ -48,12 +52,17 @@
             const iframe = document.createElement("iframe");
             iframe.src = "resources/malformed-iframe.html";
             iframe.onload = test.step_func_done(function () {
+                assert_equals(iframe.contentDocument.load_error, undefined);
+                assert_equals(iframe.contentDocument.adoptedStyleSheets[0].cssRules.length, 1, "Import of malformed CSS should succeed and rules after the parse error should still be parsed");
                 assert_not_equals(getComputedStyle(iframe.contentDocument.querySelector('#test'))
                     .backgroundColor, "rgb(255, 0, 0)",
-                    "Malformed CSS should not load");
+                    "Malformed CSS rule should not be applied");
+                assert_equals(getComputedStyle(iframe.contentDocument.querySelector('#test2'))
+                    .backgroundColor, "rgb(0, 255, 0)",
+                    "Parsing should recover and rules after malformed rules should be applied");
             });
             document.body.appendChild(iframe);
-        }, "Malformed CSS should not load");
+        }, "A parse error should not prevent subsequent rules from being included in a CSS module");
 
         async_test(function (test) {
             const iframe = document.createElement("iframe");
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html
index 4fbc111..1396785 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html
@@ -10,7 +10,8 @@
         promise_test(async function (test) {
             const css_module = await import("./resources/basic.css", { assert: { type: "css" }});
             assert_true(css_module.default instanceof CSSStyleSheet);
-            assert_equals(css_module.default.cssRules[0].cssText, "#test { background-color: red; }");
+            assert_equals(css_module.default.cssRules[0].cssText,
+                "#test { background-color: rgb(255, 0, 0); }");
         }, "Load a CSS module with dynamic import()");
 
         promise_test(function (test) {
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/integrity.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/integrity.html
new file mode 100644
index 0000000..1dd0dad4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/integrity.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>&lt;script> integrity="" with CSS modules</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+window.matchesLog = [];
+window.matchesEvents = [];
+
+window.mismatchesLog = [];
+window.mismatchesEvents = [];
+</script>
+<script type="module" src="resources/integrity-matches.js" integrity="sha384-xvbfmg9iJFHqmCoOS4VNMCwnFPPxEoIlW1Ojzl+fgEd+Wf8Pyez+SMWue+KNovjA"  onload="window.matchesEvents.push('load');" onerror="window.matchesEvents.push('error')"></script>
+<script type="module" src="resources/integrity-mismatches.js" integrity="sha384-doesnotmatch" onload="window.mismatchesEvents.push('load');" onerror="window.mismatchesEvents.push('error')"></script>
+
+<script type="module">
+test(() => {
+  assert_array_equals(window.matchesLog, ["integrity-matches,css:#test { background-color: rgb(255, 0, 0); }"], "The module and its dependency must have executed");
+  assert_array_equals(window.matchesEvents, ["load"], "The load event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a CSS module and allow it to execute when it matches");
+
+test(() => {
+  assert_array_equals(window.mismatchesLog, [], "The module and its dependency must not have executed");
+  assert_array_equals(window.mismatchesEvents, ["error"], "The error event must have fired");
+}, "The integrity attribute must be verified on the top-level of a module loading a CSS module and not allow it to execute when there's a mismatch");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/load-error-events.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/load-error-events.html
new file mode 100644
index 0000000..3457452c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/load-error-events.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<head>
+<title>load/error events for CSS modules</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/load-error-events-helpers.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+</head>
+<script>
+  "use strict";
+
+  var test1_load = event_test('inline, 200, parser-inserted', false, false);
+  var test1_error = event_test('inline, 404, parser-inserted', false, true);
+
+  var test2_load = event_test('src, 200, parser-inserted', true, false);
+  var test2_error = event_test('src, 404, parser-inserted', false, true);
+
+  var test3_dynamic_load = event_test('src, 200, not parser-inserted', true, false);
+  var test3_dynamic_error = event_test('src, 404, not parser-inserted', false, true);
+
+  var test4_dynamic_load = event_test('inline, 200, not parser-inserted', false, false);
+  var test4_dynamic_error = event_test('inline, 404, not parser-inserted', false, true);
+
+  var script3_dynamic_load = document.createElement('script');
+  script3_dynamic_load.setAttribute('type', 'module');
+  script3_dynamic_load.onload = () => onLoad(test3_dynamic_load);
+  script3_dynamic_load.onerror = () => onError(test3_dynamic_load);
+  script3_dynamic_load.src = "./resources/load-error-events.py?test=test3_dynamic_load";
+  document.head.appendChild(script3_dynamic_load);
+
+  var script3_dynamic_error = document.createElement('script');
+  script3_dynamic_error.setAttribute('type', 'module');
+  script3_dynamic_error.onload = () => onLoad(test3_dynamic_error);
+  script3_dynamic_error.onerror = () => onError(test3_dynamic_error);
+  script3_dynamic_error.src = "./resources/load-error-events.py?test=test3_dynamic_error";
+  document.head.appendChild(script3_dynamic_error);
+
+  var script4_dynamic_load = document.createElement('script');
+  script4_dynamic_load.setAttribute('type', 'module');
+  script4_dynamic_load.onload = () => onLoad(test4_dynamic_load);
+  script4_dynamic_load.onerror = () => onError(test4_dynamic_load);
+  script4_dynamic_load.async = true;
+  script4_dynamic_load.appendChild(document.createTextNode(`
+    import "./resources/basic.css" assert { type: "css" };
+    onExecute(test4_dynamic_load);`
+  ));
+  document.head.appendChild(script4_dynamic_load);
+
+  var script4_dynamic_error = document.createElement('script');
+  script4_dynamic_error.setAttribute('type', 'module');
+  script4_dynamic_error.onload = () => onLoad(test4_dynamic_error);
+  script4_dynamic_error.onerror = () => onError(test4_dynamic_error);
+  script4_dynamic_error.async = true;
+  script4_dynamic_error.appendChild(document.createTextNode(`import "./not_found.css" assert { type: "css" };`));
+  document.head.appendChild(script4_dynamic_error);
+</script>
+<script onload="onLoad(test1_load);" onerror="onError(test1_load);" type="module">
+  import "./resources/basic.css" assert { type: "css"};
+  onExecute(test1_load);
+</script>
+<script onload="onLoad(test1_error);" onerror="onError(test1_error);" type="module">
+    import "./not_found.css" assert { type: "css"};
+    onExecute(test1_error);
+</script>
+<script src="./resources/load-error-events.py?test=test2_load" onload="onLoad(test2_load);" onerror="onError(test2_load);" type="module"></script>
+<script src="./resources/load-error-events.py?test=test2_error" onload="onLoad(test2_error);" onerror="onError(test2_error);" type="module"></script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/referrer-policies.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/referrer-policies.sub.html
new file mode 100644
index 0000000..efa53407
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/referrer-policies.sub.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Referrers with CSS module requests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script type="module">
+  // "name" parameter is necessary for bypassing the module map.
+  import referrerSame from "./resources/referrer-checker.py?name=sameNoReferrerPolicy" assert { type: "css"};
+  import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py?name=remoteNoReferrerPolicy" assert { type: "css"};
+
+  const origin = (new URL(location.href)).origin + "/";
+  const originUrl = location.href;
+
+  test(t => {
+    assert_equals(
+        referrerSame.rules[0].style.content, '"' + originUrl + '"',
+        "Referrer URL should be sent for the same-origin top-level script.");
+  }, "Importing a same-origin top-level script with the default referrer policy.");
+
+  test(t => {
+    assert_equals(
+        referrerRemote.rules[0].style.content, '"' + origin + '"',
+        "Referrer origin should be sent for the remote-origin top-level script.");
+  }, "Importing a remote-origin top-level script with the default referrer policy.");
+</script>
+<script type="module" referrerpolicy="origin">
+  import referrerSame from "./resources/referrer-checker.py?name=sameReferrerPolicyOrigin" assert { type: "css"};
+  import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py?name=remoteReferrerPolicyOrigin" assert { type: "css"};
+
+  const origin = (new URL(location.href)).origin + "/";
+
+  test(t => {
+    assert_equals(
+        referrerSame.rules[0].style.content, '"' + origin + '"',
+        "Referrer origin should be sent for the same-origin top-level script.");
+  }, "Importing a same-origin top-level script with the origin policy.");
+
+  test(t => {
+    assert_equals(
+        referrerRemote.rules[0].style.content, '"' + origin + '"',
+        "Referrer origin should be sent for the remote-origin top-level script.");
+  }, "Importing a remote-origin top-level script with the origin policy.");
+
+</script>
+<script type="module" referrerpolicy="no-referrer">
+  import referrerSame from "./resources/referrer-checker.py?name=sameReferrerPolicyNoReferrer" assert { type: "css"};
+  import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py?name=remoteReferrerPolicyNoReferrer" assert { type: "css"};
+
+  test(t => {
+    assert_equals(
+        referrerSame.rules[0].style.content, '""',
+        "No referrer should be sent for the same-origin top-level script.");
+  }, "Importing a same-origin top-level script with the no-referrer policy.");
+
+  test(t => {
+    assert_equals(
+        referrerRemote.rules[0].style.content, '""',
+        "No referrer should be sent for the remote-origin top-level script.");
+  }, "Importing a remote-origin top-level script with the no-referrer policy.");
+
+</script>
+<script type="module" referrerpolicy="unsafe-url">
+  import referrerSame from "./resources/referrer-checker.py?name=sameNoReferrerPolicyUnsafeUrl" assert { type: "css"};
+  import referrerRemote from "http://{{domains[www1]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py?name=remoteNoReferrerPolicyUnsafeUrl" assert { type: "css"};
+
+  const originUrl = location.href;
+
+  test(t => {
+    assert_equals(
+        referrerSame.rules[0].style.content, '"' + originUrl + '"',
+        "Referrer URL should be sent for the same-origin top-level script.");
+  }, "Importing a same-origin top-level script with the unsafe-url referrer policy.");
+
+  test(t => {
+    assert_equals(
+        referrerRemote.rules[0].style.content, '"' + originUrl + '"',
+        "Referrer URL should be sent for the remote-origin top-level script.");
+  }, "Importing a remote-origin top-level script with the unsafe-url referrer policy.");
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/bad-import.css b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/bad-import.css
index 796446b..0ada27b6 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/bad-import.css
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/bad-import.css
@@ -1 +1,4 @@
-@import "basic.css"
\ No newline at end of file
+@import "basic.css";
+#test2 {
+    background-color:#00FF00;
+}
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css
index 3ea2ef45..e034ed9 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css
@@ -1,3 +1,3 @@
 #test {
-    background-color:red;
+    background-color: #FF0000;
 }
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/credentials-iframe.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/credentials-iframe.sub.html
new file mode 100644
index 0000000..38868dc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/credentials-iframe.sub.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+
+<script type="module">
+    import styleSheet from "./cross-origin.py?id=sameOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+    window.sameOriginNoneDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="anonymous">
+    import styleSheet from "./cross-origin.py?id=sameOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+    window.sameOriginAnonymousDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="use-credentials">
+    import styleSheet from "./cross-origin.py?id=sameOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+    window.sameOriginUseCredentialsDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module">
+    import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py?id=crossOriginNoneDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+    window.crossOriginNoneDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="anonymous">
+    import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py?id=crossOriginAnonymousDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+    window.crossOriginAnonymousDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+<script type="module" crossOrigin="use-credentials">
+    import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py?id=crossOriginUseCredentialsDescendant&origin=http://{{host}}:{{ports[http][0]}}" assert { type: "css" };
+    window.crossOriginUseCredentialsDescendant = (styleSheet.cssRules[0].cssText.indexOf(".requestHadCookies") !== -1);
+</script>
+
+<script type="text/javascript">
+window.addEventListener('load', event => {
+  window.parent.postMessage({}, '*');
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py
new file mode 100644
index 0000000..d744fc95
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/cross-origin.py
@@ -0,0 +1,17 @@
+def main(request, response):
+
+    headers = [
+        (b"Content-Type", b"text/css"),
+        (b"Access-Control-Allow-Origin", request.GET.first(b"origin")),
+        (b"Access-Control-Allow-Credentials", b"true")
+    ]
+
+    milk = request.cookies.first(b"milk", None)
+
+    # Send back
+    if milk is None:
+        return headers, u'.requestDidNotHaveCookies { }'
+    elif milk.value == b"1":
+        return headers, u'.requestHadCookies { }'
+
+    return headers, u'.requestDidNotHaveCookies { }'
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-parse-error-with-cors.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-parse-error-with-cors.sub.html
new file mode 100644
index 0000000..1774ef3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-parse-error-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>css-module-import-cross-domain-parse-error-WithCORS</title>
+    <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+    <h1>css-module-import-cross-domain-parse-error-WithCORS</h1>
+    <script type="module" crossorigin>
+        import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css?pipe=header(Access-Control-Allow-Origin,*)" assert { type: "css" };
+        // Push an event to the log indicating that the script was executed.
+        document._log.push(`imported CSS rules count: ${styleSheet.rules.length}`);
+    </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-with-cors.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-with-cors.sub.html
new file mode 100644
index 0000000..f02a51d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-with-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>css-module-import-cross-domain-WithCORS</title>
+    <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+    <h1>css-module-import-cross-domain-WithCORS</h1>
+    <script type="module" crossorigin>
+        import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css?pipe=header(Access-Control-Allow-Origin,*)" assert { type: "css" };
+        // Push an event to the log indicating that the script was executed.
+        document._log.push(`imported CSS: ${styleSheet.rules[0].cssText}`);
+    </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-without-cors.sub.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-without-cors.sub.html
new file mode 100644
index 0000000..6236f79
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/crossorigin-import-without-cors.sub.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>css-module-import-cross-domain-NoCORS</title>
+    <script src="../../module/crossorigin-common.js"></script>
+</head>
+<body>
+    <h1>css-module-import-cross-domain-NoCORS</h1>
+    <script type="module" onerror="document._log.push('error');">
+        import styleSheet from "http://{{domains[www2]}}:{{ports[http][0]}}/html/semantics/scripting-1/the-script-element/css-module/resources/basic.css" assert { type: "css" };
+        // Push an event to the log indicating that the script was executed.
+        document._log.push(`imported CSS: ${styleSheet.rules[0].cssText}`);
+    </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/css-module-at-import-iframe.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/css-module-at-import-iframe.html
index cce9e21..90f1223 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/css-module-at-import-iframe.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/css-module-at-import-iframe.html
@@ -15,4 +15,7 @@
     <div id="test">
         I am a test div.
     </div>
+    <div id="test2">
+        I am another test div.
+    </div>
 </body>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-matches.js b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-matches.js
new file mode 100644
index 0000000..95be445
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-matches.js
@@ -0,0 +1,2 @@
+import styleSheet from "./basic.css" assert { type: "css" };
+window.matchesLog.push(`integrity-matches,css:${styleSheet.cssRules[0].cssText}`);
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-mismatches.js b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-mismatches.js
new file mode 100644
index 0000000..af6fc24d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/integrity-mismatches.js
@@ -0,0 +1,2 @@
+import styleSheet from "./basic.css" assert { type: "css" };
+window.matchesLog.push(`integrity-mismatches,css:${styleSheet.cssRules[0].cssText}`);
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/load-error-events.py b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/load-error-events.py
new file mode 100644
index 0000000..b61b1ca
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/load-error-events.py
@@ -0,0 +1,14 @@
+import re
+
+def main(request, response):
+    headers = [(b"Content-Type", b"text/javascript")]
+    test = request.GET.first(b'test')
+    assert(re.match(b'^[a-zA-Z0-9_]+$', test))
+
+    status = 200
+    if test.find(b'_load') >= 0:
+      content = b'import "./basic.css" assert { type: "css"}; %s.executed = true;' % test
+    else:
+      content = b'import "./not_found.css" assert { type: "css"}; %s.test.step(function() { assert_unreached("404 script should not be executed"); });' % test
+
+    return status, headers, content
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/malformed-iframe.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/malformed-iframe.html
index f5c64f6..cd049cb 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/malformed-iframe.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/malformed-iframe.html
@@ -8,4 +8,7 @@
     <div id="test">
         I am a test div.
     </div>
+    <div id="test2">
+        I am another test div.
+    </div>
 </body>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/malformed.css b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/malformed.css
index fb20336..592e506 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/malformed.css
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/malformed.css
@@ -1,3 +1,7 @@
-#test {{
-    background-color:red;
-}
\ No newline at end of file
+#test } {
+    background-color: #FF0000;
+}
+
+#test2 {
+    background-color: #00FF00;
+}
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css
new file mode 100644
index 0000000..2bee3ff
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/parse-error.css
@@ -0,0 +1,2 @@
+div /* Opening bracket skipped intentionally. */ }
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py
new file mode 100644
index 0000000..c1eaed8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/referrer-checker.py
@@ -0,0 +1,7 @@
+def main(request, response):
+    referrer = request.headers.get(b"referer", b"")
+    response_headers = [(b"Content-Type", b"text/css"),
+                        (b"Access-Control-Allow-Origin", b"*")]
+    # Put the referrer in a CSS rule that can be read by the importer through CSSOM
+    return (200, response_headers,
+            b'.referrer { content: "' + referrer + b'" }')
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/utf-8.css b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/utf-8.css
new file mode 100644
index 0000000..0a8b4665
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/utf-8.css
@@ -0,0 +1,3 @@
+#test {
+    content: "śćążź";
+}
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/utf8.css b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/utf8.css
deleted file mode 100644
index 35d16cd..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/utf8.css
+++ /dev/null
@@ -1,3 +0,0 @@
-#test {
-    content: "…";
-}
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/windows-1250.css b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/windows-1250.css
new file mode 100644
index 0000000..a155dcb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/resources/windows-1250.css
@@ -0,0 +1,3 @@
+#test {
+    content: "œæ¹¿Ÿ";
+}
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/script-element-css-src.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/script-element-css-src.html
new file mode 100644
index 0000000..231d02db
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/script-element-css-src.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>&lt;script&gt; with CSS src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+  window.log = [];
+
+  const test_load = async_test(
+      "Test that <script> doesn't load when the src is CSS.");
+  window.addEventListener("load", test_load.step_func_done(ev => {
+    assert_array_equals(log, ["error"]);
+  }));
+</script>
+<script type="module" src="./resources/basic.css" onload="t.unreached_func('CSS src should fail to load')" onerror="log.push('error')"></script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/utf8.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/utf8.tentative.html
deleted file mode 100644
index 6adcd716..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-script-element/css-module/utf8.tentative.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS modules: UTF-8 decoding</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-function check(t, v) {
-  t.step(() => {
-    assert_equals(typeof v, "object");
-    assert_equals(v.rules[0].style.content, "\"…\"");
-    t.done();
-  });
-}
-const t1 = async_test("utf-8");
-const t2 = async_test("shift-jis");
-const t3 = async_test("windows-1252");
-const t4 = async_test("utf-7");
-</script>
-<script type="module" onerror="t1.step(() => assert_unreached(event))">
-import v from "../serve-with-content-type.py?fn=css-module/resources/utf8.css&ct=text/css%3Bcharset=utf-8" assert { type: "css" };
-check(t1, v);
-</script>
-<script type="module" onerror="t2.step(() => assert_unreached(event))">
-import v from "../serve-with-content-type.py?fn=css-module/resources/utf8.css&ct=text/css%3Bcharset=shift-jis" assert { type: "css" };
-check(t2, v);
-</script>
-<script type="module" onerror="t3.step(() => assert_unreached(event))">
-import v from "../serve-with-content-type.py?fn=css-module/resources/utf8.css&ct=text/css%3Bcharset=windows-1252" assert { type: "css" };
-check(t3, v);
-</script>
-<script type="module" onerror="t4.step(() => assert_unreached(event))">
-import v from "../serve-with-content-type.py?fn=css-module/resources/utf8.css&ct=text/css%3Bcharset=utf-7" assert { type: "css" };
-check(t4, v);
-</script>
diff --git a/third_party/blink/web_tests/http/tests/misc/app-history-promise-crash-expected.txt b/third_party/blink/web_tests/http/tests/misc/app-history-promise-crash-expected.txt
new file mode 100644
index 0000000..4c5caa9
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/misc/app-history-promise-crash-expected.txt
@@ -0,0 +1 @@
+PASS if no crash. 
diff --git a/third_party/blink/web_tests/http/tests/misc/app-history-promise-crash.html b/third_party/blink/web_tests/http/tests/misc/app-history-promise-crash.html
new file mode 100644
index 0000000..c3106ed
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/misc/app-history-promise-crash.html
@@ -0,0 +1,15 @@
+<body>
+PASS if no crash.
+<iframe id="i" src="../resources/dummy.html"></iframe>
+<script>
+// TODO: make this a testharness test and upstream this to WPT if
+// https://github.com/web-platform-tests/wpt/issues/7899 ever gets resolved
+if (window.testRunner)
+  testRunner.dumpAsText();
+
+window.onload = () => {
+  let promise = i.contentWindow.appHistory.navigate("?1");
+  gc();
+}
+</script>
+</body>
diff --git a/third_party/blink/web_tests/images/resources/avif/README.md b/third_party/blink/web_tests/images/resources/avif/README.md
index 78abe86..c49df584 100644
--- a/third_party/blink/web_tests/images/resources/avif/README.md
+++ b/third_party/blink/web_tests/images/resources/avif/README.md
@@ -84,13 +84,4 @@
 avifenc -r f -d  8 -y 420 -s 0 --irot 3 --imir 1 red.png red-full-range-angle-3-axis-1-420-8bpc.avif
 ```
 
-### blue-and-magenta-crop.avif
-This image uses a 'clap' (clean aperture) image property to crop the image to
-contain the blue rectangle only (with a magenta rectangle inside).
-
-### blue-and-magenta-crop-invalid.avif
-This image is the same as blue-and-magenta-crop.avif except that the fractions
-horizOff and vertOff have positive numerators and negative denominators (30/-1
-and 10/-1 instead of -30/1 and -10/1). Changed with a hex editor.
-
 ### TODO(crbug.com/960620): Figure out how the rest of files were generated.
diff --git a/third_party/blink/web_tests/images/resources/avif/blue-and-magenta-crop-invalid.avif b/third_party/blink/web_tests/images/resources/avif/blue-and-magenta-crop-invalid.avif
deleted file mode 100644
index e465182..0000000
--- a/third_party/blink/web_tests/images/resources/avif/blue-and-magenta-crop-invalid.avif
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/images/resources/avif/blue-and-magenta-crop.avif b/third_party/blink/web_tests/images/resources/avif/blue-and-magenta-crop.avif
deleted file mode 100644
index a2e290c..0000000
--- a/third_party/blink/web_tests/images/resources/avif/blue-and-magenta-crop.avif
+++ /dev/null
Binary files differ
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 7bec21e..70b495f 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -46432,6 +46432,7 @@
   <int value="-835331907" label="TabOutlinesInLowContrastThemes:disabled"/>
   <int value="-835242361" label="OmniboxAdaptiveSuggestionsCount:enabled"/>
   <int value="-834661509" label="ModalPermissionPrompts:disabled"/>
+  <int value="-832806243" label="QuickActionSearchWidgetAndroid:disabled"/>
   <int value="-832780530" label="SecurePaymentConfirmationDebug:enabled"/>
   <int value="-832561975" label="enable-picture-in-picture"/>
   <int value="-831066457" label="IncognitoBrandConsistencyForDesktop:disabled"/>
@@ -46684,6 +46685,7 @@
   <int value="-612633819" label="NotificationScrollBar:disabled"/>
   <int value="-612480090" label="FasterLocationReload:enabled"/>
   <int value="-610411643" label="enable-printer-app-search"/>
+  <int value="-609034895" label="QuickActionSearchWidgetAndroid:enabled"/>
   <int value="-608775184" label="PasswordsWeaknessCheck:enabled"/>
   <int value="-608065163" label="PermissionChipRequestTypeSensitive:disabled"/>
   <int value="-607925721" label="WebViewVulkan:disabled"/>
@@ -67111,9 +67113,8 @@
 </enum>
 
 <enum name="ReceiverAppTypeSet">
-  <int value="0" label="Other"/>
-  <int value="1" label="Web"/>
-  <int value="2" label="Android Tv and Web"/>
+  <int value="0" label="Web"/>
+  <int value="1" label="Android Tv and Web"/>
 </enum>
 
 <enum name="RecentTabsAction">
diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml
index 056dc0b7..dc6c472 100644
--- a/tools/metrics/histograms/histograms_xml/android/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml
@@ -3423,8 +3423,9 @@
 </histogram>
 
 <histogram name="Android.WebView.Visibility.Global" enum="WebViewVisibility"
-    expires_after="2021-07-01">
+    expires_after="2022-06-01">
   <owner>idries@google.com</owner>
+  <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
     Records the global visibility state of WebView in seconds, updated with
@@ -3438,8 +3439,9 @@
 </histogram>
 
 <histogram name="Android.WebView.Visibility.PerWebView"
-    enum="WebViewVisibility" expires_after="2021-07-01">
+    enum="WebViewVisibility" expires_after="2022-06-01">
   <owner>idries@google.com</owner>
+  <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
     Records per-WebView visibility duration in seconds, updated with every
@@ -3455,8 +3457,9 @@
 </histogram>
 
 <histogram name="Android.WebView.WebViewOpenWebVisible.Global"
-    enum="WebViewOpenWebVisibility" expires_after="2021-07-01">
+    enum="WebViewOpenWebVisibility" expires_after="2022-06-01">
   <owner>idries@google.com</owner>
+  <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
     Identical to Android.WebView.Visibility.Global except that the
@@ -3470,8 +3473,9 @@
 </histogram>
 
 <histogram name="Android.WebView.WebViewOpenWebVisible.PerWebView"
-    enum="WebViewOpenWebVisibility" expires_after="2021-07-01">
+    enum="WebViewOpenWebVisibility" expires_after="2022-06-01">
   <owner>idries@google.com</owner>
+  <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
     Identical to Android.WebView.Visibility.PerWebView except that the
@@ -3485,8 +3489,9 @@
 </histogram>
 
 <histogram name="Android.WebView.WebViewOpenWebVisible.ScreenPortion"
-    enum="WebViewOpenWebScreenPortion" expires_after="2021-07-01">
+    enum="WebViewOpenWebScreenPortion" expires_after="2022-06-01">
   <owner>idries@google.com</owner>
+  <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
     Records the number of seconds that WebView is displaying Open Web Content
diff --git a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
index 9b4c6b9..14dab6c7 100644
--- a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml
@@ -1091,7 +1091,7 @@
 
 <histogram
     name="Enterprise.MachineLevelUserCloudPolicyEnrollment.RequestFailureTime"
-    units="ms" expires_after="2021-08-09">
+    units="ms" expires_after="2022-06-01">
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
   <summary>
@@ -1102,7 +1102,7 @@
 
 <histogram
     name="Enterprise.MachineLevelUserCloudPolicyEnrollment.RequestSuccessTime"
-    units="ms" expires_after="2021-06-01">
+    units="ms" expires_after="2022-06-01">
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
   <summary>
@@ -1113,7 +1113,7 @@
 
 <histogram name="Enterprise.MachineLevelUserCloudPolicyEnrollment.Result"
     enum="MachineLevelUserCloudPolicyEnrollmentResult"
-    expires_after="2021-10-04">
+    expires_after="2022-06-01">
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
   <summary>The result of machine level user cloud policy enrollment.</summary>
@@ -1122,7 +1122,7 @@
 <histogram
     name="Enterprise.MachineLevelUserCloudPolicyEnrollment.StartupDialog"
     enum="MachineLevelUserCloudPolicyEnrollmentStartupDialog"
-    expires_after="2021-06-01">
+    expires_after="2022-06-01">
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
   <summary>
@@ -1133,7 +1133,7 @@
 
 <histogram
     name="Enterprise.MachineLevelUserCloudPolicyEnrollment.StartupDialogTime"
-    units="ms" expires_after="2021-06-01">
+    units="ms" expires_after="2022-06-01">
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
   <summary>
@@ -1144,7 +1144,7 @@
 
 <histogram
     name="Enterprise.MachineLevelUserCloudPolicyEnrollment.UnenrollSuccess"
-    enum="BooleanSuccess" expires_after="2021-10-31">
+    enum="BooleanSuccess" expires_after="2022-06-01">
   <owner>domfc@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/ios/histograms.xml b/tools/metrics/histograms/histograms_xml/ios/histograms.xml
index 3f2fabc..5016598 100644
--- a/tools/metrics/histograms/histograms_xml/ios/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/ios/histograms.xml
@@ -507,6 +507,7 @@
 <histogram name="IOS.IsDefaultBrowser" enum="Boolean" expires_after="never">
 <!-- expires-never: used internally for filtering -->
 
+  <owner>javierrobles@chromium.org</owner>
   <owner>thegreenfrog@chromium.org</owner>
   <owner>rohitrao@chromium.org</owner>
   <owner>chrome-metrics-team@google.com</owner>
@@ -516,7 +517,9 @@
     likely to change certain stability metrics. Thus, it will be good to filter
     those metrics by default browser status. This metrics records whether the
     user was deemed to have set Chrome as the device's default browser. This
-    metric will be logged once per metrics log upload.
+    metric will be logged once per metrics log upload. As long as link is opened
+    in Chrome in the last 21 days, the user will be considered a default user.
+    Before M93 instead of 21 days, 7 days was used.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/histograms_xml/media/histograms.xml b/tools/metrics/histograms/histograms_xml/media/histograms.xml
index 8ae628e..789bd3e 100644
--- a/tools/metrics/histograms/histograms_xml/media/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/media/histograms.xml
@@ -4991,7 +4991,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Cast.LaunchSessionRequest.SupportedAppTypes"
-    enum="ReceiverAppTypeSet" expires_after="2021-06-08">
+    enum="ReceiverAppTypeSet" expires_after="2022-06-08">
   <owner>muyaoxu@google.com</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml
index e3bb107..64b24aa 100644
--- a/tools/metrics/histograms/histograms_xml/others/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -15433,12 +15433,18 @@
 
 <histogram name="Sqlite.CloseFailure" enum="SqliteErrorCode"
     expires_after="M85">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>Error which prevented database close.</summary>
 </histogram>
 
 <histogram name="Sqlite.DeprecationVersionResult"
     enum="SqliteVersionDeprecation" expires_after="M77">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>
     Annotations for which bits of sql::MetaTable::CheckDeprecated() fire.
@@ -15447,11 +15453,17 @@
 
 <histogram name="Sqlite.Error" enum="SqliteErrorCode"
     expires_after="2020-02-16">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>SQLite extended error codes.</summary>
 </histogram>
 
 <histogram name="Sqlite.MemoryKB.OneDay" units="KB" expires_after="M81">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>
     SQLite memory footprint from sqlite3_memory_used() recorded 1 day after
@@ -15460,6 +15472,9 @@
 </histogram>
 
 <histogram name="Sqlite.MemoryKB.OneHour" units="KB" expires_after="M81">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>
     SQLite memory footprint from sqlite3_memory_used() recorded 1 hour after
@@ -15468,6 +15483,9 @@
 </histogram>
 
 <histogram name="Sqlite.MemoryKB.OneWeek" units="KB" expires_after="M81">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>
     SQLite memory footprint from sqlite3_memory_used() recorded 1 week after
@@ -15476,6 +15494,9 @@
 </histogram>
 
 <histogram name="Sqlite.MemoryKB.TenMinutes" units="KB" expires_after="M81">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>
     SQLite memory footprint from sqlite3_memory_used() recorded 10 minutes after
@@ -15484,6 +15505,9 @@
 </histogram>
 
 <histogram name="Sqlite.Migration.History" units="ms" expires_after="M85">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>
     Time used to migrate History database schema to a new version.
@@ -15491,6 +15515,9 @@
 </histogram>
 
 <histogram name="Sqlite.OpenFailure" enum="SqliteErrorCode" expires_after="M95">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>pwnall@chromium.org</owner>
   <owner>src/storage/OWNERS</owner>
   <summary>Error which prevented database open.</summary>
@@ -15498,24 +15525,36 @@
 
 <histogram name="Sqlite.OpenProbeFailure" enum="SqliteErrorCode"
     expires_after="M77">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>Error from first read of the database.</summary>
 </histogram>
 
 <histogram name="Sqlite.RazeDatabase" enum="SqliteErrorCode"
     expires_after="M77">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>Errors attempting to Raze() database.</summary>
 </histogram>
 
 <histogram name="Sqlite.RazeDatabase2" enum="SqliteErrorCode"
     expires_after="M77">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>Errors on second attempt to Raze() database.</summary>
 </histogram>
 
 <histogram name="Sqlite.RazeDatabaseTruncate" enum="SqliteErrorCode"
     expires_after="M85">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>Errors truncating database for Raze().</summary>
 </histogram>
@@ -15530,6 +15569,9 @@
 
 <histogram name="Sqlite.RecoveryEvents" enum="SqliteRecoveryEventEnum"
     expires_after="M81">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>
     Records specific failure and success cases in sql::Recovery implementation,
@@ -15541,6 +15583,9 @@
 
 <histogram name="Sqlite.RecoveryHandle" enum="SqliteErrorCode"
     expires_after="M85">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>Error from sqlite3_backup_init() in sql::Recovery.</summary>
 </histogram>
@@ -15552,6 +15597,9 @@
 </histogram>
 
 <histogram name="Sqlite.Stats2" enum="SqliteStats2Enum" expires_after="M81">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>pwnall@chromium.org</owner>
   <summary>
     SQLite failures encountered by //sql code. Intended to be viewed using
@@ -15562,6 +15610,9 @@
 </histogram>
 
 <histogram name="Sqlite.Version" units="units" expires_after="M81">
+  <obsolete>
+    Removed in M92
+  </obsolete>
   <owner>costan@google.com</owner>
   <summary>Version of pre-existing database at startup.</summary>
 </histogram>
diff --git a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
index 479ff77b..35ee64d4 100644
--- a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml
@@ -1958,7 +1958,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.WebView.AppOptIn" enum="SafeBrowsingAppOptIn"
-    expires_after="2021-07-07">
+    expires_after="2022-06-01">
   <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/sync/histograms.xml b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
index 80431f446..3b5f2b8 100644
--- a/tools/metrics/histograms/histograms_xml/sync/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
@@ -105,6 +105,19 @@
   </summary>
 </histogram>
 
+<histogram name="Sync.BookmarkModelMerger.UnsyncedEntitiesUponCompletion"
+    units="bookmarks" expires_after="2021-10-25">
+  <owner>rushans@google.com</owner>
+  <owner>mastiz@chromium.org</owner>
+  <component>Services&gt;Sync</component>
+  <summary>
+    Records the number of unsynced entities (bookmarks or folders) as a result
+    of the initial merge for bookmarks. This includes local creations (i.e. did
+    not match any entity in the server) as well as local modifications (e.g.
+    pending reupload). Recorded upon completion of the initial merge procedure.
+  </summary>
+</histogram>
+
 <histogram name="Sync.BookmarkModelMerger.ValidInputUpdates" units="bookmarks"
     expires_after="2021-10-25">
   <owner>rushans@google.com</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 175e1c0..57d5f22b 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -9,8 +9,8 @@
             "remote_path": "perfetto_binaries/trace_processor_shell/mac/bae8193de6c017394901163b7817157342914679/trace_processor_shell"
         },
         "linux": {
-            "hash": "e5faa69a486f60fe15e12f1a73fca358580b4dd5",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/71719e601946d80f52445f4ca232f3b1b4d652f3/trace_processor_shell"
+            "hash": "d8409cee39bfb2ba7210faad852f07ad4485f92a",
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/f1f79d741319ec182b72bd473078c3ba5e8bf777/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/typescript/PRESUBMIT.py b/tools/typescript/PRESUBMIT.py
index 8dc19eb..9a080c35 100644
--- a/tools/typescript/PRESUBMIT.py
+++ b/tools/typescript/PRESUBMIT.py
@@ -7,6 +7,8 @@
 for more details about the presubmit API built into depot_tools.
 """
 
+USE_PYTHON3 = True
+
 
 def RunTypescriptTests(input_api, output_api):
   presubmit_path = input_api.PresubmitLocalPath()
diff --git a/ui/views/PRESUBMIT.py b/ui/views/PRESUBMIT.py
index 7273cb19..4b967b3 100644
--- a/ui/views/PRESUBMIT.py
+++ b/ui/views/PRESUBMIT.py
@@ -8,6 +8,8 @@
 for more details about the presubmit API built into depot_tools.
 """
 
+USE_PYTHON3 = True
+
 INCLUDE_CPP_FILES_ONLY = (
   r'.*\.(cc|h)$',
 )
diff --git a/weblayer/browser/persistence/browser_persister.cc b/weblayer/browser/persistence/browser_persister.cc
index 762cc4b..e9baff5 100644
--- a/weblayer/browser/persistence/browser_persister.cc
+++ b/weblayer/browser/persistence/browser_persister.cc
@@ -111,7 +111,7 @@
 
 void BrowserPersister::OnTabAdded(Tab* tab) {
   auto* tab_impl = static_cast<TabImpl*>(tab);
-  data_observer_.Add(tab_impl);
+  data_observations_.AddObservation(tab_impl);
   content::WebContents* web_contents = tab_impl->web_contents();
   auto* tab_helper = sessions::SessionTabHelper::FromWebContents(web_contents);
   DCHECK(tab_helper);
@@ -137,7 +137,7 @@
 
 void BrowserPersister::OnTabRemoved(Tab* tab, bool active_tab_changed) {
   auto* tab_impl = static_cast<TabImpl*>(tab);
-  data_observer_.Remove(tab_impl);
+  data_observations_.RemoveObservation(tab_impl);
   // Allow the associated sessionStorage to get deleted; it won't be needed
   // in the session restore.
   content::WebContents* web_contents = tab_impl->web_contents();
diff --git a/weblayer/browser/persistence/browser_persister.h b/weblayer/browser/persistence/browser_persister.h
index 46066ccb..8a67919e 100644
--- a/weblayer/browser/persistence/browser_persister.h
+++ b/weblayer/browser/persistence/browser_persister.h
@@ -15,7 +15,7 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/scoped_observer.h"
+#include "base/scoped_multi_source_observation.h"
 #include "components/sessions/content/session_tab_helper_delegate.h"
 #include "components/sessions/core/command_storage_manager_delegate.h"
 #include "components/sessions/core/session_service_commands.h"
@@ -137,11 +137,11 @@
 
   std::vector<uint8_t> crypto_key_;
 
-  ScopedObserver<TabImpl,
-                 TabImpl::DataObserver,
-                 &TabImpl::AddDataObserver,
-                 &TabImpl::RemoveDataObserver>
-      data_observer_{this};
+  base::ScopedMultiSourceObservation<TabImpl,
+                                     TabImpl::DataObserver,
+                                     &TabImpl::AddDataObserver,
+                                     &TabImpl::RemoveDataObserver>
+      data_observations_{this};
 
   // True while asynchronously reading the state to restore.
   bool is_restore_in_progress_ = true;
diff --git a/weblayer/browser/ssl_browsertest.cc b/weblayer/browser/ssl_browsertest.cc
index 798ac8b3e..f1e0476a 100644
--- a/weblayer/browser/ssl_browsertest.cc
+++ b/weblayer/browser/ssl_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include "base/files/file_path.h"
 #include "base/macros.h"
-#include "base/scoped_observer.h"
+#include "base/scoped_observation.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "components/network_time/network_time_tracker.h"
@@ -38,7 +38,7 @@
 class NewTabWaiter : public BrowserObserver {
  public:
   NewTabWaiter(Browser* browser, const GURL& url) : url_(url) {
-    observer_.Add(browser);
+    observation_.Observe(browser);
   }
 
   void OnTabAdded(Tab* tab) override {
@@ -57,7 +57,7 @@
   GURL url_;
   std::unique_ptr<TestNavigationObserver> navigation_observer_;
   base::RunLoop run_loop_;
-  ScopedObserver<Browser, BrowserObserver> observer_{this};
+  base::ScopedObservation<Browser, BrowserObserver> observation_{this};
 };
 #endif
 
diff --git a/weblayer/public/java/PRESUBMIT.py b/weblayer/public/java/PRESUBMIT.py
index 1507cc8d..c114db1 100644
--- a/weblayer/public/java/PRESUBMIT.py
+++ b/weblayer/public/java/PRESUBMIT.py
@@ -12,6 +12,8 @@
 import sys
 import tempfile
 
+USE_PYTHON3 = True
+
 _WEBLAYER_PUBLIC_MANIFEST_PATH=os.path.join("weblayer", "public", "java",
                                             "AndroidManifest.xml")