diff --git a/DEPS b/DEPS
index c1a1885..4b70df3 100644
--- a/DEPS
+++ b/DEPS
@@ -126,11 +126,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': '6152470dc69ee96172e5f4c3270f98e47ff9693d',
+  'skia_revision': '126ac6365c3c4342a009cc27c44a00d2b95f2cab',
   # 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': 'd34a141dae9be2c1f66509c7c449992ea34d058a',
+  'v8_revision': 'e9d7dbcd257d066b85a13a8b83bfffb765b81bb5',
   # 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.
@@ -189,7 +189,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': '8ba5518f87cc9179d81af3df7eaad5fb15a34acf',
+  'catapult_revision': 'b3d62293b2f882ca7a8b5654bcc43eaf1153ce41',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -253,7 +253,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'b2207737abd32e20e39a1ac00987179626f050c7',
+  'dawn_revision': '6fe9b9821a1a46d3150af99eb64e8b50d89a7d27',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -732,7 +732,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '499f9dd2f00ec1c72fd7f2322d756db28e17eb9d',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'aea01e37674869d75cf26c8a826195b4dd6a890b',
       'condition': 'checkout_linux',
   },
 
@@ -1092,7 +1092,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '3271875cb274dbfb0ada8d2cec976bf4e1e7d0ca',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '14aebc30d20c645ee57c025b5f45e3ba23678a88',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1255,7 +1255,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a0f51b2e123f39c9ff12e621b0b47dd28dd64424',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'b1ea48c2e8682e9c2f67ff3cfa4e9dbaebbb8cc7',
+    Var('webrtc_git') + '/src.git' + '@' + 'd00045ef0e68ecb102caa35866b38593fff28001',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1296,7 +1296,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@116ba2e6c585afa1507e806e162cae6c098bf9ef',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b4dab2cd03397ca5ad18fbf9c2f612ab8ffffd5f',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/browser/aw_download_manager_delegate.cc b/android_webview/browser/aw_download_manager_delegate.cc
index 75e1fa3..a9617c09 100644
--- a/android_webview/browser/aw_download_manager_delegate.cc
+++ b/android_webview/browser/aw_download_manager_delegate.cc
@@ -8,8 +8,31 @@
 #include "components/download/public/common/download_danger_type.h"
 #include "components/download/public/common/download_item.h"
 
+#include "android_webview/browser/aw_contents_client_bridge.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+
 namespace android_webview {
 
+namespace {
+
+void DownloadStartingOnUIThread(content::WebContents* web_contents,
+                                const GURL& url,
+                                const std::string& user_agent,
+                                const std::string& content_disposition,
+                                const std::string& mime_type,
+                                int64_t content_length) {
+  AwContentsClientBridge* client =
+      AwContentsClientBridge::FromWebContents(web_contents);
+  if (!client)
+    return;
+  client->NewDownload(url, user_agent, content_disposition, mime_type,
+                      content_length);
+}
+
+}  // namespace
+
 AwDownloadManagerDelegate::~AwDownloadManagerDelegate() {}
 
 bool AwDownloadManagerDelegate::DetermineDownloadTarget(
@@ -39,6 +62,21 @@
   return true;
 }
 
+bool AwDownloadManagerDelegate::InterceptDownloadIfApplicable(
+    const GURL& url,
+    const std::string& user_agent,
+    const std::string& content_disposition,
+    const std::string& mime_type,
+    const std::string& request_origin,
+    int64_t content_length,
+    content::WebContents* web_contents) {
+  base::PostTaskWithTraits(
+      FROM_HERE, {content::BrowserThread::UI},
+      base::BindOnce(&DownloadStartingOnUIThread, web_contents, url, user_agent,
+                     content_disposition, mime_type, content_length));
+  return true;
+}
+
 void AwDownloadManagerDelegate::GetNextId(
     const content::DownloadIdCallback& callback) {
   static uint32_t next_id = download::DownloadItem::kInvalidId + 1;
diff --git a/android_webview/browser/aw_download_manager_delegate.h b/android_webview/browser/aw_download_manager_delegate.h
index 39592bd..d62cfc7 100644
--- a/android_webview/browser/aw_download_manager_delegate.h
+++ b/android_webview/browser/aw_download_manager_delegate.h
@@ -5,6 +5,8 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_AW_DOWNLOAD_MANAGER_DELEGATE_H_
 #define ANDROID_WEBVIEW_BROWSER_AW_DOWNLOAD_MANAGER_DELEGATE_H_
 
+#include <string>
+
 #include "base/supports_user_data.h"
 #include "content/public/browser/download_manager_delegate.h"
 
@@ -26,6 +28,14 @@
   bool ShouldOpenDownload(
       download::DownloadItem* item,
       const content::DownloadOpenDelayedCallback& callback) override;
+  bool InterceptDownloadIfApplicable(
+      const GURL& url,
+      const std::string& user_agent,
+      const std::string& content_disposition,
+      const std::string& mime_type,
+      const std::string& request_origin,
+      int64_t content_length,
+      content::WebContents* web_contents) override;
   void GetNextId(const content::DownloadIdCallback& callback) override;
 };
 
diff --git a/base/mac/foundation_util.h b/base/mac/foundation_util.h
index fededa1..9dd50e04 100644
--- a/base/mac/foundation_util.h
+++ b/base/mac/foundation_util.h
@@ -158,25 +158,6 @@
 BASE_EXPORT void NSObjectRetain(void* obj);
 BASE_EXPORT void NSObjectRelease(void* obj);
 
-// CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation
-// object (one derived from CFTypeRef) to the Foundation memory management
-// system.  In a traditional managed-memory environment, cf_object is
-// autoreleased and returned as an NSObject.  In a garbage-collected
-// environment, cf_object is marked as eligible for garbage collection.
-//
-// This function should only be used to convert a concrete CFTypeRef type to
-// its equivalent "toll-free bridged" NSObject subclass, for example,
-// converting a CFStringRef to NSString.
-//
-// By calling this function, callers relinquish any ownership claim to
-// cf_object.  In a managed-memory environment, the object's ownership will be
-// managed by the innermost NSAutoreleasePool, so after this function returns,
-// callers should not assume that cf_object is valid any longer than the
-// returned NSObject.
-//
-// Returns an id, typed here for C++'s sake as a void*.
-BASE_EXPORT void* CFTypeRefToNSObjectAutorelease(CFTypeRef cf_object);
-
 // Returns the base bundle ID, which can be set by SetBaseBundleID but
 // defaults to a reasonable string. This never returns NULL. BaseBundleID
 // returns a pointer to static storage that must not be freed.
diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
index a63b7431..26a4041 100644
--- a/base/mac/foundation_util.mm
+++ b/base/mac/foundation_util.mm
@@ -232,17 +232,6 @@
   [nsobj release];
 }
 
-void* CFTypeRefToNSObjectAutorelease(CFTypeRef cf_object) {
-  // When GC is on, NSMakeCollectable marks cf_object for GC and autorelease
-  // is a no-op.
-  //
-  // In the traditional GC-less environment, NSMakeCollectable is a no-op,
-  // and cf_object is autoreleased, balancing out the caller's ownership claim.
-  //
-  // NSMakeCollectable returns nil when used on a NULL object.
-  return [NSMakeCollectable(cf_object) autorelease];
-}
-
 static const char* base_bundle_id;
 
 const char* BaseBundleID() {
diff --git a/base/strings/string_util.h b/base/strings/string_util.h
index 00a0cff..002e513d 100644
--- a/base/strings/string_util.h
+++ b/base/strings/string_util.h
@@ -370,7 +370,7 @@
 // library versions will change based on locale).
 template <typename Char>
 inline bool IsAsciiWhitespace(Char c) {
-  return c == ' ' || c == '\r' || c == '\n' || c == '\t';
+  return c == ' ' || c == '\r' || c == '\n' || c == '\t' || c == '\f';
 }
 template <typename Char>
 inline bool IsAsciiAlpha(Char c) {
diff --git a/base/strings/sys_string_conversions_mac.mm b/base/strings/sys_string_conversions_mac.mm
index 637d941..4d84d966 100644
--- a/base/strings/sys_string_conversions_mac.mm
+++ b/base/strings/sys_string_conversions_mac.mm
@@ -153,13 +153,11 @@
 }
 
 NSString* SysUTF8ToNSString(const std::string& utf8) {
-  return (NSString*)base::mac::CFTypeRefToNSObjectAutorelease(
-      SysUTF8ToCFStringRef(utf8));
+  return [mac::CFToNSCast(SysUTF8ToCFStringRef(utf8)) autorelease];
 }
 
 NSString* SysUTF16ToNSString(const string16& utf16) {
-  return (NSString*)base::mac::CFTypeRefToNSObjectAutorelease(
-      SysUTF16ToCFStringRef(utf16));
+  return [mac::CFToNSCast(SysUTF16ToCFStringRef(utf16)) autorelease];
 }
 
 std::string SysCFStringRefToUTF8(CFStringRef ref) {
diff --git a/base/task/task_scheduler/scheduler_worker_pool_impl.cc b/base/task/task_scheduler/scheduler_worker_pool_impl.cc
index a90a1131..232e37f5 100644
--- a/base/task/task_scheduler/scheduler_worker_pool_impl.cc
+++ b/base/task/task_scheduler/scheduler_worker_pool_impl.cc
@@ -97,7 +97,7 @@
 // to satisfy locking requirements of worker actions.
 class SchedulerWorkerPoolImpl::SchedulerWorkerActionExecutor {
  public:
-  SchedulerWorkerActionExecutor(TrackedRef<SchedulerWorkerPoolImpl> outer)
+  SchedulerWorkerActionExecutor(SchedulerWorkerPoolImpl* outer)
       : outer_(outer) {}
 
   ~SchedulerWorkerActionExecutor() {
@@ -157,7 +157,7 @@
     DISALLOW_COPY_AND_ASSIGN(WorkerContainer);
   };
 
-  const TrackedRef<SchedulerWorkerPoolImpl> outer_;
+  SchedulerWorkerPoolImpl* const outer_;
 
   WorkerContainer workers_to_wake_up_;
   WorkerContainer workers_to_start_;
@@ -364,7 +364,7 @@
     SchedulerWorkerObserver* scheduler_worker_observer,
     WorkerEnvironment worker_environment,
     Optional<TimeDelta> may_block_threshold) {
-  SchedulerWorkerActionExecutor executor(tracked_ref_factory_.GetTrackedRef());
+  SchedulerWorkerActionExecutor executor(this);
 
   AutoSchedulerLock auto_lock(lock_);
 
@@ -421,7 +421,7 @@
 void SchedulerWorkerPoolImpl::PushSequenceAndWakeUpWorkers(
     SequenceAndTransaction sequence_and_transaction) {
   bool must_schedule_adjust_max_tasks;
-  SchedulerWorkerActionExecutor executor(tracked_ref_factory_.GetTrackedRef());
+  SchedulerWorkerActionExecutor executor(this);
   {
     AutoSchedulerLock auto_lock(lock_);
     priority_queue_.Push(std::move(sequence_and_transaction.sequence),
@@ -620,7 +620,7 @@
   DCHECK(!worker_only().is_running_task);
   DCHECK(!read_worker().is_running_best_effort_task);
 
-  SchedulerWorkerActionExecutor executor(outer_);
+  SchedulerWorkerActionExecutor executor(outer_.get());
   AutoSchedulerLock auto_lock(outer_->lock_);
 
   DCHECK(ContainsWorker(outer_->workers_, worker));
@@ -944,7 +944,7 @@
   DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
   DCHECK(worker_only().is_running_task);
 
-  SchedulerWorkerActionExecutor executor(outer_);
+  SchedulerWorkerActionExecutor executor(outer_.get());
   AutoSchedulerLock auto_lock(outer_->lock_);
 
   DCHECK(!incremented_max_tasks_since_blocked_);
@@ -1113,7 +1113,7 @@
   DCHECK(
       after_start().service_thread_task_runner->RunsTasksInCurrentSequence());
 
-  SchedulerWorkerActionExecutor executor(tracked_ref_factory_.GetTrackedRef());
+  SchedulerWorkerActionExecutor executor(this);
   AutoSchedulerLock auto_lock(lock_);
 
   // Increment max tasks for each worker that has been within a MAY_BLOCK
diff --git a/base/task/task_scheduler/tracked_ref.h b/base/task/task_scheduler/tracked_ref.h
index 2949220..d4bc15a 100644
--- a/base/task/task_scheduler/tracked_ref.h
+++ b/base/task/task_scheduler/tracked_ref.h
@@ -107,6 +107,11 @@
     return ptr_ == compared_ptr;
   }
 
+  // Returns the raw pointer stored in this TrackedRef. This is occasionally
+  // useful for operations in scope but, as with other smart pointers, it
+  // shouldn't be used beyond the scope of this TrackedRef.
+  T* get() const { return ptr_; }
+
  private:
   friend class TrackedRefFactory<T>;
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 7f9d51d..0b18059 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1555,16 +1555,9 @@
       "__STDC_FORMAT_MACROS",
     ]
 
-    if (!is_debug && !using_sanitizer &&
-        (!is_linux || !is_clang || is_official_build) &&
-        current_cpu != "s390x" && current_cpu != "s390" &&
-        current_cpu != "ppc64" && current_cpu != "ppc64" &&
+    if (!is_debug && !using_sanitizer && current_cpu != "s390x" &&
+        current_cpu != "s390" && current_cpu != "ppc64" &&
         current_cpu != "mips" && current_cpu != "mips64") {
-      # _FORTIFY_SOURCE isn't really supported by Clang now, see
-      # http://llvm.org/bugs/show_bug.cgi?id=16821.
-      # It seems to work fine with Ubuntu 12 headers though, so use it in
-      # official builds.
-      #
       # Non-chromium code is not guaranteed to compile cleanly with
       # _FORTIFY_SOURCE. Also, fortified build may fail when optimizations are
       # disabled, so only do that for Release build.
diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc
index 644de377..ecd3fb7 100644
--- a/cc/animation/animation.cc
+++ b/cc/animation/animation.cc
@@ -269,7 +269,7 @@
   animation_host_->AddToTicking(this);
 }
 
-void Animation::KeyframeModelRemovedFromTicking() {
+void Animation::RemoveFromTicking() {
   DCHECK_GE(ticking_keyframe_effects_count, 0);
   if (!ticking_keyframe_effects_count)
     return;
diff --git a/cc/animation/animation.h b/cc/animation/animation.h
index fe0a875..a4033d4 100644
--- a/cc/animation/animation.h
+++ b/cc/animation/animation.h
@@ -100,7 +100,7 @@
   virtual void Tick(base::TimeTicks monotonic_time);
 
   void AddToTicking();
-  void KeyframeModelRemovedFromTicking();
+  void RemoveFromTicking();
 
   // AnimationDelegate routing.
   void NotifyKeyframeModelStarted(const AnimationEvent& event);
diff --git a/cc/animation/keyframe_effect.cc b/cc/animation/keyframe_effect.cc
index 15ef5fe..fa8ee8e 100644
--- a/cc/animation/keyframe_effect.cc
+++ b/cc/animation/keyframe_effect.cc
@@ -174,7 +174,7 @@
   // Resetting last_tick_time_ here ensures that calling ::UpdateState
   // before ::Animate doesn't start a keyframe model.
   last_tick_time_ = base::TimeTicks();
-  animation_->KeyframeModelRemovedFromTicking();
+  animation_->RemoveFromTicking();
 }
 
 void KeyframeEffect::UpdateState(bool start_ready_keyframe_models,
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 447726f..c22f2c53 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -555,6 +555,14 @@
   return std::make_unique<ScopedDeferMainFrameUpdate>(this);
 }
 
+void LayerTreeHost::StartDeferringCommits() {
+  proxy_->SetDeferCommits(true);
+}
+
+void LayerTreeHost::StopDeferringCommits() {
+  proxy_->SetDeferCommits(false);
+}
+
 DISABLE_CFI_PERF
 void LayerTreeHost::SetNeedsAnimate() {
   proxy_->SetNeedsAnimate();
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 2dfc651f..5634ca05 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -236,6 +236,11 @@
   // StopDeferringCommits is called.
   std::unique_ptr<ScopedDeferMainFrameUpdate> DeferMainFrameUpdate();
 
+  // Prevents the proxy from committing the layer tree to the compositor,
+  // while still allowing main frame lifecycle updates.
+  void StartDeferringCommits();
+  void StopDeferringCommits();
+
   // Returns whether there are any outstanding ScopedDeferMainFrameUpdate,
   // though commits may be deferred also when the local_surface_id_from_parent()
   // is not valid.
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java
index 33377ac..a287d1e 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java
@@ -67,9 +67,8 @@
         // See https://crbug.com/901414.
         if (mNativeFeedLoggingBridge == 0) return;
 
-        // TODO(https://crbug.com/924739): Emit wasCommitted as well.
-        nativeOnContentDismissed(
-                mNativeFeedLoggingBridge, data.getPositionInStream(), data.getRepresentationUri());
+        nativeOnContentDismissed(mNativeFeedLoggingBridge, data.getPositionInStream(),
+                data.getRepresentationUri(), wasCommitted);
     }
 
     @Override
@@ -135,7 +134,8 @@
         // See https://crbug.com/901414.
         if (mNativeFeedLoggingBridge == 0) return;
 
-        // TODO(https://crbug.com/924739): Implementation.
+        nativeOnNotInterestedInSource(
+                mNativeFeedLoggingBridge, data.getPositionInStream(), wasCommitted);
     }
 
     @Override
@@ -144,7 +144,8 @@
         // See https://crbug.com/901414.
         if (mNativeFeedLoggingBridge == 0) return;
 
-        // TODO(https://crbug.com/924739): Implementation.
+        nativeOnNotInterestedInTopic(
+                mNativeFeedLoggingBridge, data.getPositionInStream(), wasCommitted);
     }
 
     @Override
@@ -185,7 +186,11 @@
 
     @Override
     public void onPietFrameRenderingEvent(List<Integer> pietErrorCodes) {
-        // TODO(https://crbug.com/924739): Implementation.
+        int[] pietErrorCodesArray = new int[pietErrorCodes.size()];
+        for (int i = 0; i < pietErrorCodes.size(); ++i) {
+            pietErrorCodesArray[i] = pietErrorCodes.get(i);
+        }
+        nativeOnPietFrameRenderingEvent(mNativeFeedLoggingBridge, pietErrorCodesArray);
     }
 
     @Override
@@ -290,7 +295,7 @@
     private native void nativeOnContentViewed(long nativeFeedLoggingBridge, int position,
             long publishedTimeMs, long timeContentBecameAvailableMs, float score);
     private native void nativeOnContentDismissed(
-            long nativeFeedLoggingBridge, int position, String uri);
+            long nativeFeedLoggingBridge, int position, String uri, boolean wasCommitted);
     private native void nativeOnContentSwiped(long nativeFeedLoggingBridge);
     private native void nativeOnClientAction(long nativeFeedLoggingBridge,
             int windowOpenDisposition, int position, long publishedTimeMs, float score);
@@ -298,11 +303,17 @@
             long nativeFeedLoggingBridge, int position, long publishedTimeMs, float score);
     private native void nativeOnMoreButtonViewed(long nativeFeedLoggingBridge, int position);
     private native void nativeOnMoreButtonClicked(long nativeFeedLoggingBridge, int position);
+    private native void nativeOnNotInterestedInSource(
+            long nativeFeedLoggingBridge, int position, boolean wasCommitted);
+    private native void nativeOnNotInterestedInTopic(
+            long nativeFeedLoggingBridge, int position, boolean wasCommitted);
     private native void nativeOnOpenedWithContent(
             long nativeFeedLoggingBridge, int timeToPopulateMs, int contentCount);
     private native void nativeOnOpenedWithNoImmediateContent(long nativeFeedLoggingBridge);
     private native void nativeOnOpenedWithNoContent(long nativeFeedLoggingBridge);
     private native void nativeOnSpinnerShown(long nativeFeedLoggingBridge, long spinnerShownTimeMs);
+    private native void nativeOnPietFrameRenderingEvent(
+            long nativeFeedLoggingBridge, int[] pietErrorCodes);
     private native void nativeOnContentTargetVisited(
             long nativeFeedLoggingBridge, long visitTimeMs, boolean isOffline, boolean returnToNtp);
     private native void nativeReportScrolledAfterOpen(long nativeFeedLoggingBridge);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitions.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitions.java
index bcce8cef..70e5df9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitions.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelDefinitions.java
@@ -185,6 +185,13 @@
     }
 
     /**
+     * @return A set of all known channel group ids that can be used for {@link #getChannelGroup}.
+     */
+    static Set<String> getAllChannelGroupIds() {
+        return PredefinedChannelGroups.MAP.keySet();
+    }
+
+    /**
      * @return A set of all known channel ids that can be used for {@link #getChannelFromId}.
      */
     static Set<String> getAllChannelIds() {
@@ -200,6 +207,17 @@
     }
 
     /**
+     * @return A set of channel group ids of channel groups that should be initialized on startup.
+     */
+    static Set<String> getStartupChannelGroupIds() {
+        Set<String> groupIds = new HashSet<>();
+        for (String id : getStartupChannelIds()) {
+            groupIds.add(getChannelFromId(id).mGroupId);
+        }
+        return groupIds;
+    }
+
+    /**
      * @return An array of old ChannelIds that may have been returned by
      * {@link #getStartupChannelIds} in the past, but are no longer in use.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializer.java
index bc4105a..38fc8d6a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializer.java
@@ -17,8 +17,10 @@
 import org.chromium.chrome.browser.webapps.WebApkServiceClient;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Initializes our notification channels.
@@ -39,7 +41,9 @@
      * channel settings from first launch onwards.
      */
     void initializeStartupChannels() {
-        ensureInitialized(ChannelDefinitions.getStartupChannelIds());
+        Set<String> groupIds = ChannelDefinitions.getStartupChannelGroupIds();
+        Set<String> channelIds = ChannelDefinitions.getStartupChannelIds();
+        ensureInitialized(groupIds, channelIds);
     }
 
     /**
@@ -49,13 +53,18 @@
      */
     void updateLocale(Resources resources) {
         mResources = resources;
-        HashSet<String> channelIds = new HashSet<>();
+        Set<String> groupIds = new HashSet<>();
+        Set<String> channelIds = new HashSet<>();
+        for (NotificationChannelGroup group : mNotificationManager.getNotificationChannelGroups()) {
+            groupIds.add(group.getId());
+        }
         for (NotificationChannel channel : mNotificationManager.getNotificationChannels()) {
             channelIds.add(channel.getId());
         }
         // only re-initialize known channel ids, as we only want to update known & existing channels
+        groupIds.retainAll(ChannelDefinitions.getAllChannelGroupIds());
         channelIds.retainAll(ChannelDefinitions.getAllChannelIds());
-        ensureInitialized(channelIds);
+        ensureInitialized(groupIds, channelIds);
     }
 
     /**
@@ -88,10 +97,11 @@
      *
      * Calling this is a (potentially lengthy) no-op if the channels have already been created.
      *
+     * @param groupIds The IDs of the channel groups to be initialized.
      * @param channelIds The IDs of the channel to be initialized.
      */
-    public void ensureInitialized(Collection<String> channelIds) {
-        ensureInitializedWithEnabledState(channelIds, true);
+    public void ensureInitialized(Collection<String> groupIds, Collection<String> channelIds) {
+        ensureInitializedWithEnabledState(groupIds, channelIds, true);
     }
 
     /**
@@ -120,13 +130,25 @@
     }
 
     private void ensureInitializedWithEnabledState(String channelId, boolean enabled) {
-        ensureInitializedWithEnabledState(CollectionUtil.newArrayList(channelId), enabled);
+        Collection<String> groupIds = Collections.emptyList();
+        Collection<String> channelIds = CollectionUtil.newArrayList(channelId);
+        ensureInitializedWithEnabledState(groupIds, channelIds, enabled);
     }
 
-    private void ensureInitializedWithEnabledState(Collection<String> channelIds, boolean enabled) {
+    private void ensureInitializedWithEnabledState(
+            Collection<String> groupIds, Collection<String> channelIds, boolean enabled) {
         HashMap<String, NotificationChannelGroup> channelGroups = new HashMap<>();
         HashMap<String, NotificationChannel> channels = new HashMap<>();
 
+        for (String groupId : groupIds) {
+            ChannelDefinitions.PredefinedChannelGroup predefinedChannelGroup =
+                    ChannelDefinitions.getChannelGroup(groupId);
+            if (predefinedChannelGroup == null) continue;
+            NotificationChannelGroup channelGroup =
+                    predefinedChannelGroup.toNotificationChannelGroup(mResources);
+            channelGroups.put(channelGroup.getId(), channelGroup);
+        }
+
         for (String channelId : channelIds) {
             ChannelDefinitions.PredefinedChannel predefinedChannel =
                     getPredefinedChannel(channelId);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
index 4dffd03..469a1b0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/channels/ChannelsInitializerTest.java
@@ -37,6 +37,7 @@
 import org.chromium.content_public.browser.test.NativeLibraryTestRule;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 
@@ -318,8 +319,11 @@
     @TargetApi(Build.VERSION_CODES.O)
     @Feature({"Browser", "Notifications"})
     public void testEnsureInitialized_multipleIds() throws Exception {
-        mChannelsInitializer.ensureInitialized(CollectionUtil.newHashSet(
-                ChannelDefinitions.ChannelId.SITES, ChannelDefinitions.ChannelId.BROWSER));
+        Collection<String> groupIds = CollectionUtil.newHashSet(
+                ChannelDefinitions.ChannelGroupId.SITES, ChannelDefinitions.ChannelGroupId.GENERAL);
+        Collection<String> channelIds = CollectionUtil.newHashSet(
+                ChannelDefinitions.ChannelId.MEDIA, ChannelDefinitions.ChannelId.BROWSER);
+        mChannelsInitializer.ensureInitialized(groupIds, channelIds);
         assertThat(getChannelsIgnoringDefault(), hasSize(2));
     }
 
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 8dd94b9f..ad01b86 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4201,6 +4201,11 @@
      flag_descriptions::kEnableImplicitRootScrollerDescription, kOsAll,
      FEATURE_VALUE_TYPE(blink::features::kImplicitRootScroller)},
 
+    {"enable-text-fragment-anchor",
+     flag_descriptions::kEnableTextFragmentAnchorName,
+     flag_descriptions::kEnableTextFragmentAnchorDescription, kOsAll,
+     FEATURE_VALUE_TYPE(blink::features::kTextFragmentAnchor)},
+
 #if defined(OS_CHROMEOS)
     {"enable-assistant-stereo-input",
      flag_descriptions::kEnableGoogleAssistantStereoInputName,
diff --git a/chrome/browser/android/feed/feed_logging_bridge.cc b/chrome/browser/android/feed/feed_logging_bridge.cc
index a2d4839..aacfb0d 100644
--- a/chrome/browser/android/feed/feed_logging_bridge.cc
+++ b/chrome/browser/android/feed/feed_logging_bridge.cc
@@ -5,7 +5,9 @@
 #include "chrome/browser/android/feed/feed_logging_bridge.h"
 
 #include <jni.h>
+#include <vector>
 
+#include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/feed/feed_host_service_factory.h"
@@ -46,7 +48,7 @@
 
 void FeedLoggingBridge::OnContentViewed(
     JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
+    const JavaRef<jobject>& j_this,
     const jint j_position,
     const jlong j_publishedTimeMs,
     const jlong j_timeContentBecameAvailableMs,
@@ -56,28 +58,26 @@
       base::Time::FromJavaTime(j_timeContentBecameAvailableMs));
 }
 
-void FeedLoggingBridge::OnContentDismissed(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jint j_position,
-    const base::android::JavaRef<jstring>& j_url) {
+void FeedLoggingBridge::OnContentDismissed(JNIEnv* j_env,
+                                           const JavaRef<jobject>& j_this,
+                                           const jint j_position,
+                                           const JavaRef<jstring>& j_url,
+                                           const jboolean was_committed) {
   feed_logging_metrics_->OnSuggestionDismissed(
-      j_position, GURL(ConvertJavaStringToUTF8(j_env, j_url)));
+      j_position, GURL(ConvertJavaStringToUTF8(j_env, j_url)), was_committed);
 }
 
-void FeedLoggingBridge::OnContentSwiped(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this) {
+void FeedLoggingBridge::OnContentSwiped(JNIEnv* j_env,
+                                        const JavaRef<jobject>& j_this) {
   feed_logging_metrics_->OnSuggestionSwiped();
 }
 
-void FeedLoggingBridge::OnClientAction(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jint j_window_open_disposition,
-    const jint j_position,
-    const jlong j_publishedTimeMs,
-    const jfloat j_score) {
+void FeedLoggingBridge::OnClientAction(JNIEnv* j_env,
+                                       const JavaRef<jobject>& j_this,
+                                       const jint j_window_open_disposition,
+                                       const jint j_position,
+                                       const jlong j_publishedTimeMs,
+                                       const jfloat j_score) {
   feed_logging_metrics_->OnSuggestionOpened(
       j_position, base::Time::FromJavaTime(j_publishedTimeMs), j_score);
   feed_logging_metrics_->OnSuggestionWindowOpened(
@@ -86,7 +86,7 @@
 
 void FeedLoggingBridge::OnContentContextMenuOpened(
     JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
+    const JavaRef<jobject>& j_this,
     const jint j_position,
     const jlong j_publishedTimeMs,
     const jfloat j_score) {
@@ -106,6 +106,20 @@
   feed_logging_metrics_->OnMoreButtonClicked(j_position);
 }
 
+void FeedLoggingBridge::OnNotInterestedInSource(JNIEnv* j_env,
+                                                const JavaRef<jobject>& j_this,
+                                                const jint j_position,
+                                                const jboolean was_committed) {
+  feed_logging_metrics_->OnNotInterestedInSource(j_position, was_committed);
+}
+
+void FeedLoggingBridge::OnNotInterestedInTopic(JNIEnv* j_env,
+                                               const JavaRef<jobject>& j_this,
+                                               const jint j_position,
+                                               const jboolean was_committed) {
+  feed_logging_metrics_->OnNotInterestedInTopic(j_position, was_committed);
+}
+
 void FeedLoggingBridge::OnOpenedWithContent(JNIEnv* j_env,
                                             const JavaRef<jobject>& j_this,
                                             const jlong j_time_to_populate,
@@ -117,28 +131,35 @@
 
 void FeedLoggingBridge::OnOpenedWithNoImmediateContent(
     JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this) {}
+    const JavaRef<jobject>& j_this) {}
 
-void FeedLoggingBridge::OnOpenedWithNoContent(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this) {
+void FeedLoggingBridge::OnOpenedWithNoContent(JNIEnv* j_env,
+                                              const JavaRef<jobject>& j_this) {
   feed_logging_metrics_->OnPageShown(/*suggestions_count=*/0);
 }
 
-void FeedLoggingBridge::OnSpinnerShown(
-    JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jlong j_shownTimeMs) {
+void FeedLoggingBridge::OnSpinnerShown(JNIEnv* j_env,
+                                       const JavaRef<jobject>& j_this,
+                                       const jlong j_shownTimeMs) {
   feed_logging_metrics_->OnSpinnerShown(
       base::TimeDelta::FromMilliseconds(j_shownTimeMs));
 }
 
-void FeedLoggingBridge::OnContentTargetVisited(
+void FeedLoggingBridge::OnPietFrameRenderingEvent(
     JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this,
-    const jlong visit_time_ms,
-    const jboolean is_offline,
-    const jboolean return_to_ntp) {
+    const JavaRef<jobject>& j_this,
+    const JavaRef<jintArray>& j_piet_error_codes) {
+  std::vector<int> piet_error_codes;
+  base::android::JavaIntArrayToIntVector(j_env, j_piet_error_codes,
+                                         &piet_error_codes);
+  feed_logging_metrics_->OnPietFrameRenderingEvent(std::move(piet_error_codes));
+}
+
+void FeedLoggingBridge::OnContentTargetVisited(JNIEnv* j_env,
+                                               const JavaRef<jobject>& j_this,
+                                               const jlong visit_time_ms,
+                                               const jboolean is_offline,
+                                               const jboolean return_to_ntp) {
   if (is_offline) {
     feed_logging_metrics_->OnSuggestionOfflinePageVisited(
         base::TimeDelta::FromMilliseconds(visit_time_ms), return_to_ntp);
@@ -150,7 +171,7 @@
 
 void FeedLoggingBridge::ReportScrolledAfterOpen(
     JNIEnv* j_env,
-    const base::android::JavaRef<jobject>& j_this) {
+    const JavaRef<jobject>& j_this) {
   feed_logging_metrics_->ReportScrolledAfterOpen();
 }
 
diff --git a/chrome/browser/android/feed/feed_logging_bridge.h b/chrome/browser/android/feed/feed_logging_bridge.h
index 3208cbd..8315569d 100644
--- a/chrome/browser/android/feed/feed_logging_bridge.h
+++ b/chrome/browser/android/feed/feed_logging_bridge.h
@@ -33,7 +33,8 @@
   void OnContentDismissed(JNIEnv* j_env,
                           const base::android::JavaRef<jobject>& j_this,
                           const jint j_position,
-                          const base::android::JavaRef<jstring>& j_url);
+                          const base::android::JavaRef<jstring>& j_url,
+                          const jboolean was_committed);
 
   void OnContentSwiped(JNIEnv* j_env,
                        const base::android::JavaRef<jobject>& j_this);
@@ -59,6 +60,16 @@
                            const base::android::JavaRef<jobject>& j_this,
                            const jint j_position);
 
+  void OnNotInterestedInSource(JNIEnv* j_env,
+                               const base::android::JavaRef<jobject>& j_this,
+                               const jint j_position,
+                               const jboolean was_committed);
+
+  void OnNotInterestedInTopic(JNIEnv* j_env,
+                              const base::android::JavaRef<jobject>& j_this,
+                              const jint j_position,
+                              const jboolean was_committed);
+
   void OnOpenedWithContent(JNIEnv* j_env,
                            const base::android::JavaRef<jobject>& j_this,
                            const jlong j_time_to_populate,
@@ -75,6 +86,11 @@
                       const base::android::JavaRef<jobject>& j_this,
                       const jlong j_shownTimeMs);
 
+  void OnPietFrameRenderingEvent(
+      JNIEnv* j_env,
+      const base::android::JavaRef<jobject>& j_this,
+      const base::android::JavaRef<jintArray>& j_piet_error_codes);
+
   void OnContentTargetVisited(JNIEnv* j_env,
                               const base::android::JavaRef<jobject>& j_this,
                               const jlong visit_time_ms,
diff --git a/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc b/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc
index f396fec..7530040 100644
--- a/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc
+++ b/chrome/browser/browser_switcher/alternative_browser_driver_unittest.cc
@@ -21,6 +21,12 @@
 
 namespace {
 
+class TestBrowserSwitcherPrefs : public BrowserSwitcherPrefs {
+ public:
+  explicit TestBrowserSwitcherPrefs(PrefService* prefs)
+      : BrowserSwitcherPrefs(prefs, nullptr) {}
+};
+
 StringType UTF8ToNative(base::StringPiece src) {
 #if defined(OS_WIN)
   return base::UTF8ToWide(src);
@@ -46,7 +52,7 @@
  public:
   void SetUp() override {
     BrowserSwitcherPrefs::RegisterProfilePrefs(prefs_backend_.registry());
-    prefs_ = std::make_unique<BrowserSwitcherPrefs>(&prefs_backend_);
+    prefs_ = std::make_unique<TestBrowserSwitcherPrefs>(&prefs_backend_);
     driver_ = std::make_unique<AlternativeBrowserDriverImpl>(prefs_.get());
   }
 
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs.cc b/chrome/browser/browser_switcher/browser_switcher_prefs.cc
index 9a6cecb..da6f479a 100644
--- a/chrome/browser/browser_switcher/browser_switcher_prefs.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_prefs.cc
@@ -7,43 +7,87 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
+#include "chrome/browser/policy/profile_policy_connector.h"
+#include "chrome/browser/policy/profile_policy_connector_factory.h"
+#include "chrome/browser/profiles/profile.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_thread.h"
 
 namespace browser_switcher {
 
 RuleSet::RuleSet() = default;
 RuleSet::~RuleSet() = default;
 
-BrowserSwitcherPrefs::BrowserSwitcherPrefs(PrefService* prefs) : prefs_(prefs) {
-  DCHECK(prefs_);
+BrowserSwitcherPrefs::BrowserSwitcherPrefs(Profile* profile)
+    : BrowserSwitcherPrefs(
+          profile->GetPrefs(),
+          policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile)
+              ->policy_service()) {}
 
-  change_registrar_.Init(prefs_);
+BrowserSwitcherPrefs::BrowserSwitcherPrefs(
+    PrefService* prefs,
+    policy::PolicyService* policy_service)
+    : policy_service_(policy_service), prefs_(prefs), weak_ptr_factory_(this) {
+  filtering_change_registrar_.Init(prefs_);
 
   const struct {
     const char* pref_name;
-    void (BrowserSwitcherPrefs::*callback)();
+    base::RepeatingCallback<void(BrowserSwitcherPrefs*)> callback;
   } hooks[] = {
       {prefs::kAlternativeBrowserPath,
-       &BrowserSwitcherPrefs::AlternativeBrowserPathChanged},
+       base::BindRepeating(
+           &BrowserSwitcherPrefs::AlternativeBrowserPathChanged)},
       {prefs::kAlternativeBrowserParameters,
-       &BrowserSwitcherPrefs::AlternativeBrowserParametersChanged},
-      {prefs::kUrlList, &BrowserSwitcherPrefs::UrlListChanged},
-      {prefs::kUrlGreylist, &BrowserSwitcherPrefs::GreylistChanged},
+       base::BindRepeating(
+           &BrowserSwitcherPrefs::AlternativeBrowserParametersChanged)},
+      {prefs::kUrlList,
+       base::BindRepeating(&BrowserSwitcherPrefs::UrlListChanged)},
+      {prefs::kUrlGreylist,
+       base::BindRepeating(&BrowserSwitcherPrefs::GreylistChanged)},
   };
 
   // Listen for pref changes, and run all the hooks once to initialize state.
   for (const auto& hook : hooks) {
-    change_registrar_.Add(
-        hook.pref_name,
-        base::BindRepeating(hook.callback, base::Unretained(this)));
-    (*this.*hook.callback)();
+    auto callback = base::BindRepeating(hook.callback, base::Unretained(this));
+    filtering_change_registrar_.Add(hook.pref_name, callback);
+    callback.Run();
   }
+
+  // When any pref changes, mark this object as 'dirty' for the purpose of
+  // triggering observers.
+  notifying_change_registrar_.Init(prefs_);
+  const char* all_prefs[] = {
+    prefs::kEnabled,
+    prefs::kAlternativeBrowserPath,
+    prefs::kAlternativeBrowserParameters,
+    prefs::kKeepLastTab,
+    prefs::kUrlList,
+    prefs::kUrlGreylist,
+    prefs::kExternalSitelistUrl,
+#if defined(OS_WIN)
+    prefs::kUseIeSitelist,
+#endif
+  };
+  for (const char* pref_name : all_prefs) {
+    notifying_change_registrar_.Add(
+        pref_name, base::BindRepeating(&BrowserSwitcherPrefs::MarkDirty,
+                                       base::Unretained(this)));
+  }
+
+  if (policy_service_)
+    policy_service_->AddObserver(policy::POLICY_DOMAIN_CHROME, this);
 }
 
 BrowserSwitcherPrefs::~BrowserSwitcherPrefs() = default;
 
+void BrowserSwitcherPrefs::Shutdown() {
+  if (policy_service_)
+    policy_service_->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this);
+}
+
 // static
 void BrowserSwitcherPrefs::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
@@ -95,6 +139,33 @@
 }
 #endif
 
+void BrowserSwitcherPrefs::OnPolicyUpdated(const policy::PolicyNamespace& ns,
+                                           const policy::PolicyMap& previous,
+                                           const policy::PolicyMap& current) {
+  // Let all the other policy observers run first, so that prefs are up-to-date
+  // when we run our own callbacks.
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(&BrowserSwitcherPrefs::RunCallbacksIfDirty,
+                                weak_ptr_factory_.GetWeakPtr()));
+}
+
+std::unique_ptr<BrowserSwitcherPrefs::CallbackSubscription>
+BrowserSwitcherPrefs::RegisterPrefsChangedCallback(
+    BrowserSwitcherPrefs::PrefsChangedCallback cb) {
+  return callback_list_.Add(cb);
+}
+
+void BrowserSwitcherPrefs::RunCallbacksIfDirty() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (dirty_)
+    callback_list_.Notify(this);
+  dirty_ = false;
+}
+
+void BrowserSwitcherPrefs::MarkDirty() {
+  dirty_ = true;
+}
+
 void BrowserSwitcherPrefs::AlternativeBrowserPathChanged() {
   alt_browser_path_.clear();
   if (prefs_->IsManagedPreference(prefs::kAlternativeBrowserPath))
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs.h b/chrome/browser/browser_switcher/browser_switcher_prefs.h
index e15f078..030156dc 100644
--- a/chrome/browser/browser_switcher/browser_switcher_prefs.h
+++ b/chrome/browser/browser_switcher/browser_switcher_prefs.h
@@ -8,8 +8,13 @@
 #include <string>
 #include <vector>
 
+#include "base/callback.h"
+#include "base/callback_list.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/policy/core/common/policy_service.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "url/gurl.h"
 
@@ -18,6 +23,7 @@
 }  // namespace user_prefs
 
 class PrefService;
+class Profile;
 
 namespace browser_switcher {
 
@@ -34,10 +40,19 @@
 // only respects managed prefs. Also does some type conversions and
 // transformations on the prefs (e.g. expanding preset values for
 // AlternativeBrowserPath).
-class BrowserSwitcherPrefs {
+class BrowserSwitcherPrefs : public KeyedService,
+                             public policy::PolicyService::Observer {
  public:
-  explicit BrowserSwitcherPrefs(PrefService* prefs);
-  virtual ~BrowserSwitcherPrefs();
+  using PrefsChangedCallback =
+      base::RepeatingCallback<void(BrowserSwitcherPrefs*)>;
+  using CallbackSubscription =
+      base::CallbackList<void(BrowserSwitcherPrefs*)>::Subscription;
+
+  explicit BrowserSwitcherPrefs(Profile* profile);
+  ~BrowserSwitcherPrefs() override;
+
+  // KeyedService:
+  void Shutdown() override;
 
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
@@ -69,15 +84,42 @@
   bool UseIeSitelist() const;
 #endif
 
+  // policy::PolicyService::Observer
+  void OnPolicyUpdated(const policy::PolicyNamespace& ns,
+                       const policy::PolicyMap& previous,
+                       const policy::PolicyMap& current) override;
+
+  std::unique_ptr<CallbackSubscription> RegisterPrefsChangedCallback(
+      PrefsChangedCallback cb);
+
+ protected:
+  // For internal use and testing.
+  BrowserSwitcherPrefs(PrefService* prefs,
+                       policy::PolicyService* policy_service);
+
  private:
+  void RunCallbacksIfDirty();
+  void MarkDirty();
+
   // Hooks for PrefChangeRegistrar.
   void AlternativeBrowserPathChanged();
   void AlternativeBrowserParametersChanged();
   void UrlListChanged();
   void GreylistChanged();
 
-  PrefService* prefs_;
-  PrefChangeRegistrar change_registrar_;
+  policy::PolicyService* const policy_service_;
+  PrefService* const prefs_;
+
+  // We need 2 change registrars because we can't bind 2 observers to the same
+  // pref on the same registrar.
+
+  // Listens on *some* prefs, to apply a filter to them
+  // (e.g. convert ListValue => vector<string>).
+  PrefChangeRegistrar filtering_change_registrar_;
+
+  // Listens on *all* BrowserSwitcher prefs, to notify observers when prefs
+  // change as a result of a policy refresh.
+  PrefChangeRegistrar notifying_change_registrar_;
 
   // Type-converted and/or expanded pref values, updated by the
   // PrefChangeRegistrar hooks.
@@ -86,6 +128,13 @@
 
   RuleSet rules_;
 
+  // True if a policy refresh recently caused prefs to change.
+  bool dirty_ = false;
+
+  base::CallbackList<void(BrowserSwitcherPrefs*)> callback_list_;
+
+  base::WeakPtrFactory<BrowserSwitcherPrefs> weak_ptr_factory_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(BrowserSwitcherPrefs);
 };
 
diff --git a/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc b/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc
index 62a7eb6..8dd8e19 100644
--- a/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_prefs_unittest.cc
@@ -6,24 +6,39 @@
 
 #include <algorithm>
 #include <memory>
+#include <utility>
 
+#include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/browser_switcher/browser_switcher_prefs.h"
 #include "chrome/browser/browser_switcher/ieem_sitelist_parser.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/core/common/policy_map.h"
+#include "components/policy/core/common/policy_service_impl.h"
+#include "components/policy/policy_constants.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
 using testing::_;
 using testing::Invoke;
+using testing::Return;
 
 namespace browser_switcher {
 
 namespace {
 
+class TestBrowserSwitcherPrefs : public BrowserSwitcherPrefs {
+ public:
+  TestBrowserSwitcherPrefs(PrefService* prefs,
+                           policy::PolicyService* policy_service)
+      : BrowserSwitcherPrefs(prefs, policy_service) {}
+};
+
 std::unique_ptr<base::Value> StringArrayToValue(
     const std::vector<const char*>& strings) {
   std::vector<base::Value> values(strings.size());
@@ -38,16 +53,34 @@
  public:
   void SetUp() override {
     BrowserSwitcherPrefs::RegisterProfilePrefs(prefs_backend_.registry());
-    prefs_ = std::make_unique<BrowserSwitcherPrefs>(&prefs_backend_);
+    policy_provider_ =
+        std::make_unique<policy::MockConfigurationPolicyProvider>();
+    EXPECT_CALL(*policy_provider_, IsInitializationComplete(_))
+        .WillRepeatedly(Return(true));
+    std::vector<policy::ConfigurationPolicyProvider*> providers = {
+        policy_provider_.get()};
+    policy_service_ = std::make_unique<policy::PolicyServiceImpl>(providers);
+    prefs_ = std::make_unique<TestBrowserSwitcherPrefs>(&prefs_backend_,
+                                                        policy_service_.get());
   }
 
+  void TearDown() override { prefs_->Shutdown(); }
+
+  policy::MockConfigurationPolicyProvider* policy_provider() {
+    return policy_provider_.get();
+  }
   sync_preferences::TestingPrefServiceSyncable* prefs_backend() {
     return &prefs_backend_;
   }
   BrowserSwitcherPrefs* prefs() { return prefs_.get(); }
 
  private:
+  content::TestBrowserThreadBundle thread_bundle_;
+
   sync_preferences::TestingPrefServiceSyncable prefs_backend_;
+
+  std::unique_ptr<policy::MockConfigurationPolicyProvider> policy_provider_;
+  std::unique_ptr<policy::PolicyService> policy_service_;
   std::unique_ptr<BrowserSwitcherPrefs> prefs_;
 };
 
@@ -79,4 +112,29 @@
   EXPECT_EQ("foo.example.com", prefs()->GetRules().greylist[0]);
 }
 
+TEST_F(BrowserSwitcherPrefsTest, TriggersObserversOnPolicyChange) {
+  policy::PolicyMap policy_map;
+  policy_map.Set(policy::key::kAlternativeBrowserPath,
+                 policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
+                 policy::POLICY_SOURCE_PLATFORM,
+                 std::make_unique<base::Value>("notepad.exe"), nullptr);
+
+  base::RunLoop run_loop;
+  auto subscription = prefs()->RegisterPrefsChangedCallback(base::BindRepeating(
+      [](base::OnceClosure quit, BrowserSwitcherPrefs* prefs) {
+        EXPECT_EQ("notepad.exe", prefs->GetAlternativeBrowserPath());
+        std::move(quit).Run();
+      },
+      run_loop.QuitClosure()));
+
+  prefs_backend()->SetManagedPref(prefs::kAlternativeBrowserPath,
+                                  std::make_unique<base::Value>("notepad.exe"));
+  policy_provider()->UpdateChromePolicy(policy_map);
+
+  run_loop.Run();
+
+  // If this code is reached, the callback has run as expected. Now just clean
+  // up.
+}
+
 }  // namespace browser_switcher
diff --git a/chrome/browser/browser_switcher/browser_switcher_service.cc b/chrome/browser/browser_switcher/browser_switcher_service.cc
index 4310e81..9d454aa 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_service.cc
@@ -116,7 +116,7 @@
 }
 
 BrowserSwitcherService::BrowserSwitcherService(Profile* profile)
-    : prefs_(profile->GetPrefs()),
+    : prefs_(profile),
       driver_(new AlternativeBrowserDriverImpl(&prefs_)),
       sitelist_(new BrowserSwitcherSitelistImpl(&prefs_)),
       weak_ptr_factory_(this) {
@@ -129,7 +129,11 @@
   }
 }
 
-BrowserSwitcherService::~BrowserSwitcherService() {}
+BrowserSwitcherService::~BrowserSwitcherService() = default;
+
+void BrowserSwitcherService::Shutdown() {
+  prefs_.Shutdown();
+}
 
 AlternativeBrowserDriver* BrowserSwitcherService::driver() {
   return driver_.get();
diff --git a/chrome/browser/browser_switcher/browser_switcher_service.h b/chrome/browser/browser_switcher/browser_switcher_service.h
index 0cc6ffe72..91501ab7 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service.h
+++ b/chrome/browser/browser_switcher/browser_switcher_service.h
@@ -59,6 +59,9 @@
   explicit BrowserSwitcherService(Profile* profile);
   ~BrowserSwitcherService() override;
 
+  // KeyedService:
+  void Shutdown() override;
+
   AlternativeBrowserDriver* driver();
   BrowserSwitcherSitelist* sitelist();
   const BrowserSwitcherPrefs& prefs() const;
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_win.cc b/chrome/browser/browser_switcher/browser_switcher_service_win.cc
index c60a611..b49f418 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service_win.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_service_win.cc
@@ -71,10 +71,15 @@
   return buffer.str();
 }
 
-void SavePrefsToFile(std::string data) {
-  // Ensure the directory exists
+// Does the I/O for the |SavePrefsToFile()|. Should be run in a worker thread to
+// avoid blocking the main thread.
+void DoSavePrefsToFile(std::string data) {
+  // Ensure the directory exists.
   base::FilePath dir = GetCacheDir();
 
+  if (dir.empty())
+    return;
+
   bool success = base::CreateDirectory(dir);
   UMA_HISTOGRAM_BOOLEAN("BrowserSwitcher.CacheFile.MkDirSuccess", success);
   if (!success) {
@@ -105,6 +110,17 @@
   return ieem_sitelist_url_for_testing.get();
 }
 
+void DoRemovePrefsFile() {
+  base::FilePath dir = GetCacheDir();
+
+  if (dir.empty())
+    return;
+
+  // Ignore errors while deleting.
+  base::FilePath dest_path = dir.AppendASCII("cache.dat");
+  base::DeleteFile(dest_path, false);
+}
+
 }  // namespace
 
 BrowserSwitcherServiceWin::BrowserSwitcherServiceWin(Profile* profile)
@@ -119,21 +135,26 @@
     }
   }
 
-  if (prefs_.IsEnabled()) {
-    // TODO(nicolaso): also write cache.dat when policies change (e.g. after
-    // loading cloud policies or after enabling LBS while Chrome is running).
-    //
-    // Write the cache.dat file.
-    base::PostTaskWithTraits(
-        FROM_HERE,
-        {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
-         base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
-        base::BindOnce(&SavePrefsToFile, SerializeCacheFile(prefs_)));
-  }
+  if (prefs_.IsEnabled())
+    SavePrefsToFile();
+  else
+    DeletePrefsFile();
+
+  prefs_subscription_ = prefs_.RegisterPrefsChangedCallback(base::BindRepeating(
+      &BrowserSwitcherServiceWin::OnBrowserSwitcherPrefsChanged,
+      base::Unretained(this)));
 }
 
 BrowserSwitcherServiceWin::~BrowserSwitcherServiceWin() = default;
 
+void BrowserSwitcherServiceWin::OnBrowserSwitcherPrefsChanged(
+    BrowserSwitcherPrefs* prefs) {
+  if (prefs_.IsEnabled())
+    SavePrefsToFile();
+  else
+    DeletePrefsFile();
+}
+
 // static
 void BrowserSwitcherServiceWin::SetIeemSitelistUrlForTesting(
     const std::string& spec) {
@@ -167,4 +188,19 @@
   ieem_downloader_.reset();
 }
 
+void BrowserSwitcherServiceWin::SavePrefsToFile() const {
+  base::PostTaskWithTraits(
+      FROM_HERE,
+      {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+       base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
+      base::BindOnce(&DoSavePrefsToFile, SerializeCacheFile(prefs_)));
+}
+
+void BrowserSwitcherServiceWin::DeletePrefsFile() const {
+  base::PostTaskWithTraits(FROM_HERE,
+                           {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+                            base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
+                           base::BindOnce(&DoRemovePrefsFile));
+}
+
 }  // namespace browser_switcher
diff --git a/chrome/browser/browser_switcher/browser_switcher_service_win.h b/chrome/browser/browser_switcher/browser_switcher_service_win.h
index ff44535..e334106 100644
--- a/chrome/browser/browser_switcher/browser_switcher_service_win.h
+++ b/chrome/browser/browser_switcher/browser_switcher_service_win.h
@@ -19,6 +19,8 @@
   explicit BrowserSwitcherServiceWin(Profile* profile);
   ~BrowserSwitcherServiceWin() override;
 
+  void OnBrowserSwitcherPrefsChanged(BrowserSwitcherPrefs* prefs);
+
   static void SetIeemSitelistUrlForTesting(const std::string& url);
 
  private:
@@ -29,8 +31,19 @@
 
   void OnIeemSitelistParsed(ParsedXml xml);
 
+  // Save the current prefs' state to the "cache.dat" file, to be read & used by
+  // the Internet Explorer BHO. This call does not block, it only posts a task
+  // to a worker thread.
+  void SavePrefsToFile() const;
+  // Delete the "cache.dat" file created by |SavePrefsToFile()|. This call does
+  // not block, it only posts a task to a worker thread.
+  void DeletePrefsFile() const;
+
   std::unique_ptr<XmlDownloader> ieem_downloader_;
 
+  std::unique_ptr<BrowserSwitcherPrefs::CallbackSubscription>
+      prefs_subscription_;
+
   base::WeakPtrFactory<BrowserSwitcherServiceWin> weak_ptr_factory_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(BrowserSwitcherServiceWin);
diff --git a/chrome/browser/browser_switcher/browser_switcher_sitelist_unittest.cc b/chrome/browser/browser_switcher/browser_switcher_sitelist_unittest.cc
index c95e915d..d4868268 100644
--- a/chrome/browser/browser_switcher/browser_switcher_sitelist_unittest.cc
+++ b/chrome/browser/browser_switcher/browser_switcher_sitelist_unittest.cc
@@ -22,6 +22,12 @@
 
 namespace {
 
+class TestBrowserSwitcherPrefs : public BrowserSwitcherPrefs {
+ public:
+  explicit TestBrowserSwitcherPrefs(PrefService* prefs)
+      : BrowserSwitcherPrefs(prefs, nullptr) {}
+};
+
 std::unique_ptr<base::Value> StringArrayToValue(
     const std::vector<const char*>& strings) {
   std::vector<base::Value> values(strings.size());
@@ -43,7 +49,7 @@
                                   StringArrayToValue(url_list));
     prefs_backend_.SetManagedPref(prefs::kUrlGreylist,
                                   StringArrayToValue(url_greylist));
-    prefs_ = std::make_unique<BrowserSwitcherPrefs>(&prefs_backend_);
+    prefs_ = std::make_unique<TestBrowserSwitcherPrefs>(&prefs_backend_);
     sitelist_ = std::make_unique<BrowserSwitcherSitelistImpl>(prefs_.get());
   }
 
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index bb3f8208..862f081 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -18,6 +18,7 @@
 #include "base/callback_helpers.h"
 #include "base/metrics/user_metrics.h"
 #include "base/task/post_task.h"
+#include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "chrome/browser/android/feed/feed_host_service_factory.h"
 #include "chrome/browser/autofill/legacy_strike_database_factory.h"
@@ -313,6 +314,9 @@
            ~FILTERABLE_DATA_TYPES) == 0) ||
          filter_builder.IsEmptyBlacklist());
 
+  TRACE_EVENT0("browsing_data",
+               "ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData");
+
   // Embedder-defined DOM-accessible storage currently contains only
   // one datatype, which is the durable storage permission.
   if (remove_mask &
@@ -350,7 +354,7 @@
   //////////////////////////////////////////////////////////////////////////////
   // INITIALIZATION
   base::ScopedClosureRunner synchronous_clear_operations(
-      CreatePendingTaskCompletionClosure());
+      CreateTaskCompletionClosure(TracingDataType::kSynchronous));
   callback_ = std::move(callback);
 
   delete_begin_ = delete_begin;
@@ -399,7 +403,8 @@
       history_service->DeleteLocalAndRemoteHistoryBetween(
           WebHistoryServiceFactory::GetForProfile(profile_), delete_begin_,
           delete_end_,
-          base::AdaptCallbackForRepeating(CreatePendingTaskCompletionClosure()),
+          base::AdaptCallbackForRepeating(
+              CreateTaskCompletionClosure(TracingDataType::kHistory)),
           &history_task_tracker_);
     }
     if (ClipboardRecentContent::GetInstance())
@@ -452,8 +457,9 @@
     // created, so we'll not honor the time range.
     BrowserContext::GetDefaultStoragePartition(profile_)
         ->GetNetworkContext()
-        ->ClearHostCache(filter_builder.BuildNetworkServiceFilter(),
-                         CreatePendingTaskCompletionClosureForMojo());
+        ->ClearHostCache(
+            filter_builder.BuildNetworkServiceFilter(),
+            CreateTaskCompletionClosureForMojo(TracingDataType::kHostCache));
 
     // As part of history deletion we also delete the auto-generated keywords.
     TemplateURLService* keywords_model =
@@ -466,7 +472,7 @@
           base::AdaptCallbackForRepeating(base::BindOnce(
               &ChromeBrowsingDataRemoverDelegate::OnKeywordsLoaded,
               weak_ptr_factory_.GetWeakPtr(), nullable_filter,
-              CreatePendingTaskCompletionClosure())));
+              CreateTaskCompletionClosure(TracingDataType::kKeywordsModel))));
       keywords_model->Load();
     } else if (keywords_model) {
       keywords_model->RemoveAutoGeneratedForUrlsBetween(
@@ -498,7 +504,8 @@
           delete_begin_, delete_end_);
       // Ask for a call back when the above call is finished.
       web_data_service->GetDBTaskRunner()->PostTaskAndReply(
-          FROM_HERE, base::DoNothing(), CreatePendingTaskCompletionClosure());
+          FROM_HERE, base::DoNothing(),
+          CreateTaskCompletionClosure(TracingDataType::kAutofillOrigins));
 
       autofill::PersonalDataManager* data_manager =
           autofill::PersonalDataManagerFactory::GetForProfile(profile_);
@@ -513,13 +520,13 @@
             webrtc_logging::TextLogList::
                 GetWebRtcLogDirectoryForBrowserContextPath(profile_->GetPath()),
             delete_begin_),
-        CreatePendingTaskCompletionClosure());
+        CreateTaskCompletionClosure(TracingDataType::kWebrtcLogs));
 
 #if defined(OS_ANDROID)
     base::PostTaskWithTraitsAndReply(
         FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
         base::BindOnce(&ClearPrecacheInBackground, profile_),
-        CreatePendingTaskCompletionClosure());
+        CreateTaskCompletionClosure(TracingDataType::kPrecache));
 
     // Clear the history information (last launch time and origin URL) of any
     // registered webapps.
@@ -589,7 +596,7 @@
           profile_->GetVideoDecodePerfHistory();
       if (video_decode_perf_history) {
         video_decode_perf_history->ClearHistory(
-            CreatePendingTaskCompletionClosure());
+            CreateTaskCompletionClosure(TracingDataType::kVideoDecodeHistory));
       }
     }
 
@@ -601,7 +608,8 @@
             profile_);
     if (explore_sites_service) {
       explore_sites_service->ClearActivities(
-          delete_begin_, delete_end_, CreatePendingTaskCompletionClosure());
+          delete_begin_, delete_end_,
+          CreateTaskCompletionClosure(TracingDataType::kExploreSites));
     }
 #endif
 
@@ -658,9 +666,10 @@
 
         manager_ptr->DeleteCookies(
             std::move(deletion_filter),
-            base::BindOnce(&OnClearedCookies,
-                           CreatePendingTaskCompletionClosure(),
-                           std::move(cookie_manager)));
+            base::BindOnce(
+                &OnClearedCookies,
+                CreateTaskCompletionClosure(TracingDataType::kCookies),
+                std::move(cookie_manager)));
       }
     }
 
@@ -781,13 +790,14 @@
       password_store->RemoveLoginsByURLAndTime(
           filter, delete_begin_, delete_end_,
           base::AdaptCallbackForRepeating(
-              CreatePendingTaskCompletionClosure()));
+              CreateTaskCompletionClosure(TracingDataType::kPasswords)));
     }
 
     BrowserContext::GetDefaultStoragePartition(profile_)
         ->GetNetworkContext()
         ->ClearHttpAuthCache(delete_begin_,
-                             CreatePendingTaskCompletionClosureForMojo());
+                             CreateTaskCompletionClosureForMojo(
+                                 TracingDataType::kHttpAuthCache));
 
 #if defined(OS_MACOSX)
     device::fido::mac::TouchIdCredentialStore(
@@ -805,8 +815,8 @@
 
     if (password_store) {
       password_store->DisableAutoSignInForOrigins(
-          filter, base::AdaptCallbackForRepeating(
-                      CreatePendingTaskCompletionClosure()));
+          filter, base::AdaptCallbackForRepeating(CreateTaskCompletionClosure(
+                      TracingDataType::kDisableAutoSignin)));
     }
   }
 
@@ -818,8 +828,8 @@
     if (password_store) {
       password_store->RemoveStatisticsByOriginAndTime(
           nullable_filter, delete_begin_, delete_end_,
-          base::AdaptCallbackForRepeating(
-              CreatePendingTaskCompletionClosure()));
+          base::AdaptCallbackForRepeating(CreateTaskCompletionClosure(
+              TracingDataType::kPasswordsStatistics)));
     }
   }
 
@@ -845,12 +855,14 @@
       autofill::LegacyStrikeDatabase* legacy_strike_database =
           autofill::LegacyStrikeDatabaseFactory::GetForProfile(profile_);
       if (legacy_strike_database)
-        legacy_strike_database->ClearAllStrikes(base::AdaptCallbackForRepeating(
-            IgnoreArgument<bool>(CreatePendingTaskCompletionClosure())));
+        legacy_strike_database->ClearAllStrikes(
+            base::AdaptCallbackForRepeating(IgnoreArgument<bool>(
+                CreateTaskCompletionClosure(TracingDataType::kLegacyStrikes))));
 
       // Ask for a call back when the above calls are finished.
       web_data_service->GetDBTaskRunner()->PostTaskAndReply(
-          FROM_HERE, base::DoNothing(), CreatePendingTaskCompletionClosure());
+          FROM_HERE, base::DoNothing(),
+          CreateTaskCompletionClosure(TracingDataType::kAutofillData));
 
       autofill::PersonalDataManager* data_manager =
           autofill::PersonalDataManagerFactory::GetForProfile(profile_);
@@ -873,14 +885,16 @@
 #if BUILDFLAG(ENABLE_NACL)
     base::PostTaskWithTraits(
         FROM_HERE, {BrowserThread::IO},
-        base::BindOnce(&ClearNaClCacheOnIOThread,
-                       base::AdaptCallbackForRepeating(UIThreadTrampoline(
-                           CreatePendingTaskCompletionClosure()))));
+        base::BindOnce(
+            &ClearNaClCacheOnIOThread,
+            base::AdaptCallbackForRepeating(UIThreadTrampoline(
+                CreateTaskCompletionClosure(TracingDataType::kNaclCache)))));
     base::PostTaskWithTraits(
         FROM_HERE, {BrowserThread::IO},
-        base::BindOnce(&ClearPnaclCacheOnIOThread, delete_begin_, delete_end_,
-                       base::AdaptCallbackForRepeating(UIThreadTrampoline(
-                           CreatePendingTaskCompletionClosure()))));
+        base::BindOnce(
+            &ClearPnaclCacheOnIOThread, delete_begin_, delete_end_,
+            base::AdaptCallbackForRepeating(UIThreadTrampoline(
+                CreateTaskCompletionClosure(TracingDataType::kPnaclCache)))));
 #endif
 
     // The PrerenderManager may have a page actively being prerendered, which
@@ -933,7 +947,8 @@
               base::AdaptCallbackForRepeating(
                   IgnoreArgument<
                       offline_pages::OfflinePageModel::DeletePageResult>(
-                      CreatePendingTaskCompletionClosure())));
+                      CreateTaskCompletionClosure(
+                          TracingDataType::kOfflinePages))));
     }
 #endif
 
@@ -942,7 +957,7 @@
     if (webrtc_event_log_manager) {
       webrtc_event_log_manager->ClearCacheForBrowserContext(
           profile_, delete_begin_, delete_end_,
-          CreatePendingTaskCompletionClosure());
+          CreateTaskCompletionClosure(TracingDataType::kWebrtcEventLogs));
     } else {
       LOG(ERROR) << "WebRtcEventLogManager not instantiated.";
     }
@@ -977,7 +992,7 @@
           base::BindOnce(
               &ChromeBrowsingDataRemoverDelegate::OnWaitableEventSignaled,
               weak_ptr_factory_.GetWeakPtr(),
-              CreatePendingTaskCompletionClosure());
+              CreateTaskCompletionClosure(TracingDataType::kPluginData));
       watcher_.StartWatching(event, std::move(watcher_callback),
                              base::SequencedTaskRunnerHandle::Get());
     } else {
@@ -986,7 +1001,7 @@
       flash_lso_helper_->StartFetching(base::BindOnce(
           &ChromeBrowsingDataRemoverDelegate::OnSitesWithFlashDataFetched,
           weak_ptr_factory_.GetWeakPtr(), filter_builder.BuildPluginFilter(),
-          CreatePendingTaskCompletionClosure()));
+          CreateTaskCompletionClosure(TracingDataType::kFlashLsoHelper)));
     }
   }
 #endif
@@ -1033,14 +1048,16 @@
                 base::BindOnce(
                     &ChromeBrowsingDataRemoverDelegate::OnClearPlatformKeys,
                     weak_ptr_factory_.GetWeakPtr(),
-                    CreatePendingTaskCompletionClosure()));
+                    CreateTaskCompletionClosure(
+                        TracingDataType::kTpmAttestationKeys)));
       }
     }
 #endif  // defined(OS_CHROMEOS)
 
 #if defined(OS_ANDROID)
-    ClearMediaDrmLicenses(prefs, delete_begin_, delete_end, nullable_filter,
-                          CreatePendingTaskCompletionClosure());
+    ClearMediaDrmLicenses(
+        prefs, delete_begin_, delete_end, nullable_filter,
+        CreateTaskCompletionClosure(TracingDataType::kDrmLicenses));
 #endif  // defined(OS_ANDROID);
   }
 
@@ -1065,8 +1082,9 @@
     else
       mode = network::mojom::NetworkContext::DomainReliabilityClearMode::
           CLEAR_BEACONS;
-    domain_reliability_clearer_.Run(
-        filter_builder, mode, CreatePendingTaskCompletionClosureForMojo());
+    domain_reliability_clearer_.Run(filter_builder, mode,
+                                    CreateTaskCompletionClosureForMojo(
+                                        TracingDataType::kDomainReliability));
   }
 
 #if BUILDFLAG(ENABLE_REPORTING)
@@ -1076,10 +1094,11 @@
             ->GetNetworkContext();
     network_context->ClearReportingCacheReports(
         filter_builder.BuildNetworkServiceFilter(),
-        CreatePendingTaskCompletionClosureForMojo());
+        CreateTaskCompletionClosureForMojo(TracingDataType::kReportingCache));
     network_context->ClearNetworkErrorLogging(
         filter_builder.BuildNetworkServiceFilter(),
-        CreatePendingTaskCompletionClosureForMojo());
+        CreateTaskCompletionClosureForMojo(
+            TracingDataType::kNetworkErrorLogging));
   }
 #endif  // BUILDFLAG(ENABLE_REPORTING)
 
@@ -1097,11 +1116,14 @@
     ExternalProtocolHandler::ClearData(profile_);
 }
 
-void ChromeBrowsingDataRemoverDelegate::OnTaskComplete() {
+void ChromeBrowsingDataRemoverDelegate::OnTaskComplete(
+    TracingDataType data_type) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_GT(num_pending_tasks_, 0);
   num_pending_tasks_--;
-
+  TRACE_EVENT_ASYNC_END1("browsing_data", "ChromeBrowsingDataRemoverDelegate",
+                         static_cast<int>(data_type), "data_type",
+                         static_cast<int>(data_type));
   if (num_pending_tasks_)
     return;
 
@@ -1110,22 +1132,27 @@
 }
 
 base::OnceClosure
-ChromeBrowsingDataRemoverDelegate::CreatePendingTaskCompletionClosure() {
+ChromeBrowsingDataRemoverDelegate::CreateTaskCompletionClosure(
+    TracingDataType data_type) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   num_pending_tasks_++;
+  TRACE_EVENT_ASYNC_BEGIN1("browsing_data", "ChromeBrowsingDataRemoverDelegate",
+                           static_cast<int>(data_type), "data_type",
+                           static_cast<int>(data_type));
   return base::BindOnce(&ChromeBrowsingDataRemoverDelegate::OnTaskComplete,
-                        weak_ptr_factory_.GetWeakPtr());
+                        weak_ptr_factory_.GetWeakPtr(), data_type);
 }
 
 base::OnceClosure
-ChromeBrowsingDataRemoverDelegate::CreatePendingTaskCompletionClosureForMojo() {
+ChromeBrowsingDataRemoverDelegate::CreateTaskCompletionClosureForMojo(
+    TracingDataType data_type) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Note num_pending_tasks++ unnecessary here because it's done by the call to
-  // CreatePendingTaskCompletionClosure().
+  // CreateTaskCompletionClosure().
   return mojo::WrapCallbackWithDropHandler(
-      CreatePendingTaskCompletionClosure(),
+      CreateTaskCompletionClosure(data_type),
       base::BindOnce(&ChromeBrowsingDataRemoverDelegate::OnTaskComplete,
-                     weak_ptr_factory_.GetWeakPtr()));
+                     weak_ptr_factory_.GetWeakPtr(), data_type));
 }
 
 #if defined(OS_ANDROID)
@@ -1206,6 +1233,6 @@
     OnDeauthorizeFlashContentLicensesCompleted(uint32_t request_id,
                                                bool /* success */) {
   DCHECK_EQ(request_id, deauthorize_flash_content_licenses_request_id_);
-  OnTaskComplete();
+  OnTaskComplete(TracingDataType::kFlashDeauthorization);
 }
 #endif
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h
index 51a679ee..341bad0 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h
@@ -191,19 +191,54 @@
  private:
   using WebRtcEventLogManager = webrtc_event_logging::WebRtcEventLogManager;
 
-  // Called by the closures returned by CreatePendingTaskCompletionClosure().
+  // For debugging purposes. Please add new deletion tasks at the end.
+  enum class TracingDataType {
+    kSynchronous = 1,
+    kHistory = 2,
+    kHostNameResolution = 3,
+    kNaclCache = 4,
+    kPnaclCache = 5,
+    kAutofillData = 6,
+    kAutofillOrigins = 7,
+    kPluginData = 8,
+    kFlashLsoHelper = 9,
+    kDomainReliability = 10,
+    kNetworkPredictor = 11,
+    kWebrtcLogs = 12,
+    kVideoDecodeHistory = 13,
+    kCookies = 14,
+    kPasswords = 15,
+    kHttpAuthCache = 16,
+    kDisableAutoSignin = 17,
+    kPasswordsStatistics = 18,
+    kKeywordsModel = 19,
+    kReportingCache = 20,
+    kNetworkErrorLogging = 21,
+    kFlashDeauthorization = 22,
+    kOfflinePages = 23,
+    kPrecache = 24,
+    kExploreSites = 25,
+    kLegacyStrikes = 26,
+    kWebrtcEventLogs = 27,
+    kDrmLicenses = 28,
+    kHostCache = 29,
+    kTpmAttestationKeys = 30,
+  };
+
+  // Called by the closures returned by CreateTaskCompletionClosure().
   // Checks if all tasks have completed, and if so, calls callback_.
-  void OnTaskComplete();
+  void OnTaskComplete(TracingDataType data_type);
 
   // Increments the number of pending tasks by one, and returns a OnceClosure
   // that calls OnTaskComplete(). The Remover is complete once all the closures
   // created by this method have been invoked.
-  base::OnceClosure CreatePendingTaskCompletionClosure();
+  base::OnceClosure CreateTaskCompletionClosure(TracingDataType data_type);
 
-  // Same as CreatePendingTaskCompletionClosure() but guarantees that
+  // Same as CreateTaskCompletionClosure() but guarantees that
   // OnTaskComplete() is called if the task is dropped. That can typically
   // happen when the connection is closed while an interface call is made.
-  base::OnceClosure CreatePendingTaskCompletionClosureForMojo();
+  base::OnceClosure CreateTaskCompletionClosureForMojo(
+      TracingDataType data_type);
 
   // Callback for when TemplateURLService has finished loading. Clears the data,
   // clears the respective waiting flag, and invokes NotifyIfDone.
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 e210861..2321881 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
@@ -81,7 +81,7 @@
 #if defined(OS_CHROMEOS)
   // In browser tests, the profile may already by authenticated with stub
   // account |user_manager::kStubUserEmail|.
-  AccountInfo info =
+  CoreAccountInfo info =
       IdentityManagerFactory::GetForProfile(profile)->GetPrimaryAccountInfo();
   username = info.email;
 #endif
diff --git a/chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher.cc b/chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher.cc
index cfce499..13a41e6 100644
--- a/chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_robot_auth_code_fetcher.cc
@@ -71,7 +71,7 @@
   enterprise_management::DeviceServiceApiAccessRequest* request =
       fetch_request_job_->GetRequest()->mutable_service_api_access_request();
   request->set_oauth2_client_id(kAndoidClientId);
-  request->add_auth_scope(GaiaConstants::kAnyApiOAuth2Scope);
+  request->add_auth_scopes(GaiaConstants::kAnyApiOAuth2Scope);
   request->set_device_type(
       enterprise_management::DeviceServiceApiAccessRequest::ANDROID_OS);
 
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc
index 7f9ee412..693c95e 100644
--- a/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc
+++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc
@@ -35,7 +35,7 @@
   EnrollmentScreenTest() = default;
   ~EnrollmentScreenTest() override = default;
 
-  // InProcessBrowserTest:
+  // Overridden from InProcessBrowserTest:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     InProcessBrowserTest::SetUpCommandLine(command_line);
     command_line->AppendArg(switches::kLoginManager);
@@ -43,69 +43,64 @@
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
     ShowLoginWizard(OobeScreen::SCREEN_OOBE_ENROLLMENT);
+    EXPECT_EQ(WizardController::default_controller()->current_screen(),
+              enrollment_screen());
+    static_cast<BaseScreen*>(enrollment_screen())->base_screen_delegate_ =
+        &mock_base_screen_delegate_;
+  }
+  void TearDownOnMainThread() override {
+    static_cast<BaseScreen*>(enrollment_screen())->base_screen_delegate_ =
+        WizardController::default_controller();
+    InProcessBrowserTest::TearDownOnMainThread();
+  }
+
+  EnrollmentScreen* enrollment_screen() {
+    EXPECT_TRUE(WizardController::default_controller());
+    EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(
+        WizardController::default_controller()->screen_manager());
+    EXPECT_TRUE(enrollment_screen);
+    return enrollment_screen;
+  }
+
+  MockBaseScreenDelegate* mock_base_screen_delegate() {
+    return &mock_base_screen_delegate_;
   }
 
  private:
+  MockBaseScreenDelegate mock_base_screen_delegate_;
+
   DISALLOW_COPY_AND_ASSIGN(EnrollmentScreenTest);
 };
 
 IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, TestCancel) {
-  ASSERT_TRUE(WizardController::default_controller());
-
-  EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(
-      WizardController::default_controller()->screen_manager());
-  ASSERT_TRUE(enrollment_screen);
-
   base::RunLoop run_loop;
-  MockBaseScreenDelegate mock_base_screen_delegate;
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      &mock_base_screen_delegate;
-
-  ASSERT_EQ(WizardController::default_controller()->current_screen(),
-            enrollment_screen);
-
-  EXPECT_CALL(mock_base_screen_delegate,
+  EXPECT_CALL(*mock_base_screen_delegate(),
               OnExit(ScreenExitCode::ENTERPRISE_ENROLLMENT_COMPLETED))
       .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
-  enrollment_screen->OnCancel();
-  content::RunThisRunLoop(&run_loop);
-  Mock::VerifyAndClearExpectations(&mock_base_screen_delegate);
-
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      WizardController::default_controller();
+  enrollment_screen()->OnCancel();
+  run_loop.Run();
 }
 
 // Flaky test: crbug.com/394069
 IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, DISABLED_TestSuccess) {
-  ASSERT_TRUE(WizardController::default_controller());
-  EXPECT_FALSE(StartupUtils::IsOobeCompleted());
-
-  EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(
-      WizardController::default_controller()->screen_manager());
-  ASSERT_TRUE(enrollment_screen);
-
+  WizardController::SkipEnrollmentPromptsForTesting();
   base::RunLoop run_loop;
-  MockBaseScreenDelegate mock_base_screen_delegate;
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      &mock_base_screen_delegate;
-
-  ASSERT_EQ(WizardController::default_controller()->current_screen(),
-            enrollment_screen);
-
-  enrollment_screen->OnDeviceEnrolled();
-  run_loop.RunUntilIdle();
-  EXPECT_TRUE(StartupUtils::IsOobeCompleted());
-
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      WizardController::default_controller();
+  EXPECT_FALSE(StartupUtils::IsDeviceRegistered());
+  EXPECT_CALL(*mock_base_screen_delegate(),
+              OnExit(ScreenExitCode::ENTERPRISE_ENROLLMENT_COMPLETED))
+      .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
+  enrollment_screen()->OnDeviceAttributeUpdatePermission(false /* granted */);
+  run_loop.Run();
+  EXPECT_TRUE(StartupUtils::IsDeviceRegistered());
 }
 
 class AttestationAuthEnrollmentScreenTest : public EnrollmentScreenTest {
  public:
-  AttestationAuthEnrollmentScreenTest() {}
+  AttestationAuthEnrollmentScreenTest() = default;
+  ~AttestationAuthEnrollmentScreenTest() override = default;
 
  private:
-  // Overridden from InProcessBrowserTest:
+  // Overridden from EnrollmentScreenTest:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EnrollmentScreenTest::SetUpCommandLine(command_line);
     command_line->AppendSwitch(switches::kEnterpriseEnableZeroTouchEnrollment);
@@ -115,41 +110,18 @@
 };
 
 IN_PROC_BROWSER_TEST_F(AttestationAuthEnrollmentScreenTest, TestCancel) {
-  ASSERT_TRUE(WizardController::default_controller());
-
-  EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(
-      WizardController::default_controller()->screen_manager());
-  ASSERT_TRUE(enrollment_screen);
-
   base::RunLoop run_loop;
-  MockBaseScreenDelegate mock_base_screen_delegate;
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      &mock_base_screen_delegate;
 
-  ASSERT_EQ(WizardController::default_controller()->current_screen(),
-            enrollment_screen);
-
-  EXPECT_CALL(mock_base_screen_delegate,
+  EXPECT_CALL(*mock_base_screen_delegate(),
               OnExit(ScreenExitCode::ENTERPRISE_ENROLLMENT_COMPLETED))
       .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
-  ASSERT_FALSE(enrollment_screen->AdvanceToNextAuth());
-  enrollment_screen->OnCancel();
-  content::RunThisRunLoop(&run_loop);
-  Mock::VerifyAndClearExpectations(&mock_base_screen_delegate);
-
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      WizardController::default_controller();
+  ASSERT_FALSE(enrollment_screen()->AdvanceToNextAuth());
+  enrollment_screen()->OnCancel();
+  run_loop.Run();
 }
 
 IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, EnrollmentSpinner) {
-  WizardController* wcontroller = WizardController::default_controller();
-  ASSERT_TRUE(wcontroller);
-
-  EnrollmentScreen* enrollment_screen =
-      EnrollmentScreen::Get(wcontroller->screen_manager());
-  ASSERT_TRUE(enrollment_screen);
-
-  EnrollmentScreenView* view = enrollment_screen->GetView();
+  EnrollmentScreenView* view = enrollment_screen()->GetView();
   ASSERT_TRUE(view);
 
   test::JSChecker checker(
@@ -175,10 +147,11 @@
 
 class ForcedAttestationAuthEnrollmentScreenTest : public EnrollmentScreenTest {
  public:
-  ForcedAttestationAuthEnrollmentScreenTest() {}
+  ForcedAttestationAuthEnrollmentScreenTest() = default;
+  ~ForcedAttestationAuthEnrollmentScreenTest() override = default;
 
  private:
-  // Overridden from InProcessBrowserTest:
+  // Overridden from EnrollmentScreenTest:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EnrollmentScreenTest::SetUpCommandLine(command_line);
     command_line->AppendSwitchASCII(
@@ -189,38 +162,22 @@
 };
 
 IN_PROC_BROWSER_TEST_F(ForcedAttestationAuthEnrollmentScreenTest, TestCancel) {
-  ASSERT_TRUE(WizardController::default_controller());
-
-  EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(
-      WizardController::default_controller()->screen_manager());
-  ASSERT_TRUE(enrollment_screen);
-
   base::RunLoop run_loop;
-  MockBaseScreenDelegate mock_base_screen_delegate;
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      &mock_base_screen_delegate;
-
-  ASSERT_EQ(WizardController::default_controller()->current_screen(),
-            enrollment_screen);
-
-  EXPECT_CALL(mock_base_screen_delegate,
+  EXPECT_CALL(*mock_base_screen_delegate(),
               OnExit(ScreenExitCode::ENTERPRISE_ENROLLMENT_BACK))
       .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
-  ASSERT_FALSE(enrollment_screen->AdvanceToNextAuth());
-  enrollment_screen->OnCancel();
-  content::RunThisRunLoop(&run_loop);
-  Mock::VerifyAndClearExpectations(&mock_base_screen_delegate);
-
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      WizardController::default_controller();
+  ASSERT_FALSE(enrollment_screen()->AdvanceToNextAuth());
+  enrollment_screen()->OnCancel();
+  run_loop.Run();
 }
 
 class MultiAuthEnrollmentScreenTest : public EnrollmentScreenTest {
  public:
-  MultiAuthEnrollmentScreenTest() {}
+  MultiAuthEnrollmentScreenTest() = default;
+  ~MultiAuthEnrollmentScreenTest() override = default;
 
  private:
-  // Overridden from InProcessBrowserTest:
+  // Overridden from EnrollmentScreenTest:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EnrollmentScreenTest::SetUpCommandLine(command_line);
     command_line->AppendSwitch(switches::kEnterpriseEnableZeroTouchEnrollment);
@@ -237,38 +194,22 @@
 };
 
 IN_PROC_BROWSER_TEST_F(MultiAuthEnrollmentScreenTest, TestCancel) {
-  ASSERT_TRUE(WizardController::default_controller());
-
-  EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(
-      WizardController::default_controller()->screen_manager());
-  ASSERT_TRUE(enrollment_screen);
-
   base::RunLoop run_loop;
-  MockBaseScreenDelegate mock_base_screen_delegate;
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      &mock_base_screen_delegate;
-
-  ASSERT_EQ(WizardController::default_controller()->current_screen(),
-            enrollment_screen);
-
-  EXPECT_CALL(mock_base_screen_delegate,
+  EXPECT_CALL(*mock_base_screen_delegate(),
               OnExit(ScreenExitCode::ENTERPRISE_ENROLLMENT_BACK))
       .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
-  ASSERT_TRUE(enrollment_screen->AdvanceToNextAuth());
-  enrollment_screen->OnCancel();
-  content::RunThisRunLoop(&run_loop);
-  Mock::VerifyAndClearExpectations(&mock_base_screen_delegate);
-
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      WizardController::default_controller();
+  ASSERT_TRUE(enrollment_screen()->AdvanceToNextAuth());
+  enrollment_screen()->OnCancel();
+  run_loop.Run();
 }
 
 class ProvisionedEnrollmentScreenTest : public EnrollmentScreenTest {
  public:
-  ProvisionedEnrollmentScreenTest() {}
+  ProvisionedEnrollmentScreenTest() = default;
+  ~ProvisionedEnrollmentScreenTest() override = default;
 
  private:
-  // Overridden from InProcessBrowserTest:
+  // Overridden from EnrollmentScreenTest:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     EnrollmentScreenTest::SetUpCommandLine(command_line);
     base::FilePath test_data_dir;
@@ -283,29 +224,12 @@
 };
 
 IN_PROC_BROWSER_TEST_F(ProvisionedEnrollmentScreenTest, TestBackButton) {
-  ASSERT_TRUE(WizardController::default_controller());
-
-  EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(
-      WizardController::default_controller()->screen_manager());
-  ASSERT_TRUE(enrollment_screen);
-
   base::RunLoop run_loop;
-  MockBaseScreenDelegate mock_base_screen_delegate;
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      &mock_base_screen_delegate;
-
-  ASSERT_EQ(WizardController::default_controller()->current_screen(),
-            enrollment_screen);
-
-  EXPECT_CALL(mock_base_screen_delegate,
+  EXPECT_CALL(*mock_base_screen_delegate(),
               OnExit(ScreenExitCode::ENTERPRISE_ENROLLMENT_BACK))
       .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
-  enrollment_screen->OnCancel();
-  content::RunThisRunLoop(&run_loop);
-  Mock::VerifyAndClearExpectations(&mock_base_screen_delegate);
-
-  static_cast<BaseScreen*>(enrollment_screen)->base_screen_delegate_ =
-      WizardController::default_controller();
+  enrollment_screen()->OnCancel();
+  run_loop.Run();
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index e7ab2e6..aab985b 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -1192,11 +1192,6 @@
     }
 
     case apu::EcryptfsMigrationAction::kMinimalMigrate:
-      // Reset the profile ever initialized flag, so that user policy manager
-      // will block sign-in if no policy can be retrieved for the migrated
-      // profile.
-      user_manager::UserManager::Get()->ResetProfileEverInitialized(
-          user_context.GetAccountId());
       user_manager::known_user::SetUserHomeMinimalMigrationAttempted(
           user_context.GetAccountId(), true);
       user_manager::UserManager::Get()->GetLocalState()->CommitPendingWrite(
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc
index 417bb707..db47dbd 100644
--- a/chrome/browser/chromeos/login/login_manager_test.cc
+++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -161,7 +161,7 @@
   users_pref->AppendIfNotPresent(
       std::make_unique<base::Value>(account_id.GetUserEmail()));
   if (user_manager::UserManager::IsInitialized())
-    user_manager::known_user::SetProfileEverInitialized(account_id, false);
+    user_manager::known_user::SaveKnownUser(account_id);
 }
 
 void LoginManagerTest::SetExpectedCredentials(const UserContext& user_context) {
diff --git a/chrome/browser/chromeos/login/screens/base_screen.h b/chrome/browser/chromeos/login/screens/base_screen.h
index 277c224..b1fc32a 100644
--- a/chrome/browser/chromeos/login/screens/base_screen.h
+++ b/chrome/browser/chromeos/login/screens/base_screen.h
@@ -138,15 +138,8 @@
   ::login::ScreenContext context_;
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(EnrollmentScreenTest, TestCancel);
-  FRIEND_TEST_ALL_PREFIXES(EnrollmentScreenTest, TestSuccess);
-  FRIEND_TEST_ALL_PREFIXES(AttestationAuthEnrollmentScreenTest, TestCancel);
-  FRIEND_TEST_ALL_PREFIXES(ForcedAttestationAuthEnrollmentScreenTest,
-                           TestCancel);
-  FRIEND_TEST_ALL_PREFIXES(MultiAuthEnrollmentScreenTest, TestCancel);
-  FRIEND_TEST_ALL_PREFIXES(ProvisionedEnrollmentScreenTest, TestBackButton);
-
   friend class BaseWebUIHandler;
+  friend class EnrollmentScreenTest;
   friend class NetworkScreenTest;
   friend class ScreenEditor;
   friend class ScreenManager;
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
index d6d1660..2ec56ae4 100644
--- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc
+++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
@@ -466,11 +466,9 @@
       token_status == user_manager::User::OAUTH2_TOKEN_STATUS_INVALID)
     RecordReauthReason(user->GetAccountId(), ReauthReason::OTHER);
 
-  // We need to force an online signin if the user is marked as requiring it,
-  // or if the user's session never completed initialization (still need to
-  // check for policy/management state) or if there's an invalid OAUTH token
-  // that needs to be refreshed.
-  return user->force_online_signin() || !user->profile_ever_initialized() ||
+  // We need to force an online signin if the user is marked as requiring it or
+  // if there's an invalid OAUTH token that needs to be refreshed.
+  return user->force_online_signin() ||
          (has_gaia_account &&
           (token_status == user_manager::User::OAUTH2_TOKEN_STATUS_INVALID ||
            token_status == user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN));
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
index bfdff0b1..6047a2c 100644
--- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
+++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -246,10 +246,6 @@
 
 void FakeChromeUserManager::OnSessionStarted() {}
 
-void FakeChromeUserManager::OnProfileInitialized(user_manager::User* user) {
-  user->set_profile_ever_initialized(true);
-}
-
 void FakeChromeUserManager::RemoveUser(
     const AccountId& account_id,
     user_manager::RemoveUserDelegate* delegate) {}
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
index d14ae0d6..c7e947c3 100644
--- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
+++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
@@ -73,7 +73,6 @@
   void SwitchActiveUser(const AccountId& account_id) override;
   void SwitchToLastActiveUser() override;
   void OnSessionStarted() override;
-  void OnProfileInitialized(user_manager::User* user) override;
   void RemoveUser(const AccountId& account_id,
                   user_manager::RemoveUserDelegate* delegate) override;
   void RemoveUserFromList(const AccountId& account_id) override;
diff --git a/chrome/browser/chromeos/login/users/user_manager_unittest.cc b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
index cd094b8..9f73e62 100644
--- a/chrome/browser/chromeos/login/users/user_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
@@ -267,28 +267,6 @@
   ResetUserManager();
 }
 
-TEST_F(UserManagerTest, ProfileInitialized) {
-  user_manager::UserManager::Get()->UserLoggedIn(
-      owner_account_id_at_invalid_domain_,
-      owner_account_id_at_invalid_domain_.GetUserEmail(),
-      false /* browser_restart */, false /* is_child */);
-  const user_manager::UserList* users =
-      &user_manager::UserManager::Get()->GetUsers();
-  ASSERT_EQ(1U, users->size());
-  EXPECT_FALSE((*users)[0]->profile_ever_initialized());
-  ResetUserManager();
-  users = &user_manager::UserManager::Get()->GetUsers();
-  ASSERT_EQ(1U, users->size());
-  EXPECT_FALSE((*users)[0]->profile_ever_initialized());
-
-  user_manager::known_user::SetProfileEverInitialized(
-      (*users)[0]->GetAccountId(), true);
-  ResetUserManager();
-  users = &user_manager::UserManager::Get()->GetUsers();
-  ASSERT_EQ(1U, users->size());
-  EXPECT_TRUE((*users)[0]->profile_ever_initialized());
-}
-
 TEST_F(UserManagerTest, ProfileRequiresPolicyUnknown) {
   user_manager::UserManager::Get()->UserLoggedIn(
       owner_account_id_at_invalid_domain_,
diff --git a/chrome/browser/chromeos/policy/affiliation_test_helper.cc b/chrome/browser/chromeos/policy/affiliation_test_helper.cc
index c43d95fe..12d07e81 100644
--- a/chrome/browser/chromeos/policy/affiliation_test_helper.cc
+++ b/chrome/browser/chromeos/policy/affiliation_test_helper.cc
@@ -169,7 +169,7 @@
   users_pref->AppendIfNotPresent(
       std::make_unique<base::Value>(account_id.GetUserEmail()));
   if (user_manager::UserManager::IsInitialized())
-    user_manager::known_user::SetProfileEverInitialized(account_id, false);
+    user_manager::known_user::SaveKnownUser(account_id);
 
   chromeos::StartupUtils::MarkOobeCompleted();
 }
diff --git a/chrome/browser/chromeos/policy/app_install_event_log.cc b/chrome/browser/chromeos/policy/app_install_event_log.cc
index 39f8bf4c..fe788dd 100644
--- a/chrome/browser/chromeos/policy/app_install_event_log.cc
+++ b/chrome/browser/chromeos/policy/app_install_event_log.cc
@@ -132,7 +132,7 @@
 void AppInstallEventLog::Serialize(em::AppInstallReportRequest* report) {
   report->Clear();
   for (const auto& log : logs_) {
-    em::AppInstallReport* const report_log = report->add_app_install_report();
+    em::AppInstallReport* const report_log = report->add_app_install_reports();
     log.second->Serialize(report_log);
   }
 }
diff --git a/chrome/browser/chromeos/policy/app_install_event_log_manager_unittest.cc b/chrome/browser/chromeos/policy/app_install_event_log_manager_unittest.cc
index fb7ddc0..0c5bd0a 100644
--- a/chrome/browser/chromeos/policy/app_install_event_log_manager_unittest.cc
+++ b/chrome/browser/chromeos/policy/app_install_event_log_manager_unittest.cc
@@ -64,21 +64,21 @@
 
 bool ContainsSameEvents(const Events& expected,
                         const em::AppInstallReportRequest& actual) {
-  if (actual.app_install_report_size() != static_cast<int>(expected.size())) {
+  if (actual.app_install_reports_size() != static_cast<int>(expected.size())) {
     return false;
   }
   for (const auto& expected_app_log : expected) {
     bool app_found = false;
-    for (int i = 0; i < actual.app_install_report_size(); ++i) {
-      const auto& actual_app_log = actual.app_install_report(i);
+    for (int i = 0; i < actual.app_install_reports_size(); ++i) {
+      const auto& actual_app_log = actual.app_install_reports(i);
       if (actual_app_log.package() == expected_app_log.first) {
-        if (actual_app_log.log_size() !=
+        if (actual_app_log.logs_size() !=
             static_cast<int>(expected_app_log.second.size())) {
           return false;
         }
         for (int j = 0; j < static_cast<int>(expected_app_log.second.size());
              ++j) {
-          if (actual_app_log.log(j).SerializePartialAsString() !=
+          if (actual_app_log.logs(j).SerializePartialAsString() !=
               expected_app_log.second[j].SerializePartialAsString()) {
             return false;
           }
diff --git a/chrome/browser/chromeos/policy/app_install_event_log_unittest.cc b/chrome/browser/chromeos/policy/app_install_event_log_unittest.cc
index 8c2d7e3..9187d28 100644
--- a/chrome/browser/chromeos/policy/app_install_event_log_unittest.cc
+++ b/chrome/browser/chromeos/policy/app_install_event_log_unittest.cc
@@ -44,27 +44,27 @@
 
   void VerifyTenLogEntriesEach(int first_app_timestamp_offset,
                                int second_app_timestamp_offset) {
-    ASSERT_EQ(2, report_.app_install_report_size());
+    ASSERT_EQ(2, report_.app_install_reports_size());
     const int first_app_index =
-        report_.app_install_report(0).package() == kFirstPackageName ? 0 : 1;
+        report_.app_install_reports(0).package() == kFirstPackageName ? 0 : 1;
     const int second_app_index = 1 - first_app_index;
 
     const em::AppInstallReport& first_app_log =
-        report_.app_install_report(first_app_index);
+        report_.app_install_reports(first_app_index);
     EXPECT_EQ(kFirstPackageName, first_app_log.package());
-    ASSERT_EQ(10, first_app_log.log_size());
+    ASSERT_EQ(10, first_app_log.logs_size());
     for (int i = 0; i < 10; ++i) {
       EXPECT_EQ(i + first_app_timestamp_offset,
-                first_app_log.log(i).timestamp());
+                first_app_log.logs(i).timestamp());
     }
 
     const em::AppInstallReport& second_app_log =
-        report_.app_install_report(second_app_index);
+        report_.app_install_reports(second_app_index);
     EXPECT_EQ(kSecondPackageName, second_app_log.package());
-    ASSERT_EQ(10, second_app_log.log_size());
+    ASSERT_EQ(10, second_app_log.logs_size());
     for (int i = 0; i < 10; ++i) {
       EXPECT_EQ(i + second_app_timestamp_offset,
-                second_app_log.log(i).timestamp());
+                second_app_log.logs(i).timestamp());
     }
   }
 
@@ -88,11 +88,11 @@
   }
 
   void VerifyOneLogEntryEachPlusFirstApp(int first_app_log_entries) {
-    ASSERT_EQ(kMaxLogs, report_.app_install_report_size());
+    ASSERT_EQ(kMaxLogs, report_.app_install_reports_size());
     std::map<std::string, em::AppInstallReport> logs;
     for (int i = 0; i < kMaxLogs; ++i) {
-      logs[report_.app_install_report(i).package()] =
-          report_.app_install_report(i);
+      logs[report_.app_install_reports(i).package()] =
+          report_.app_install_reports(i);
     }
 
     for (int i = 0; i < kMaxLogs - 1; ++i) {
@@ -101,20 +101,20 @@
       const auto log = logs.find(package.str());
       ASSERT_NE(logs.end(), log);
       EXPECT_EQ(package.str(), log->second.package());
-      ASSERT_EQ(1, log->second.log_size());
-      EXPECT_EQ(i, log->second.log(0).timestamp());
+      ASSERT_EQ(1, log->second.logs_size());
+      EXPECT_EQ(i, log->second.logs(0).timestamp());
       EXPECT_EQ(em::AppInstallReportLogEvent::SUCCESS,
-                log->second.log(0).event_type());
+                log->second.logs(0).event_type());
     }
 
     const auto log = logs.find(kFirstPackageName);
     ASSERT_NE(logs.end(), log);
     EXPECT_EQ(kFirstPackageName, log->second.package());
-    ASSERT_EQ(first_app_log_entries, log->second.log_size());
+    ASSERT_EQ(first_app_log_entries, log->second.logs_size());
     for (int i = 0; i < first_app_log_entries; ++i) {
-      EXPECT_EQ(i + kMaxLogs - 1, log->second.log(i).timestamp());
+      EXPECT_EQ(i + kMaxLogs - 1, log->second.logs(i).timestamp());
       EXPECT_EQ(em::AppInstallReportLogEvent::SUCCESS,
-                log->second.log(i).event_type());
+                log->second.logs(i).event_type());
     }
 
     EXPECT_EQ(logs.end(), logs.find(kSecondPackageName));
@@ -136,7 +136,7 @@
   EXPECT_EQ(0, log_->max_size());
 
   log_->Serialize(&report_);
-  EXPECT_EQ(0, report_.app_install_report_size());
+  EXPECT_EQ(0, report_.app_install_reports_size());
 }
 
 // Populate the logs for two apps. Verify that the entries are serialized
@@ -154,29 +154,29 @@
   EXPECT_EQ(2, log_->max_size());
 
   log_->Serialize(&report_);
-  ASSERT_EQ(2, report_.app_install_report_size());
+  ASSERT_EQ(2, report_.app_install_reports_size());
   const int first_app_index =
-      report_.app_install_report(0).package() == kFirstPackageName ? 0 : 1;
+      report_.app_install_reports(0).package() == kFirstPackageName ? 0 : 1;
   const int second_app_index = 1 - first_app_index;
 
   const em::AppInstallReport& first_app_log =
-      report_.app_install_report(first_app_index);
+      report_.app_install_reports(first_app_index);
   EXPECT_EQ(kFirstPackageName, first_app_log.package());
-  ASSERT_EQ(2, first_app_log.log_size());
-  EXPECT_EQ(0, first_app_log.log(0).timestamp());
+  ASSERT_EQ(2, first_app_log.logs_size());
+  EXPECT_EQ(0, first_app_log.logs(0).timestamp());
   EXPECT_EQ(em::AppInstallReportLogEvent::SUCCESS,
-            first_app_log.log(0).event_type());
-  EXPECT_EQ(2, first_app_log.log(1).timestamp());
+            first_app_log.logs(0).event_type());
+  EXPECT_EQ(2, first_app_log.logs(1).timestamp());
   EXPECT_EQ(em::AppInstallReportLogEvent::SUCCESS,
-            first_app_log.log(1).event_type());
+            first_app_log.logs(1).event_type());
 
   const em::AppInstallReport& second_app_log =
-      report_.app_install_report(second_app_index);
+      report_.app_install_reports(second_app_index);
   EXPECT_EQ(kSecondPackageName, second_app_log.package());
-  ASSERT_EQ(1, second_app_log.log_size());
-  EXPECT_EQ(1, second_app_log.log(0).timestamp());
+  ASSERT_EQ(1, second_app_log.logs_size());
+  EXPECT_EQ(1, second_app_log.logs(0).timestamp());
   EXPECT_EQ(em::AppInstallReportLogEvent::SUCCESS,
-            second_app_log.log(0).event_type());
+            second_app_log.logs(0).event_type());
 }
 
 // Add 10 log entries for an app. Serialize the log. Clear the serialized log
@@ -200,7 +200,7 @@
 
   report_.Clear();
   log_->Serialize(&report_);
-  EXPECT_EQ(0, report_.app_install_report_size());
+  EXPECT_EQ(0, report_.app_install_reports_size());
 }
 
 // Add 10 log entries for a first app. Serialize the log. Add 10 more log
@@ -257,7 +257,7 @@
 
   report_.Clear();
   log_->Serialize(&report_);
-  EXPECT_EQ(0, report_.app_install_report_size());
+  EXPECT_EQ(0, report_.app_install_reports_size());
 }
 
 // Add entries for as many apps as the log has capacity for. Add entries for one
@@ -284,7 +284,7 @@
 
   report_.Clear();
   log_->Serialize(&report_);
-  EXPECT_EQ(0, report_.app_install_report_size());
+  EXPECT_EQ(0, report_.app_install_reports_size());
 }
 
 // Add entries for as many apps as the log has capacity for. Add entries for one
@@ -315,12 +315,12 @@
 
   report_.Clear();
   log_->Serialize(&report_);
-  ASSERT_EQ(1, report_.app_install_report_size());
-  const em::AppInstallReport& app_log = report_.app_install_report(0);
+  ASSERT_EQ(1, report_.app_install_reports_size());
+  const em::AppInstallReport& app_log = report_.app_install_reports(0);
   EXPECT_EQ(kFirstPackageName, app_log.package());
-  ASSERT_EQ(20, app_log.log_size());
+  ASSERT_EQ(20, app_log.logs_size());
   for (int i = 0; i < 20; ++i) {
-    EXPECT_EQ(i + kMaxLogs + 9, app_log.log(i).timestamp());
+    EXPECT_EQ(i + kMaxLogs + 9, app_log.logs(i).timestamp());
   }
 }
 
@@ -392,7 +392,7 @@
 
   report_.Clear();
   log.Serialize(&report_);
-  EXPECT_EQ(0, report_.app_install_report_size());
+  EXPECT_EQ(0, report_.app_install_reports_size());
 }
 
 // Populate and store a log. Load the log. Verify that that the log contents are
@@ -450,12 +450,12 @@
 
   report_.Clear();
   log.Serialize(&report_);
-  ASSERT_EQ(1, report_.app_install_report_size());
-  const em::AppInstallReport& app_log = report_.app_install_report(0);
+  ASSERT_EQ(1, report_.app_install_reports_size());
+  const em::AppInstallReport& app_log = report_.app_install_reports(0);
   EXPECT_EQ(kFirstPackageName, app_log.package());
-  ASSERT_EQ(10, app_log.log_size());
+  ASSERT_EQ(10, app_log.logs_size());
   for (int i = 0; i < 10; ++i) {
-    EXPECT_EQ(i, app_log.log(i).timestamp());
+    EXPECT_EQ(i, app_log.logs(i).timestamp());
   }
 }
 
@@ -488,7 +488,7 @@
   EXPECT_EQ(0, log.max_size());
 
   log.Serialize(&report_);
-  EXPECT_EQ(0, report_.app_install_report_size());
+  EXPECT_EQ(0, report_.app_install_reports_size());
 }
 
 // Add 10 log entries each for two apps. Store the log. Truncate the file to the
@@ -524,16 +524,16 @@
   EXPECT_EQ(10, log.max_size());
 
   log.Serialize(&report_);
-  ASSERT_EQ(1, report_.app_install_report_size());
-  const std::string& package_name = report_.app_install_report(0).package();
+  ASSERT_EQ(1, report_.app_install_reports_size());
+  const std::string& package_name = report_.app_install_reports(0).package();
   ASSERT_TRUE(package_name == kFirstPackageName ||
               package_name == kSecondPackageName);
 
-  const em::AppInstallReport& app_log = report_.app_install_report(0);
+  const em::AppInstallReport& app_log = report_.app_install_reports(0);
   EXPECT_EQ(package_name, app_log.package());
-  ASSERT_EQ(10, app_log.log_size());
+  ASSERT_EQ(10, app_log.logs_size());
   for (int i = 0; i < 10; ++i) {
-    EXPECT_EQ(i, app_log.log(i).timestamp());
+    EXPECT_EQ(i, app_log.logs(i).timestamp());
   }
 }
 
diff --git a/chrome/browser/chromeos/policy/app_install_event_log_uploader_unittest.cc b/chrome/browser/chromeos/policy/app_install_event_log_uploader_unittest.cc
index 953874b..c039b6c 100644
--- a/chrome/browser/chromeos/policy/app_install_event_log_uploader_unittest.cc
+++ b/chrome/browser/chromeos/policy/app_install_event_log_uploader_unittest.cc
@@ -278,7 +278,7 @@
 
   EXPECT_EQ(expected_delay, task_runner_->NextPendingTaskDelay());
 
-  log_.add_app_install_report()->set_package(kPackageName);
+  log_.add_app_install_reports()->set_package(kPackageName);
   CompleteSerializeAndUpload(true /* success */);
   EXPECT_CALL(delegate_, OnUploadSuccess());
   task_runner_->FastForwardBy(expected_delay);
@@ -341,7 +341,7 @@
   UnregisterClient();
   Mock::VerifyAndClearExpectations(&client_);
 
-  log_.add_app_install_report()->set_package(kPackageName);
+  log_.add_app_install_reports()->set_package(kPackageName);
   CompleteSerializeAndUpload(true /* success */);
   EXPECT_CALL(delegate_, OnUploadSuccess());
   RegisterClient();
@@ -374,7 +374,7 @@
   Mock::VerifyAndClearExpectations(&delegate_);
   Mock::VerifyAndClearExpectations(&client_);
 
-  log_.add_app_install_report()->set_package(kPackageName);
+  log_.add_app_install_reports()->set_package(kPackageName);
   CompleteSerializeAndUpload(true /* success */);
   EXPECT_CALL(delegate_, OnUploadSuccess());
   RegisterClient();
@@ -413,7 +413,7 @@
   Mock::VerifyAndClearExpectations(&delegate_);
   Mock::VerifyAndClearExpectations(&client_);
 
-  log_.add_app_install_report()->set_package(kPackageName);
+  log_.add_app_install_reports()->set_package(kPackageName);
   CompleteUpload(true /* success */);
   EXPECT_CALL(delegate_, OnUploadSuccess());
   std::move(serialization_callback_2).Run(&log_);
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client_impl.cc b/chrome/browser/chromeos/policy/auto_enrollment_client_impl.cc
index 2d1bf24..7929697 100644
--- a/chrome/browser/chromeos/policy/auto_enrollment_client_impl.cc
+++ b/chrome/browser/chromeos/policy/auto_enrollment_client_impl.cc
@@ -684,7 +684,7 @@
     }
   } else {
     // Server should have sent down a list of hashes to try.
-    has_server_state_ = IsIdHashInProtobuf(enrollment_response.hash());
+    has_server_state_ = IsIdHashInProtobuf(enrollment_response.hashes());
     // Cache the current decision in local_state, so that it is reused in case
     // the device reboots before enrolling.
     local_state_->SetBoolean(prefs::kShouldAutoEnroll, has_server_state_);
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client_impl_unittest.cc b/chrome/browser/chromeos/policy/auto_enrollment_client_impl_unittest.cc
index 9cbc7bca1..28704a8 100644
--- a/chrome/browser/chromeos/policy/auto_enrollment_client_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/auto_enrollment_client_impl_unittest.cc
@@ -126,15 +126,15 @@
             GetParam() == AutoEnrollmentProtocol::kFRE
                 ? hash_full
                 : hash_full.substr(0, kInitialEnrollmentIdHashLength);
-        enrollment_response->mutable_hash()->Add()->assign(hash);
+        enrollment_response->mutable_hashes()->Add()->assign(hash);
       }
     }
     if (with_id_hash) {
       if (GetParam() == AutoEnrollmentProtocol::kFRE) {
-        enrollment_response->mutable_hash()->Add()->assign(
+        enrollment_response->mutable_hashes()->Add()->assign(
             kStateKeyHash, crypto::kSHA256Length);
       } else {
-        enrollment_response->mutable_hash()->Add()->assign(
+        enrollment_response->mutable_hashes()->Add()->assign(
             kInitialEnrollmentIdHash, kInitialEnrollmentIdHashLength);
       }
     }
diff --git a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
index 4ee40e0..eb36bf0 100644
--- a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
+++ b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
@@ -208,7 +208,7 @@
   // Returns the body of the fetch response from the policy server.
   std::string GetPolicyResponse() {
     em::DeviceManagementResponse response;
-    response.mutable_policy_response()->add_response();
+    response.mutable_policy_response()->add_responses();
     std::string data;
     EXPECT_TRUE(response.SerializeToString(&data));
     return data;
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
index 6348208..301d22f 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -213,7 +213,7 @@
           DeviceNetworkConfigurationUpdater::DeviceAssetIDFetcher());
   // NetworkCertLoader may be not initialized in tests.
   if (chromeos::NetworkCertLoader::IsInitialized()) {
-    chromeos::NetworkCertLoader::Get()->AddPolicyCertificateProvider(
+    chromeos::NetworkCertLoader::Get()->SetDevicePolicyCertificateProvider(
         device_network_configuration_updater_.get());
   }
 
@@ -247,8 +247,8 @@
 void BrowserPolicyConnectorChromeOS::Shutdown() {
   // NetworkCertLoader may be not initialized in tests.
   if (chromeos::NetworkCertLoader::IsInitialized()) {
-    chromeos::NetworkCertLoader::Get()->RemovePolicyCertificateProvider(
-        device_network_configuration_updater_.get());
+    chromeos::NetworkCertLoader::Get()->SetDevicePolicyCertificateProvider(
+        nullptr);
   }
   device_network_configuration_updater_.reset();
 
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
index cde9da47..eafb8df 100644
--- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -375,7 +375,7 @@
   device_policy_.Build();
   session_manager_client_.set_device_policy(device_policy_.GetBlob());
   em::DeviceManagementResponse policy_fetch_response;
-  policy_fetch_response.mutable_policy_response()->add_response()->CopyFrom(
+  policy_fetch_response.mutable_policy_response()->add_responses()->CopyFrom(
       device_policy_.policy());
   policy_fetch_job->SendResponse(DM_STATUS_SUCCESS, policy_fetch_response);
   FlushDeviceSettings();
@@ -459,7 +459,7 @@
         PolicyBuilder::kFakeToken);
     register_response_.mutable_register_response()->set_enrollment_type(
         em::DeviceRegisterResponse::ENTERPRISE);
-    policy_fetch_response_.mutable_policy_response()->add_response()->CopyFrom(
+    policy_fetch_response_.mutable_policy_response()->add_responses()->CopyFrom(
         device_policy_.policy());
     robot_auth_fetch_response_.mutable_service_api_access_response()
         ->set_auth_code("auth_code_for_test");
@@ -754,7 +754,7 @@
 TEST_P(DeviceCloudPolicyManagerChromeOSEnrollmentTest, ValidationFailed) {
   device_policy_.policy().set_policy_data_signature("bad");
   policy_fetch_response_.clear_policy_response();
-  policy_fetch_response_.mutable_policy_response()->add_response()->CopyFrom(
+  policy_fetch_response_.mutable_policy_response()->add_responses()->CopyFrom(
       device_policy_.policy());
   RunTest();
   ExpectFailedEnrollment(EnrollmentStatus::VALIDATION_FAILED);
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
index 3e3c243..d5fc39d 100644
--- a/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
@@ -394,7 +394,7 @@
 
   em::DeviceManagementRequest request;
   em::DeviceManagementResponse response;
-  response.mutable_policy_response()->add_response()->CopyFrom(
+  response.mutable_policy_response()->add_responses()->CopyFrom(
       device_local_account_policy_.policy());
   EXPECT_CALL(mock_device_management_service_,
               CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH, _))
@@ -412,12 +412,12 @@
   Mock::VerifyAndClearExpectations(&service_observer_);
   Mock::VerifyAndClearExpectations(&mock_device_management_service_);
   EXPECT_TRUE(request.has_policy_request());
-  ASSERT_EQ(2, request.policy_request().request_size());
+  ASSERT_EQ(2, request.policy_request().requests_size());
 
   const em::PolicyFetchRequest* public_account =
-      &request.policy_request().request(0);
+      &request.policy_request().requests(0);
   const em::PolicyFetchRequest* extensions =
-      &request.policy_request().request(1);
+      &request.policy_request().requests(1);
   // The order is not guarateed.
   if (extensions->policy_type() ==
       dm_protocol::kChromePublicAccountPolicyType) {
@@ -458,7 +458,7 @@
   ASSERT_TRUE(broker->core()->service());
 
   em::DeviceManagementResponse response;
-  response.mutable_policy_response()->add_response()->CopyFrom(
+  response.mutable_policy_response()->add_responses()->CopyFrom(
       device_local_account_policy_.policy());
   EXPECT_CALL(mock_device_management_service_, CreateJob(_, _))
       .WillOnce(mock_device_management_service_.SucceedJob(response));
@@ -959,7 +959,7 @@
   ASSERT_TRUE(request_job);
   em::DeviceManagementResponse response;
   device_local_account_policy_.Build();
-  response.mutable_policy_response()->add_response()->CopyFrom(
+  response.mutable_policy_response()->add_responses()->CopyFrom(
       device_local_account_policy_.policy());
   request_job->SendResponse(DM_STATUS_SUCCESS, response);
   FlushDeviceSettings();
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc
index e1fef3e..006ca3a 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -477,22 +477,22 @@
   }
 
   void OnVolumeInfoReceived(const std::vector<em::VolumeInfo>& volume_info) {
-    device_status_->clear_volume_info();
+    device_status_->clear_volume_infos();
     for (const em::VolumeInfo& info : volume_info)
-      *device_status_->add_volume_info() = info;
+      *device_status_->add_volume_infos() = info;
   }
 
   void OnCPUTempInfoReceived(
       const std::vector<em::CPUTempInfo>& cpu_temp_info) {
     // Only one of OnProbeDataReceived and OnCPUTempInfoReceived should be
     // called.
-    DCHECK(device_status_->cpu_temp_info_size() == 0);
+    DCHECK(device_status_->cpu_temp_infos_size() == 0);
 
     DLOG_IF(WARNING, cpu_temp_info.empty())
         << "Unable to read CPU temp information.";
     base::Time timestamp = base::Time::Now();
     for (const em::CPUTempInfo& info : cpu_temp_info) {
-      auto* new_info = device_status_->add_cpu_temp_info();
+      auto* new_info = device_status_->add_cpu_temp_infos();
       *new_info = info;
       new_info->set_timestamp(timestamp.ToJavaTime());
     }
@@ -539,13 +539,13 @@
 
     // Only one of OnProbeDataReceived and OnCPUTempInfoReceived should be
     // called.
-    DCHECK(device_status_->cpu_temp_info_size() == 0);
+    DCHECK(device_status_->cpu_temp_infos_size() == 0);
 
     // Store CPU measurement samples.
     for (const std::unique_ptr<SampledData>& sample_data : samples) {
       for (auto it = sample_data->cpu_samples.begin();
            it != sample_data->cpu_samples.end(); it++) {
-        auto* new_info = device_status_->add_cpu_temp_info();
+        auto* new_info = device_status_->add_cpu_temp_infos();
         *new_info = it->second;
       }
     }
@@ -576,7 +576,7 @@
         for (const std::unique_ptr<SampledData>& sample_data : samples) {
           auto it = sample_data->battery_samples.find(battery.name());
           if (it != sample_data->battery_samples.end())
-            battery_info->add_sample()->CheckTypeAndMergeFrom(it->second);
+            battery_info->add_samples()->CheckTypeAndMergeFrom(it->second);
         }
       }
     }
@@ -1645,7 +1645,7 @@
     int64_t end_timestamp =
         activity_period.start_timestamp + Time::kMillisecondsPerDay;
 
-    em::ActiveTimePeriod* active_period = status->add_active_period();
+    em::ActiveTimePeriod* active_period = status->add_active_periods();
     em::TimePeriod* period = active_period->mutable_time_period();
     period->set_start_timestamp(activity_period.start_timestamp);
     period->set_end_timestamp(end_timestamp);
@@ -1772,7 +1772,7 @@
     if (type_idx >= base::size(kDeviceTypeMap))
       continue;
 
-    em::NetworkInterface* interface = status->add_network_interface();
+    em::NetworkInterface* interface = status->add_network_interfaces();
     interface->set_type(kDeviceTypeMap[type_idx].type_constant);
     if (!(*device)->mac_address().empty())
       interface->set_mac_address((*device)->mac_address());
@@ -1812,7 +1812,7 @@
     }
 
     // Copy fields from NetworkState into the status report.
-    em::NetworkState* proto_state = status->add_network_state();
+    em::NetworkState* proto_state = status->add_network_states();
     proto_state->set_connection_state(connection_state_enum);
     anything_reported = true;
 
@@ -1852,7 +1852,7 @@
     if (!user->HasGaiaAccount())
       continue;
 
-    em::DeviceUser* device_user = status->add_user();
+    em::DeviceUser* device_user = status->add_users();
     if (chromeos::ChromeUserManager::Get()->ShouldReportUser(
             user->GetAccountId().GetUserEmail())) {
       device_user->set_type(em::DeviceUser::USER_TYPE_MANAGED);
@@ -1876,11 +1876,11 @@
   // regular intervals. Unlike CPU temp and volume info these are not one-time
   // sampled values, hence the difference in logic.
   status->set_system_ram_total(base::SysInfo::AmountOfPhysicalMemory());
-  status->clear_system_ram_free();
-  status->clear_cpu_utilization_pct();
+  status->clear_system_ram_free_samples();
+  status->clear_cpu_utilization_pct_samples();
   for (const ResourceUsage& usage : resource_usage_) {
-    status->add_cpu_utilization_pct(usage.cpu_usage_percent);
-    status->add_system_ram_free(usage.bytes_of_ram_free);
+    status->add_cpu_utilization_pct_samples(usage.cpu_usage_percent);
+    status->add_system_ram_free_samples(usage.bytes_of_ram_free);
   }
 
   // Get the current device sound volume level.
@@ -1891,7 +1891,7 @@
   state->FetchTpmStatus(tpm_status_fetcher_);
 
   // clear
-  status->clear_cpu_temp_info();
+  status->clear_cpu_temp_infos();
 
   if (report_power_status_ || report_storage_status_) {
     state->FetchProbeData(probe_data_fetcher_);
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
index 391eb3f..41bf298 100644
--- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -230,8 +230,8 @@
 // status report.
 int64_t GetActiveMilliseconds(const em::DeviceStatusReportRequest& status) {
   int64_t active_milliseconds = 0;
-  for (int i = 0; i < status.active_period_size(); i++) {
-    active_milliseconds += status.active_period(i).active_duration();
+  for (int i = 0; i < status.active_periods_size(); i++) {
+    active_milliseconds += status.active_periods(i).active_duration();
   }
   return active_milliseconds;
 }
@@ -690,20 +690,20 @@
 
   // Test reporting with no data.
   GetStatus();
-  EXPECT_EQ(0, device_status_.active_period_size());
+  EXPECT_EQ(0, device_status_.active_periods_size());
   EXPECT_EQ(0, GetActiveMilliseconds(device_status_));
 
   // Test reporting with a single idle sample.
   status_collector_->Simulate(test_states, 1);
   GetStatus();
-  EXPECT_EQ(0, device_status_.active_period_size());
+  EXPECT_EQ(0, device_status_.active_periods_size());
   EXPECT_EQ(0, GetActiveMilliseconds(device_status_));
 
   // Test reporting with multiple consecutive idle samples.
   status_collector_->Simulate(test_states,
                               sizeof(test_states) / sizeof(ui::IdleState));
   GetStatus();
-  EXPECT_EQ(0, device_status_.active_period_size());
+  EXPECT_EQ(0, device_status_.active_periods_size());
   EXPECT_EQ(0, GetActiveMilliseconds(device_status_));
 }
 
@@ -719,16 +719,16 @@
   // Test a single active sample.
   status_collector_->Simulate(test_states, 1);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
+  EXPECT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
-  device_status_.clear_active_period();  // Clear the result protobuf.
+  device_status_.clear_active_periods();  // Clear the result protobuf.
 
   // Test multiple consecutive active samples.
   status_collector_->Simulate(test_states,
                               sizeof(test_states) / sizeof(ui::IdleState));
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
+  EXPECT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(4 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
 }
@@ -835,7 +835,7 @@
   status_collector_->Simulate(test_states,
                               sizeof(test_states) / sizeof(ui::IdleState));
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
+  EXPECT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(3 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
 
@@ -871,7 +871,7 @@
 
   // Check that we don't exceed the max number of periods.
   GetStatus();
-  EXPECT_EQ(kMaxDays - 1, device_status_.active_period_size());
+  EXPECT_EQ(kMaxDays - 1, device_status_.active_periods_size());
 
   // Simulate some future times.
   for (int i = 0; i < kMaxDays + 2; i++) {
@@ -889,9 +889,9 @@
   status_collector_->Simulate(test_states, 1);
 
   // Check that we don't exceed the max number of periods.
-  device_status_.clear_active_period();
+  device_status_.clear_active_periods();
   GetStatus();
-  EXPECT_LT(device_status_.active_period_size(), kMaxDays);
+  EXPECT_LT(device_status_.active_periods_size(), kMaxDays);
 }
 
 TEST_F(DeviceStatusCollectorTest, ActivityTimesEnabledByDefault) {
@@ -904,7 +904,7 @@
   status_collector_->Simulate(test_states,
                               sizeof(test_states) / sizeof(ui::IdleState));
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
+  EXPECT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(3 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
 }
@@ -921,7 +921,7 @@
   status_collector_->Simulate(test_states,
                               sizeof(test_states) / sizeof(ui::IdleState));
   GetStatus();
-  EXPECT_EQ(0, device_status_.active_period_size());
+  EXPECT_EQ(0, device_status_.active_periods_size());
   EXPECT_EQ(0, GetActiveMilliseconds(device_status_));
 }
 
@@ -938,10 +938,10 @@
 
   status_collector_->Simulate(test_states, 1);
   GetStatus();
-  ASSERT_EQ(2, device_status_.active_period_size());
+  ASSERT_EQ(2, device_status_.active_periods_size());
 
-  em::ActiveTimePeriod period0 = device_status_.active_period(0);
-  em::ActiveTimePeriod period1 = device_status_.active_period(1);
+  em::ActiveTimePeriod period0 = device_status_.active_periods(0);
+  em::ActiveTimePeriod period1 = device_status_.active_periods(1);
   EXPECT_EQ(ActivePeriodMilliseconds() - 10000, period0.active_duration());
   EXPECT_EQ(10000, period1.active_duration());
 
@@ -977,11 +977,11 @@
 
   // The collector returns the same activity times again.
   GetStatus();
-  int period_count = first_status.active_period_size();
-  EXPECT_EQ(period_count, device_status_.active_period_size());
+  int period_count = first_status.active_periods_size();
+  EXPECT_EQ(period_count, device_status_.active_periods_size());
   for (int n = 0; n < period_count; ++n) {
-    EXPECT_EQ(first_status.active_period(n).SerializeAsString(),
-              device_status_.active_period(n).SerializeAsString());
+    EXPECT_EQ(first_status.active_periods(n).SerializeAsString(),
+              device_status_.active_periods(n).SerializeAsString());
   }
 
   // After indicating a successful submit, the submitted status gets cleared,
@@ -1002,8 +1002,8 @@
 
   status_collector_->Simulate(test_states, 3);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
-  EXPECT_TRUE(device_status_.active_period(0).user_email().empty());
+  EXPECT_EQ(1, device_status_.active_periods_size());
+  EXPECT_TRUE(device_status_.active_periods(0).user_email().empty());
 }
 
 TEST_F(DeviceStatusCollectorTest, ActivityWithPublicSessionUser) {
@@ -1019,8 +1019,8 @@
 
   status_collector_->Simulate(test_states, 3);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
-  EXPECT_TRUE(device_status_.active_period(0).user_email().empty());
+  EXPECT_EQ(1, device_status_.active_periods_size());
+  EXPECT_TRUE(device_status_.active_periods(0).user_email().empty());
 }
 
 TEST_F(DeviceStatusCollectorTest, ActivityWithAffiliatedUser) {
@@ -1036,18 +1036,18 @@
 
   status_collector_->Simulate(test_states, 3);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
+  EXPECT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(account_id0.GetUserEmail(),
-            device_status_.active_period(0).user_email());
-  device_status_.clear_active_period();  // Clear the result protobuf.
+            device_status_.active_periods(0).user_email());
+  device_status_.clear_active_periods();  // Clear the result protobuf.
 
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportDeviceUsers, false);
 
   status_collector_->Simulate(test_states, 3);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
-  EXPECT_TRUE(device_status_.active_period(0).user_email().empty());
+  EXPECT_EQ(1, device_status_.active_periods_size());
+  EXPECT_TRUE(device_status_.active_periods(0).user_email().empty());
 }
 
 TEST_F(DeviceStatusCollectorTest, ActivityWithNotAffiliatedUser) {
@@ -1063,17 +1063,17 @@
 
   status_collector_->Simulate(test_states, 3);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
-  EXPECT_TRUE(device_status_.active_period(0).user_email().empty());
-  device_status_.clear_active_period();  // Clear the result protobuf.
+  EXPECT_EQ(1, device_status_.active_periods_size());
+  EXPECT_TRUE(device_status_.active_periods(0).user_email().empty());
+  device_status_.clear_active_periods();  // Clear the result protobuf.
 
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportDeviceUsers, false);
 
   status_collector_->Simulate(test_states, 3);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
-  EXPECT_TRUE(device_status_.active_period(0).user_email().empty());
+  EXPECT_EQ(1, device_status_.active_periods_size());
+  EXPECT_TRUE(device_status_.active_periods(0).user_email().empty());
 }
 
 TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
@@ -1223,31 +1223,32 @@
 
   // Verify that users are reported by default.
   GetStatus();
-  EXPECT_EQ(6, device_status_.user_size());
+  EXPECT_EQ(6, device_status_.users_size());
 
   // Verify that users are reported after enabling the setting.
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportDeviceUsers, true);
   GetStatus();
-  EXPECT_EQ(6, device_status_.user_size());
-  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.user(0).type());
-  EXPECT_EQ(account_id0.GetUserEmail(), device_status_.user(0).email());
-  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.user(1).type());
-  EXPECT_EQ(account_id1.GetUserEmail(), device_status_.user(1).email());
-  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.user(2).type());
-  EXPECT_EQ(account_id2.GetUserEmail(), device_status_.user(2).email());
-  EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED, device_status_.user(3).type());
-  EXPECT_FALSE(device_status_.user(3).has_email());
-  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.user(4).type());
-  EXPECT_EQ(account_id4.GetUserEmail(), device_status_.user(4).email());
-  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.user(5).type());
-  EXPECT_EQ(account_id5.GetUserEmail(), device_status_.user(5).email());
+  EXPECT_EQ(6, device_status_.users_size());
+  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.users(0).type());
+  EXPECT_EQ(account_id0.GetUserEmail(), device_status_.users(0).email());
+  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.users(1).type());
+  EXPECT_EQ(account_id1.GetUserEmail(), device_status_.users(1).email());
+  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.users(2).type());
+  EXPECT_EQ(account_id2.GetUserEmail(), device_status_.users(2).email());
+  EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED,
+            device_status_.users(3).type());
+  EXPECT_FALSE(device_status_.users(3).has_email());
+  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.users(4).type());
+  EXPECT_EQ(account_id4.GetUserEmail(), device_status_.users(4).email());
+  EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, device_status_.users(5).type());
+  EXPECT_EQ(account_id5.GetUserEmail(), device_status_.users(5).email());
 
   // Verify that users are no longer reported if setting is disabled.
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportDeviceUsers, false);
   GetStatus();
-  EXPECT_EQ(0, device_status_.user_size());
+  EXPECT_EQ(0, device_status_.users_size());
 }
 
 TEST_F(DeviceStatusCollectorTest, TestVolumeInfo) {
@@ -1281,12 +1282,12 @@
 
   GetStatus();
   EXPECT_EQ(expected_mount_points.size(),
-            static_cast<size_t>(device_status_.volume_info_size()));
+            static_cast<size_t>(device_status_.volume_infos_size()));
 
   // Walk the returned VolumeInfo to make sure it matches.
   for (const em::VolumeInfo& expected_info : expected_volume_info) {
     bool found = false;
-    for (const em::VolumeInfo& info : device_status_.volume_info()) {
+    for (const em::VolumeInfo& info : device_status_.volume_infos()) {
       if (info.volume_id() == expected_info.volume_id()) {
         EXPECT_EQ(expected_info.storage_total(), info.storage_total());
         EXPECT_EQ(expected_info.storage_free(), info.storage_free());
@@ -1302,7 +1303,7 @@
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportDeviceHardwareStatus, false);
   GetStatus();
-  EXPECT_EQ(0, device_status_.volume_info_size());
+  EXPECT_EQ(0, device_status_.volume_infos_size());
 }
 
 TEST_F(DeviceStatusCollectorTest, TestAvailableMemory) {
@@ -1316,7 +1317,7 @@
   }
   GetStatus();
   EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples),
-            device_status_.system_ram_free().size());
+            device_status_.system_ram_free_samples().size());
   EXPECT_TRUE(device_status_.has_system_ram_total());
   // No good way to inject specific test values for available system RAM, so
   // just make sure it's > 0.
@@ -1335,16 +1336,16 @@
   // Force finishing tasks posted by ctor of DeviceStatusCollector.
   content::RunAllTasksUntilIdle();
   GetStatus();
-  ASSERT_EQ(1, device_status_.cpu_utilization_pct().size());
-  EXPECT_EQ(100, device_status_.cpu_utilization_pct(0));
+  ASSERT_EQ(1, device_status_.cpu_utilization_pct_samples().size());
+  EXPECT_EQ(100, device_status_.cpu_utilization_pct_samples(0));
 
   // Now sample CPU usage again (active usage counters will not increase
   // so should show 0% cpu usage).
   status_collector_->RefreshSampleResourceUsage();
   base::RunLoop().RunUntilIdle();
   GetStatus();
-  ASSERT_EQ(2, device_status_.cpu_utilization_pct().size());
-  EXPECT_EQ(0, device_status_.cpu_utilization_pct(1));
+  ASSERT_EQ(2, device_status_.cpu_utilization_pct_samples().size());
+  EXPECT_EQ(0, device_status_.cpu_utilization_pct_samples(1));
 
   // Now store a bunch of 0% cpu usage and make sure we cap the max number of
   // samples.
@@ -1359,15 +1360,15 @@
   // Should not be more than kMaxResourceUsageSamples, and they should all show
   // the CPU is idle.
   EXPECT_EQ(static_cast<int>(DeviceStatusCollector::kMaxResourceUsageSamples),
-            device_status_.cpu_utilization_pct().size());
-  for (const auto utilization : device_status_.cpu_utilization_pct())
+            device_status_.cpu_utilization_pct_samples().size());
+  for (const auto utilization : device_status_.cpu_utilization_pct_samples())
     EXPECT_EQ(0, utilization);
 
   // Turning off hardware reporting should not report CPU utilization.
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportDeviceHardwareStatus, false);
   GetStatus();
-  EXPECT_EQ(0, device_status_.cpu_utilization_pct().size());
+  EXPECT_EQ(0, device_status_.cpu_utilization_pct_samples().size());
 }
 
 TEST_F(DeviceStatusCollectorTest, TestCPUTemp) {
@@ -1391,12 +1392,12 @@
 
   GetStatus();
   EXPECT_EQ(expected_temp_info.size(),
-            static_cast<size_t>(device_status_.cpu_temp_info_size()));
+            static_cast<size_t>(device_status_.cpu_temp_infos_size()));
 
   // Walk the returned CPUTempInfo to make sure it matches.
   for (const em::CPUTempInfo& expected_info : expected_temp_info) {
     bool found = false;
-    for (const em::CPUTempInfo& info : device_status_.cpu_temp_info()) {
+    for (const em::CPUTempInfo& info : device_status_.cpu_temp_infos()) {
       if (info.cpu_label() == expected_info.cpu_label()) {
         EXPECT_EQ(expected_info.cpu_temp(), info.cpu_temp());
         found = true;
@@ -1411,7 +1412,7 @@
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportDeviceHardwareStatus, false);
   GetStatus();
-  EXPECT_EQ(0, device_status_.cpu_temp_info_size());
+  EXPECT_EQ(0, device_status_.cpu_temp_infos_size());
 }
 
 TEST_F(DeviceStatusCollectorTest, KioskAndroidReporting) {
@@ -1991,15 +1992,15 @@
   // Test a single active sample.
   status_collector_->Simulate(test_states, 1);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
+  EXPECT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
-  device_status_.clear_active_period();  // Clear the result protobuf.
+  device_status_.clear_active_periods();  // Clear the result protobuf.
 
   // Test multiple consecutive active samples.
   status_collector_->Simulate(test_states, 4);
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
+  EXPECT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(4 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
 }
@@ -2015,10 +2016,10 @@
 
   GetStatus();
 
-  ASSERT_EQ(2, device_status_.active_period_size());
+  ASSERT_EQ(2, device_status_.active_periods_size());
 
-  em::ActiveTimePeriod period0 = device_status_.active_period(0);
-  em::ActiveTimePeriod period1 = device_status_.active_period(1);
+  em::ActiveTimePeriod period0 = device_status_.active_periods(0);
+  em::ActiveTimePeriod period1 = device_status_.active_periods(1);
   EXPECT_EQ(ActivePeriodMilliseconds() - 10000, period0.active_duration());
   EXPECT_EQ(10000, period1.active_duration());
 
@@ -2052,13 +2053,13 @@
 
   GetStatus();
 
-  ASSERT_EQ(2, device_status_.active_period_size());
+  ASSERT_EQ(2, device_status_.active_periods_size());
   EXPECT_EQ(3 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
-            device_status_.active_period(0).active_duration());
+            device_status_.active_periods(0).active_duration());
   EXPECT_EQ(2 * ActivePeriodMilliseconds(),
-            device_status_.active_period(1).active_duration());
+            device_status_.active_periods(1).active_duration());
 
   // Set clock after day start and report 1 activity.
   SetCurrentTime(kLaterDayStart + kHour);
@@ -2066,15 +2067,15 @@
 
   GetStatus();
 
-  ASSERT_EQ(3, device_status_.active_period_size());
+  ASSERT_EQ(3, device_status_.active_periods_size());
   EXPECT_EQ(4 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
-            device_status_.active_period(0).active_duration());
+            device_status_.active_periods(0).active_duration());
   EXPECT_EQ(2 * ActivePeriodMilliseconds(),
-            device_status_.active_period(1).active_duration());
+            device_status_.active_periods(1).active_duration());
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
-            device_status_.active_period(2).active_duration());
+            device_status_.active_periods(2).active_duration());
 }
 
 TEST_F(DeviceStatusCollectorDayStartTest, ActivityDayStartChangesToEarlier) {
@@ -2097,13 +2098,13 @@
 
   GetStatus();
 
-  ASSERT_EQ(2, device_status_.active_period_size());
+  ASSERT_EQ(2, device_status_.active_periods_size());
   EXPECT_EQ(3 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
-            device_status_.active_period(0).active_duration());
+            device_status_.active_periods(0).active_duration());
   EXPECT_EQ(2 * ActivePeriodMilliseconds(),
-            device_status_.active_period(1).active_duration());
+            device_status_.active_periods(1).active_duration());
 
   // Set clock after day start and report 1 activity.
   SetCurrentTime(kEarlierDayStart + kHour);
@@ -2111,15 +2112,15 @@
 
   GetStatus();
 
-  ASSERT_EQ(3, device_status_.active_period_size());
+  ASSERT_EQ(3, device_status_.active_periods_size());
   EXPECT_EQ(4 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
-            device_status_.active_period(0).active_duration());
+            device_status_.active_periods(0).active_duration());
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
-            device_status_.active_period(1).active_duration());
+            device_status_.active_periods(1).active_duration());
   EXPECT_EQ(2 * ActivePeriodMilliseconds(),
-            device_status_.active_period(2).active_duration());
+            device_status_.active_periods(2).active_duration());
 }
 
 TEST_F(DeviceStatusCollectorDayStartTest,
@@ -2143,13 +2144,13 @@
 
   GetStatus();
 
-  ASSERT_EQ(2, device_status_.active_period_size());
+  ASSERT_EQ(2, device_status_.active_periods_size());
   EXPECT_EQ(3 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   EXPECT_EQ(2 * ActivePeriodMilliseconds(),
-            device_status_.active_period(0).active_duration());
+            device_status_.active_periods(0).active_duration());
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
-            device_status_.active_period(1).active_duration());
+            device_status_.active_periods(1).active_duration());
 
   // Move day start back.
   RestartStatusCollectorWithDayStart(kDayStart);
@@ -2159,13 +2160,13 @@
 
   GetStatus();
 
-  ASSERT_EQ(2, device_status_.active_period_size());
+  ASSERT_EQ(2, device_status_.active_periods_size());
   EXPECT_EQ(4 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   EXPECT_EQ(3 * ActivePeriodMilliseconds(),
-            device_status_.active_period(0).active_duration());
+            device_status_.active_periods(0).active_duration());
   EXPECT_EQ(1 * ActivePeriodMilliseconds(),
-            device_status_.active_period(1).active_duration());
+            device_status_.active_periods(1).active_duration());
 }
 
 class DeviceStatusCollectorNetworkInterfacesTest
@@ -2301,8 +2302,8 @@
       bool found_match = false;
       google::protobuf::RepeatedPtrField<em::NetworkInterface>::const_iterator
           iface;
-      for (iface = device_status_.network_interface().begin();
-           iface != device_status_.network_interface().end(); ++iface) {
+      for (iface = device_status_.network_interfaces().begin();
+           iface != device_status_.network_interfaces().end(); ++iface) {
         // Check whether type, field presence and field values match.
         if (dev.expected_type == iface->type() &&
             iface->has_mac_address() == !!*dev.mac_address &&
@@ -2321,15 +2322,15 @@
       count++;
     }
 
-    EXPECT_EQ(count, device_status_.network_interface_size());
+    EXPECT_EQ(count, device_status_.network_interfaces_size());
 
     // Now make sure network state list is correct.
     EXPECT_EQ(base::size(kFakeNetworks),
-              static_cast<size_t>(device_status_.network_state_size()));
+              static_cast<size_t>(device_status_.network_states_size()));
     for (const FakeNetworkState& state : kFakeNetworks) {
       bool found_match = false;
       for (const em::NetworkState& proto_state :
-           device_status_.network_state()) {
+           device_status_.network_states()) {
         // Make sure every item has a matching entry in the proto.
         bool should_have_signal_strength = state.expected_signal_strength != 0;
         if (proto_state.has_device_path() == (strlen(state.device_path) > 0) &&
@@ -2358,8 +2359,8 @@
   // If not in an active kiosk session, there should be network interfaces
   // reported, but no network state.
   GetStatus();
-  EXPECT_LT(0, device_status_.network_interface_size());
-  EXPECT_EQ(0, device_status_.network_state_size());
+  EXPECT_LT(0, device_status_.network_interfaces_size());
+  EXPECT_EQ(0, device_status_.network_states_size());
 }
 
 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, NetworkInterfaces) {
@@ -2370,15 +2371,15 @@
 
   // Interfaces should be reported by default.
   GetStatus();
-  EXPECT_LT(0, device_status_.network_interface_size());
-  EXPECT_LT(0, device_status_.network_state_size());
+  EXPECT_LT(0, device_status_.network_interfaces_size());
+  EXPECT_LT(0, device_status_.network_states_size());
 
   // No interfaces should be reported if the policy is off.
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
       chromeos::kReportDeviceNetworkInterfaces, false);
   GetStatus();
-  EXPECT_EQ(0, device_status_.network_interface_size());
-  EXPECT_EQ(0, device_status_.network_state_size());
+  EXPECT_EQ(0, device_status_.network_interfaces_size());
+  EXPECT_EQ(0, device_status_.network_states_size());
 
   // Switch the policy on and verify the interface list is present.
   scoped_testing_cros_settings_.device_settings()->SetBoolean(
@@ -2538,7 +2539,7 @@
 
   GetStatus();
 
-  EXPECT_EQ(0, device_status_.volume_info_size());
+  EXPECT_EQ(0, device_status_.volume_infos_size());
 }
 
 TEST_F(ConsumerDeviceStatusCollectorTimeLimitDisabledTest, NotReportingUsers) {
@@ -2551,7 +2552,7 @@
 
   GetStatus();
 
-  EXPECT_EQ(0, device_status_.user_size());
+  EXPECT_EQ(0, device_status_.users_size());
 }
 
 TEST_F(ConsumerDeviceStatusCollectorTimeLimitDisabledTest,
@@ -2590,9 +2591,9 @@
   GetStatus();
 
   EXPECT_FALSE(device_status_.has_sound_volume());
-  EXPECT_EQ(0, device_status_.cpu_utilization_pct().size());
-  EXPECT_EQ(0, device_status_.cpu_temp_info_size());
-  EXPECT_EQ(0, device_status_.system_ram_free().size());
+  EXPECT_EQ(0, device_status_.cpu_utilization_pct_samples().size());
+  EXPECT_EQ(0, device_status_.cpu_temp_infos_size());
+  EXPECT_EQ(0, device_status_.system_ram_free_samples().size());
   EXPECT_FALSE(device_status_.has_system_ram_total());
   EXPECT_FALSE(device_status_.has_tpm_status_info());
 }
@@ -2619,7 +2620,7 @@
   status_collector_->Simulate(test_states, 3);
 
   GetStatus();
-  EXPECT_EQ(0, device_status_.active_period_size());
+  EXPECT_EQ(0, device_status_.active_periods_size());
 }
 
 // Tests collecting device status for registered consumer device when time
@@ -2652,12 +2653,12 @@
 
   GetStatus();
 
-  ASSERT_EQ(1, device_status_.active_period_size());
+  ASSERT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(5 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   ExpectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds());
   EXPECT_EQ(user_account_id_.GetUserEmail(),
-            device_status_.active_period(0).user_email());
+            device_status_.active_periods(0).user_email());
 }
 
 TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest,
@@ -2678,12 +2679,12 @@
 
   GetStatus();
 
-  ASSERT_EQ(1, device_status_.active_period_size());
+  ASSERT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(4 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   ExpectChildScreenTimeMilliseconds(4 * ActivePeriodMilliseconds());
   EXPECT_EQ(user_account_id_.GetUserEmail(),
-            device_status_.active_period(0).user_email());
+            device_status_.active_periods(0).user_email());
 }
 
 TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest,
@@ -2703,12 +2704,12 @@
 
   GetStatus();
 
-  ASSERT_EQ(1, device_status_.active_period_size());
+  ASSERT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(5 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   ExpectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds());
   EXPECT_EQ(user_account_id_.GetUserEmail(),
-            device_status_.active_period(0).user_email());
+            device_status_.active_periods(0).user_email());
 }
 
 TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ActivityKeptInPref) {
@@ -2770,7 +2771,7 @@
   SimulateStateChanges(test_states,
                        sizeof(test_states) / sizeof(DeviceStateTransitions));
   GetStatus();
-  EXPECT_EQ(1, device_status_.active_period_size());
+  EXPECT_EQ(1, device_status_.active_periods_size());
   EXPECT_EQ(5 * ActivePeriodMilliseconds(),
             GetActiveMilliseconds(device_status_));
   ExpectChildScreenTimeMilliseconds(5 * ActivePeriodMilliseconds());
@@ -2822,10 +2823,10 @@
   SimulateStateChanges(test_states,
                        sizeof(test_states) / sizeof(DeviceStateTransitions));
   GetStatus();
-  ASSERT_EQ(2, device_status_.active_period_size());
+  ASSERT_EQ(2, device_status_.active_periods_size());
 
-  em::ActiveTimePeriod period0 = device_status_.active_period(0);
-  em::ActiveTimePeriod period1 = device_status_.active_period(1);
+  em::ActiveTimePeriod period0 = device_status_.active_periods(0);
+  em::ActiveTimePeriod period1 = device_status_.active_periods(1);
   EXPECT_EQ(ActivePeriodMilliseconds() - 15000, period0.active_duration());
   EXPECT_EQ(15000, period1.active_duration());
 
@@ -2856,7 +2857,7 @@
   SimulateStateChanges(test_states, 1);
 
   GetStatus();
-  ASSERT_EQ(1, device_status_.active_period_size());
+  ASSERT_EQ(1, device_status_.active_periods_size());
   ExpectChildScreenTimeMilliseconds(ActivePeriodMilliseconds());
 }
 
diff --git a/chrome/browser/chromeos/policy/single_app_install_event_log.cc b/chrome/browser/chromeos/policy/single_app_install_event_log.cc
index b265753..13d150d 100644
--- a/chrome/browser/chromeos/policy/single_app_install_event_log.cc
+++ b/chrome/browser/chromeos/policy/single_app_install_event_log.cc
@@ -160,7 +160,7 @@
   report->set_package(package_);
   report->set_incomplete(incomplete_);
   for (const auto& event : events_) {
-    em::AppInstallReportLogEvent* const log_event = report->add_log();
+    em::AppInstallReportLogEvent* const log_event = report->add_logs();
     *log_event = event;
   }
   serialized_entries_ = events_.size();
diff --git a/chrome/browser/chromeos/policy/single_app_install_event_log_unittest.cc b/chrome/browser/chromeos/policy/single_app_install_event_log_unittest.cc
index ab2d056..d3b1fe48 100644
--- a/chrome/browser/chromeos/policy/single_app_install_event_log_unittest.cc
+++ b/chrome/browser/chromeos/policy/single_app_install_event_log_unittest.cc
@@ -73,7 +73,7 @@
 
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  EXPECT_EQ(0, report_.log_size());
+  EXPECT_EQ(0, report_.logs_size());
 }
 
 // Add a log entry. Verify that the entry is serialized correctly.
@@ -87,11 +87,11 @@
 
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(1, report_.log_size());
+  ASSERT_EQ(1, report_.logs_size());
   std::string original_event;
   event.SerializeToString(&original_event);
   std::string log_event;
-  report_.log(0).SerializeToString(&log_event);
+  report_.logs(0).SerializeToString(&log_event);
   EXPECT_EQ(original_event, log_event);
 }
 
@@ -109,9 +109,9 @@
 
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(10, report_.log_size());
+  ASSERT_EQ(10, report_.logs_size());
   for (int i = 0; i < 10; ++i) {
-    EXPECT_EQ(i, report_.log(i).timestamp());
+    EXPECT_EQ(i, report_.logs(i).timestamp());
   }
 
   log_->ClearSerialized();
@@ -121,7 +121,7 @@
   report_.Clear();
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  EXPECT_EQ(0, report_.log_size());
+  EXPECT_EQ(0, report_.logs_size());
 }
 
 // Add 10 log entries. Serialize the log. Add 10 more log entries. Clear the
@@ -151,9 +151,9 @@
 
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(10, report_.log_size());
+  ASSERT_EQ(10, report_.logs_size());
   for (int i = 0; i < 10; ++i) {
-    EXPECT_EQ(i + 10, report_.log(i).timestamp());
+    EXPECT_EQ(i + 10, report_.logs(i).timestamp());
   }
 }
 
@@ -173,9 +173,9 @@
 
   log_->Serialize(&report_);
   VerifyHeader(true /* incomplete */);
-  ASSERT_EQ(kLogCapacity, report_.log_size());
+  ASSERT_EQ(kLogCapacity, report_.logs_size());
   for (int i = 0; i < kLogCapacity; ++i) {
-    EXPECT_EQ(i + 1, report_.log(i).timestamp());
+    EXPECT_EQ(i + 1, report_.logs(i).timestamp());
   }
 
   log_->ClearSerialized();
@@ -185,7 +185,7 @@
   report_.Clear();
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  EXPECT_EQ(0, report_.log_size());
+  EXPECT_EQ(0, report_.logs_size());
 }
 
 // Add more entries than the log has capacity for. Serialize the log. Add one
@@ -215,8 +215,8 @@
   report_.Clear();
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(1, report_.log_size());
-  EXPECT_EQ(kLogCapacity + 1, report_.log(0).timestamp());
+  ASSERT_EQ(1, report_.logs_size());
+  EXPECT_EQ(kLogCapacity + 1, report_.logs(0).timestamp());
 }
 
 // Add more entries than the log has capacity for. Serialize the log. Add
@@ -249,9 +249,9 @@
   report_.Clear();
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(kLogCapacity, report_.log_size());
+  ASSERT_EQ(kLogCapacity, report_.logs_size());
   for (int i = 0; i < kLogCapacity; ++i) {
-    EXPECT_EQ(i + kLogCapacity, report_.log(i).timestamp());
+    EXPECT_EQ(i + kLogCapacity, report_.logs(i).timestamp());
   }
 }
 
@@ -285,9 +285,9 @@
   report_.Clear();
   log_->Serialize(&report_);
   VerifyHeader(true /* incomplete */);
-  ASSERT_EQ(kLogCapacity, report_.log_size());
+  ASSERT_EQ(kLogCapacity, report_.logs_size());
   for (int i = 0; i < kLogCapacity; ++i) {
-    EXPECT_EQ(i + kLogCapacity + 1, report_.log(i).timestamp());
+    EXPECT_EQ(i + kLogCapacity + 1, report_.logs(i).timestamp());
   }
 }
 
@@ -318,8 +318,8 @@
 
   log_->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(1, report_.log_size());
-  EXPECT_EQ(0, report_.log(0).timestamp());
+  ASSERT_EQ(1, report_.logs_size());
+  EXPECT_EQ(0, report_.logs(0).timestamp());
 }
 
 // Store an empty log. Load the log. Verify that that the log contents are
@@ -339,7 +339,7 @@
 
   log->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(0, report_.log_size());
+  ASSERT_EQ(0, report_.logs_size());
 }
 
 // Populate and store a log. Load the log. Verify that that the log contents are
@@ -366,9 +366,9 @@
 
   log->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(10, report_.log_size());
+  ASSERT_EQ(10, report_.logs_size());
   for (int i = 0; i < 10; ++i) {
-    EXPECT_EQ(i, report_.log(i).timestamp());
+    EXPECT_EQ(i, report_.logs(i).timestamp());
   }
 }
 
@@ -429,9 +429,9 @@
   report_.Clear();
   log->Serialize(&report_);
   VerifyHeader(false /* incomplete */);
-  ASSERT_EQ(10, report_.log_size());
+  ASSERT_EQ(10, report_.logs_size());
   for (int i = 0; i < 10; ++i) {
-    EXPECT_EQ(i, report_.log(i).timestamp());
+    EXPECT_EQ(i, report_.logs(i).timestamp());
   }
 }
 
@@ -471,9 +471,9 @@
   report_.Clear();
   log->Serialize(&report_);
   VerifyHeader(true /* incomplete */);
-  ASSERT_EQ(10, report_.log_size());
+  ASSERT_EQ(10, report_.logs_size());
   for (int i = 0; i < 10; ++i) {
-    EXPECT_EQ(i, report_.log(i).timestamp());
+    EXPECT_EQ(i, report_.logs(i).timestamp());
   }
 }
 
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
index 5542314..ae938436 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
@@ -103,7 +103,7 @@
 
 // TODO(agawronska): Remove test instantiation with kDMServerOAuthForChildUser
 // once it is enabled by default.
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
     UserCloudPolicyManagerTest,
     testing::Values(std::vector<base::Feature>(),
@@ -141,7 +141,6 @@
     EXPECT_EQ(GURL(kStartupURLs[i]),
               tabs->GetWebContentsAt(i)->GetVisibleURL());
   }
-  EXPECT_TRUE(user_manager->GetActiveUser()->profile_ever_initialized());
 
   // User should be marked as requiring policy.
   EXPECT_EQ(user_manager::known_user::ProfileRequiresPolicy::kPolicyRequired,
@@ -169,10 +168,6 @@
   // Should not receive a SESSION_STARTED notification.
   ASSERT_EQ(0, observer.notification_count());
 
-  // User should not be marked as having completed profile initialization.
-  const user_manager::UserManager* user_manager =
-      user_manager::UserManager::Get();
-  EXPECT_FALSE(user_manager->GetActiveUser()->profile_ever_initialized());
   // User should be marked as not knowing if policy is required yet.
   AccountId account_id =
       AccountId::FromUserEmailGaiaId(kAccountId, kTestGaiaId);
@@ -201,56 +196,11 @@
   EXPECT_EQ(user_manager::User::OAUTH2_TOKEN_STATUS_VALID,
             user_manager->GetActiveUser()->oauth_token_status());
 
-  // User should be marked as having completed profile initialization.
-  EXPECT_TRUE(user_manager->GetActiveUser()->profile_ever_initialized());
-
   // User should still be marked as not needing policy
   EXPECT_EQ(user_manager::known_user::ProfileRequiresPolicy::kNoPolicyRequired,
             user_manager::known_user::GetProfileRequiresPolicy(account_id));
 }
 
-IN_PROC_BROWSER_TEST_P(UserCloudPolicyManagerTest,
-                       PolicyCheckRequiredForInitializedProfile) {
-  // Mark user as already having initialized the profile - this should not
-  // change how the policy code treats unknown policy.
-  // the policy code to ignore errors (because we presume we already have a
-  // valid cache). We can remove this test when we fix crbug.com/731726 and
-  // remove the associated migration code from UserPolicyManagerFactoryChromeOS.
-  AccountId account_id =
-      AccountId::FromUserEmailGaiaId(kAccountId, kTestGaiaId);
-  chromeos::ChromeUserManager* user_manager =
-      chromeos::ChromeUserManager::Get();
-  user_manager::User* user =
-      user_manager::User::CreateRegularUserForTesting(account_id);
-  user->set_profile_ever_initialized(true);
-  user_manager->AddUserRecordForTesting(user);
-
-  EXPECT_EQ(user_manager::known_user::ProfileRequiresPolicy::kUnknown,
-            user_manager::known_user::GetProfileRequiresPolicy(account_id));
-
-  user_manager::known_user::SetProfileEverInitialized(account_id, true);
-  EXPECT_TRUE(user_manager::known_user::WasProfileEverInitialized(account_id));
-
-  // Delete the policy file - this will cause a 500 error on policy requests.
-  user_policy_helper()->DeletePolicyFile();
-  SkipToLoginScreen();
-  CountNotificationObserver observer(
-      chrome::NOTIFICATION_SESSION_STARTED,
-      content::NotificationService::AllSources());
-  chromeos::LoginDisplayHost::default_host()
-      ->GetOobeUI()
-      ->GetGaiaScreenView()
-      ->ShowSigninScreenForTest(kAccountId, kAccountPassword, kEmptyServices);
-  RunUntilBrowserProcessQuits();
-  // Should not receive a SESSION_STARTED notification.
-  ASSERT_EQ(0, observer.notification_count());
-
-  // Policy status should still be unknown since we haven't managed to load
-  // policy from disk nor have we been able to talk to the server.
-  EXPECT_EQ(user_manager::known_user::ProfileRequiresPolicy::kUnknown,
-            user_manager::known_user::GetProfileRequiresPolicy(account_id));
-}
-
 class UserCloudPolicyManagerNonEnterpriseTest
     : public UserCloudPolicyManagerTest {
  protected:
@@ -278,7 +228,7 @@
 
 // TODO(agawronska): Remove test instantiation with kDMServerOAuthForChildUser
 // once it is enabled by default.
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
     UserCloudPolicyManagerNonEnterpriseTest,
     testing::Values(std::vector<base::Feature>(),
@@ -305,8 +255,6 @@
   EXPECT_EQ(user_manager::User::OAUTH2_TOKEN_STATUS_VALID,
             user_manager->GetActiveUser()->oauth_token_status());
 
-  EXPECT_TRUE(user_manager->GetActiveUser()->profile_ever_initialized());
-
   // User should be marked as not requiring policy.
   EXPECT_EQ(user_manager::known_user::ProfileRequiresPolicy::kNoPolicyRequired,
             user_manager::known_user::GetProfileRequiresPolicy(account_id));
@@ -329,7 +277,7 @@
 
 // TODO(agawronska): Remove test instantiation with kDMServerOAuthForChildUser
 // once it is enabled by default.
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
     UserCloudPolicyManagerChildTest,
     testing::Values(
@@ -357,8 +305,6 @@
   EXPECT_EQ(user_manager::User::OAUTH2_TOKEN_STATUS_VALID,
             user_manager->GetActiveUser()->oauth_token_status());
 
-  EXPECT_TRUE(user_manager->GetActiveUser()->profile_ever_initialized());
-
   // User of CHILD type should be marked as requiring policy.
   EXPECT_EQ(user_manager::known_user::ProfileRequiresPolicy::kPolicyRequired,
             user_manager::known_user::GetProfileRequiresPolicy(account_id));
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
index fe04fd47..991335d 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
@@ -194,7 +194,7 @@
     policy_data_.set_device_id("id987");
     policy_data_.set_username("user@example.com");
     em::PolicyFetchResponse* policy_response =
-        policy_blob_.mutable_policy_response()->add_response();
+        policy_blob_.mutable_policy_response()->add_responses();
     ASSERT_TRUE(policy_data_.SerializeToString(
         policy_response->mutable_policy_data()));
 
diff --git a/chrome/browser/chromeos/policy/user_network_configuration_updater.cc b/chrome/browser/chromeos/policy/user_network_configuration_updater.cc
index 26653ad6..82bb1b4 100644
--- a/chrome/browser/chromeos/policy/user_network_configuration_updater.cc
+++ b/chrome/browser/chromeos/policy/user_network_configuration_updater.cc
@@ -30,8 +30,10 @@
 
 UserNetworkConfigurationUpdater::~UserNetworkConfigurationUpdater() {
   // NetworkCertLoader may be not initialized in tests.
-  if (chromeos::NetworkCertLoader::IsInitialized())
-    chromeos::NetworkCertLoader::Get()->RemovePolicyCertificateProvider(this);
+  if (chromeos::NetworkCertLoader::IsInitialized()) {
+    chromeos::NetworkCertLoader::Get()->SetUserPolicyCertificateProvider(
+        nullptr);
+  }
 }
 
 // static
@@ -84,7 +86,7 @@
   // only created for the primary profile. NetworkCertLoader may be not
   // initialized in tests.
   if (chromeos::NetworkCertLoader::IsInitialized())
-    chromeos::NetworkCertLoader::Get()->AddPolicyCertificateProvider(this);
+    chromeos::NetworkCertLoader::Get()->SetUserPolicyCertificateProvider(this);
 }
 
 void UserNetworkConfigurationUpdater::ImportClientCertificates() {
diff --git a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc
index 1e68bb9..434f9f7 100644
--- a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc
+++ b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc
@@ -122,10 +122,7 @@
   }
 
   // chromeos::NetworkCertLoader::Observer
-  void OnCertificatesLoaded(
-      const net::ScopedCERTCertificateList& all_certs) override {
-    run_loop_.Quit();
-  }
+  void OnCertificatesLoaded() override { run_loop_.Quit(); }
 
   void Wait() { run_loop_.Run(); }
 
@@ -336,10 +333,11 @@
   return cert_found;
 }
 
-bool IsCertInCertificateList(const net::X509Certificate* cert,
-                             const net::ScopedCERTCertificateList& cert_list) {
-  for (const auto& cert_list_element : cert_list) {
-    if (net::x509_util::IsSameCertificate(cert_list_element.get(), cert))
+bool IsCertInCertificateList(
+    const net::X509Certificate* cert,
+    const chromeos::NetworkCertLoader::NetworkCertList& network_cert_list) {
+  for (const auto& network_cert : network_cert_list) {
+    if (net::x509_util::IsSameCertificate(network_cert.cert(), cert))
       return true;
   }
   return false;
@@ -408,9 +406,9 @@
   ASSERT_TRUE(chromeos::NetworkCertLoader::IsInitialized());
   chromeos::NetworkCertLoader::Get()->SetUserNSSDB(test_nss_cert_db_.get());
 
-  EXPECT_FALSE(
-      IsCertInCertificateList(user_policy_certs_helper_.root_cert().get(),
-                              chromeos::NetworkCertLoader::Get()->all_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(
+      user_policy_certs_helper_.root_cert().get(),
+      chromeos::NetworkCertLoader::Get()->authority_certs()));
   NetworkCertLoaderTestObserver network_cert_loader_observer(
       chromeos::NetworkCertLoader::Get());
   user_policy_certs_helper_.SetRootCertONCUserPolicy(browser()->profile());
@@ -419,9 +417,9 @@
   // Check that |NetworkCertLoader| is aware of the authority certificate.
   // (Web Trust does not matter for the NetworkCertLoader, but we currently only
   // set a policy with a certificate requesting Web Trust here).
-  EXPECT_TRUE(
-      IsCertInCertificateList(user_policy_certs_helper_.root_cert().get(),
-                              chromeos::NetworkCertLoader::Get()->all_certs()));
+  EXPECT_TRUE(IsCertInCertificateList(
+      user_policy_certs_helper_.root_cert().get(),
+      chromeos::NetworkCertLoader::Get()->authority_certs()));
 }
 
 // Base class for testing policy-provided trust roots with device-local
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc b/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
index ec44b30..3b0b2275 100644
--- a/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
@@ -54,21 +54,16 @@
   MOCK_METHOD1(OnRefreshTokenAvailable, void(const std::string&));
 };
 
-MockOAuth2TokenServiceObserver::MockOAuth2TokenServiceObserver() {
-}
+MockOAuth2TokenServiceObserver::MockOAuth2TokenServiceObserver() {}
 
-MockOAuth2TokenServiceObserver::~MockOAuth2TokenServiceObserver() {
-}
+MockOAuth2TokenServiceObserver::~MockOAuth2TokenServiceObserver() {}
 
 }  // namespace
 
 class DeviceOAuth2TokenServiceTest : public testing::Test {
  public:
   DeviceOAuth2TokenServiceTest()
-      : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()),
-        test_shared_loader_factory_(
-            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-                &test_url_loader_factory_)) {}
+      : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
 
   // Most tests just want a noop crypto impl with a dummy refresh token value in
   // Local State (if the value is an empty string, it will be ignored).
@@ -97,8 +92,7 @@
 
   std::unique_ptr<OAuth2TokenService::Request> StartTokenRequest() {
     return oauth2_service_->StartRequest(oauth2_service_->GetRobotAccountId(),
-                                         std::set<std::string>(),
-                                         &consumer_);
+                                         std::set<std::string>(), &consumer_);
   }
 
   void SetUp() override {
@@ -121,7 +115,6 @@
 
   void TearDown() override {
     oauth2_service_.reset();
-    test_shared_loader_factory_->Detach();
     base::TaskScheduler::GetInstance()->FlushForTesting();
     DeviceSettingsService::Get()->UnsetSessionManager();
     SystemSaltGetter::Shutdown();
@@ -131,7 +124,8 @@
 
   void CreateService() {
     auto delegate = std::make_unique<DeviceOAuth2TokenServiceDelegate>(
-        test_shared_loader_factory_, scoped_testing_local_state_.Get());
+        test_url_loader_factory_.GetSafeWeakWrapper(),
+        scoped_testing_local_state_.Get());
     delegate->max_refresh_token_validation_retries_ = 0;
     oauth2_service_.reset(new DeviceOAuth2TokenService(std::move(delegate)));
     oauth2_service_->set_max_authorization_token_fetch_retries_for_testing(0);
@@ -196,9 +190,7 @@
   // base::DefaultDeleter therefore doesn't work. However, the test class is
   // declared friend in DeviceOAuth2TokenService, so this deleter works.
   struct TokenServiceDeleter {
-    inline void operator()(DeviceOAuth2TokenService* ptr) const {
-      delete ptr;
-    }
+    inline void operator()(DeviceOAuth2TokenService* ptr) const { delete ptr; }
   };
 
   content::TestBrowserThreadBundle test_browser_thread_bundle_;
@@ -208,8 +200,6 @@
   ScopedTestCrosSettings scoped_test_cros_settings_{
       scoped_testing_local_state_.Get()};
   network::TestURLLoaderFactory test_url_loader_factory_;
-  scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
-      test_shared_loader_factory_;
   FakeCryptohomeClient* fake_cryptohome_client_;
   FakeSessionManagerClient session_manager_client_;
   policy::DevicePolicyBuilder device_policy_;
diff --git a/chrome/browser/client_hints/client_hints.cc b/chrome/browser/client_hints/client_hints.cc
index e8c72703f6..a72ae92 100644
--- a/chrome/browser/client_hints/client_hints.cc
+++ b/chrome/browser/client_hints/client_hints.cc
@@ -17,9 +17,9 @@
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/client_hints/client_hints.h"
-#include "chrome/common/pref_names.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings_utils.h"
+#include "components/language/core/browser/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
@@ -375,7 +375,7 @@
         blink::kClientHintsHeaderMapping[static_cast<int>(
             blink::mojom::WebClientHintsType::kLang)],
         blink::SerializeLangClientHint(
-            profile->GetPrefs()->GetString(prefs::kAcceptLanguages)));
+            profile->GetPrefs()->GetString(language::prefs::kAcceptLanguages)));
   }
 
   // Static assert that triggers if a new client hint header is added. If a
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc
index bbf83a3..991260f 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.cc
+++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -573,8 +573,11 @@
 
 bool ChromeDownloadManagerDelegate::InterceptDownloadIfApplicable(
     const GURL& url,
+    const std::string& user_agent,
+    const std::string& content_disposition,
     const std::string& mime_type,
     const std::string& request_origin,
+    int64_t content_length,
     content::WebContents* web_contents) {
   return false;
 }
diff --git a/chrome/browser/download/chrome_download_manager_delegate.h b/chrome/browser/download/chrome_download_manager_delegate.h
index 5399d88d..9568e41a 100644
--- a/chrome/browser/download/chrome_download_manager_delegate.h
+++ b/chrome/browser/download/chrome_download_manager_delegate.h
@@ -93,8 +93,11 @@
       const content::DownloadOpenDelayedCallback& callback) override;
   bool InterceptDownloadIfApplicable(
       const GURL& url,
+      const std::string& user_agent,
+      const std::string& content_disposition,
       const std::string& mime_type,
       const std::string& request_origin,
+      int64_t content_length,
       content::WebContents* web_contents) override;
   bool GenerateFileHash() override;
   void GetSaveDir(content::BrowserContext* browser_context,
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
index 0dfad1b..23d4a382 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
@@ -59,8 +59,6 @@
 #include "extensions/browser/notification_types.h"
 #include "extensions/common/switches.h"
 #include "extensions/common/value_builder.h"
-#include "net/test/cert_test_util.h"
-#include "net/test/test_data_directory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
@@ -155,7 +153,8 @@
 
 class TestListener : public content::NotificationObserver {
  public:
-  TestListener(const std::string& message, const base::Closure& callback)
+  TestListener(const std::string& message,
+               const base::RepeatingClosure& callback)
       : message_(message), callback_(callback) {
     registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE,
                    content::NotificationService::AllSources());
@@ -172,7 +171,7 @@
 
  private:
   std::string message_;
-  base::Closure callback_;
+  base::RepeatingClosure callback_;
 
   content::NotificationRegistrar registrar_;
 
@@ -493,22 +492,6 @@
     return std::make_unique<TestNetworkingCastPrivateDelegate>();
   }
 
-  bool SetupCertificates() {
-    base::ScopedAllowBlockingForTesting allow_io;
-    net::ScopedCERTCertificateList cert_list =
-        net::CreateCERTCertificateListFromFile(
-            net::GetTestCertsDirectory(), "client_1_ca.pem",
-            net::X509Certificate::FORMAT_AUTO);
-    if (cert_list.empty())
-      return false;
-    // TODO(stevenjb): Figure out a simple way to import a test user cert.
-
-    chromeos::NetworkHandler::Get()
-        ->network_certificate_handler()
-        ->SetCertificatesForTest(cert_list);
-    return true;
-  }
-
  protected:
   NetworkPortalDetectorTestImpl* detector() { return detector_; }
 
@@ -820,11 +803,12 @@
 
 IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest,
                        OnCertificateListsChangedEvent) {
-  TestListener listener("eventListenerReady", base::Bind([]() {
-                          chromeos::NetworkHandler::Get()
-                              ->network_certificate_handler()
-                              ->NotifyCertificatsChangedForTest();
-                        }));
+  TestListener listener(
+      "eventListenerReady", base::BindRepeating([]() {
+        chromeos::NetworkHandler::Get()
+            ->network_certificate_handler()
+            ->AddAuthorityCertificateForTest("authority_cert");
+      }));
   EXPECT_TRUE(RunNetworkingSubtest("onCertificateListsChangedEvent"))
       << message_;
 }
@@ -969,7 +953,9 @@
 }
 
 IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, GetCertificateLists) {
-  ASSERT_TRUE(SetupCertificates());
+  chromeos::NetworkHandler::Get()
+      ->network_certificate_handler()
+      ->AddAuthorityCertificateForTest("authority_cert");
   EXPECT_TRUE(RunNetworkingSubtest("getCertificateLists")) << message_;
 }
 
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
index 92337c0..5a173d4 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -294,7 +294,7 @@
 
 void TabsEventRouter::OnDiscardedStateChange(
     WebContents* contents,
-    mojom::LifecycleUnitDiscardReason reason,
+    ::mojom::LifecycleUnitDiscardReason reason,
     bool is_discarded) {
   std::set<std::string> changed_property_names;
   changed_property_names.insert(tabs_constants::kDiscardedKey);
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.h b/chrome/browser/extensions/api/tabs/tabs_event_router.h
index 3fb45ae2..14f37b6f 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.h
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.h
@@ -79,7 +79,7 @@
 
   // resource_coordinator::TabLifecycleObserver:
   void OnDiscardedStateChange(content::WebContents* contents,
-                              mojom::LifecycleUnitDiscardReason reason,
+                              ::mojom::LifecycleUnitDiscardReason reason,
                               bool is_discarded) override;
   void OnAutoDiscardableStateChange(content::WebContents* contents,
                                     bool is_auto_discardable) override;
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc
index 16eb061..1769669 100644
--- a/chrome/browser/extensions/content_script_apitest.cc
+++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -969,10 +969,10 @@
   ASSERT_TRUE(RunExtensionTest("content_scripts/messaging")) << message_;
 }
 
-INSTANTIATE_TEST_CASE_P(,
-                        ContentScriptMessagingApiTest,
-                        testing::Values(BindingsType::kNative,
-                                        BindingsType::kJavaScript));
+INSTANTIATE_TEST_SUITE_P(,
+                         ContentScriptMessagingApiTest,
+                         testing::Values(BindingsType::kNative,
+                                         BindingsType::kJavaScript));
 
 // Test fixture which sets a custom NTP Page.
 // TODO(karandeepb): Similar logic to set up a custom NTP is used elsewhere as
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 7a82a43..70327da 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1873,6 +1873,11 @@
     "expiry_milestone": 76
   },
   {
+    "name": "enable-text-fragment-anchor",
+    "owners": [ "bokan", "input-dev" ],
+    "expiry_milestone": 77
+  },
+  {
     "name": "enable-touch-drag-drop",
     "owners": [ "eirage", "input-dev" ],
     "expiry_milestone": 78
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 2625953..02af9e4 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -928,6 +928,10 @@
     "Enables the new, experimental implementation of session sync (aka tab "
     "sync).";
 
+const char kEnableTextFragmentAnchorName[] = "Enable Text Fragment Anchor.";
+const char kEnableTextFragmentAnchorDescription[] =
+    "Enables scrolling to text specified in URL's fragment.";
+
 const char kEnableUseZoomForDsfName[] =
     "Use Blink's zoom for device scale factor.";
 const char kEnableUseZoomForDsfDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 985fde6..0cb2c42 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -555,6 +555,9 @@
 extern const char kEnableSyncUSSSessionsName[];
 extern const char kEnableSyncUSSSessionsDescription[];
 
+extern const char kEnableTextFragmentAnchorName[];
+extern const char kEnableTextFragmentAnchorDescription[];
+
 extern const char kEnableUseZoomForDsfName[];
 extern const char kEnableUseZoomForDsfDescription[];
 extern const char kEnableUseZoomForDsfChoiceDefault[];
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc
index 21761f6..bfb5d5e 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/base64.h"
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/command_line.h"
@@ -93,6 +94,7 @@
 #include "content/public/browser/histogram_fetcher.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/notification_service.h"
+#include "google_apis/google_api_keys.h"
 #include "ppapi/buildflags/buildflags.h"
 #include "printing/buildflags/buildflags.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -1091,3 +1093,9 @@
 #endif
   return std::string();
 }
+
+std::string ChromeMetricsServiceClient::GetUploadSigningKey() {
+  std::string decoded_key;
+  base::Base64Decode(google_apis::GetMetricsKey(), &decoded_key);
+  return decoded_key;
+}
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.h b/chrome/browser/metrics/chrome_metrics_service_client.h
index cdaf5c90..56b9eff 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.h
+++ b/chrome/browser/metrics/chrome_metrics_service_client.h
@@ -88,6 +88,7 @@
   bool SyncStateAllowsExtensionUkm() override;
   bool AreNotificationListenersEnabledOnAllProfiles() override;
   std::string GetAppPackageName() override;
+  std::string GetUploadSigningKey() override;
   static void SetNotificationListenerSetupFailedForTesting(
       bool simulate_failure);
 
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc
index d3f49c2..a660d9b8 100644
--- a/chrome/browser/metrics/ukm_browsertest.cc
+++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -337,6 +337,16 @@
                                {});
   }
 
+  void SetUpInProcessBrowserTestFixture() override {
+    // This is required to support (fake) secondary-account-signin (based on
+    // cookies) in tests. Without this, the real GaiaCookieManagerService would
+    // try talking to Google servers which of course wouldn't work in tests.
+    test_gaia_cookie_manager_factory_ =
+        secondary_account_helper::SetUpGaiaCookieManagerService(
+            &test_url_loader_factory_);
+    UkmBrowserTest::SetUpInProcessBrowserTestFixture();
+  }
+
   void SetUpOnMainThread() override {
 #if defined(OS_CHROMEOS)
     secondary_account_helper::InitNetwork();
@@ -347,6 +357,9 @@
  private:
   base::test::ScopedFeatureList features_;
 
+  secondary_account_helper::ScopedGaiaCookieManagerServiceFactory
+      test_gaia_cookie_manager_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(UkmBrowserTestWithSyncTransport);
 };
 
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac.mm b/chrome/browser/notifications/notification_platform_bridge_mac.mm
index 38097df..b2c65a3b 100644
--- a/chrome/browser/notifications/notification_platform_bridge_mac.mm
+++ b/chrome/browser/notifications/notification_platform_bridge_mac.mm
@@ -462,7 +462,7 @@
 - (void)userNotificationCenter:(NSUserNotificationCenter*)center
        didActivateNotification:(NSUserNotification*)notification {
   NSDictionary* notificationResponse =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
   NotificationPlatformBridgeMac::ProcessNotificationResponse(
       notificationResponse);
 }
@@ -476,11 +476,25 @@
 - (void)userNotificationCenter:(NSUserNotificationCenter*)center
                didDismissAlert:(NSUserNotification*)notification {
   NSDictionary* notificationResponse =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildDismissedDictionary:notification];
   NotificationPlatformBridgeMac::ProcessNotificationResponse(
       notificationResponse);
 }
 
+// Overriden from _NSUserNotificationCenterDelegatePrivate.
+// Emitted when a user closes a notification from the notification center.
+// This is an undocumented method introduced in 10.8 according to
+// https://bugzilla.mozilla.org/show_bug.cgi?id=852648#c21
+- (void)userNotificationCenter:(NSUserNotificationCenter*)center
+    didRemoveDeliveredNotifications:(NSArray*)notifications {
+  for (NSUserNotification* notification in notifications) {
+    NSDictionary* notificationResponse =
+        [NotificationResponseBuilder buildDismissedDictionary:notification];
+    NotificationPlatformBridgeMac::ProcessNotificationResponse(
+        notificationResponse);
+  }
+}
+
 - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center
      shouldPresentNotification:(NSUserNotification*)nsNotification {
   // Always display notifications, regardless of whether the app is foreground.
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac_unittest.mm b/chrome/browser/notifications/notification_platform_bridge_mac_unittest.mm
index bda17840..7d9a9f4 100644
--- a/chrome/browser/notifications/notification_platform_bridge_mac_unittest.mm
+++ b/chrome/browser/notifications/notification_platform_bridge_mac_unittest.mm
@@ -127,8 +127,9 @@
 
   NSMutableDictionary* BuildDefaultNotificationResponse() {
     return [NSMutableDictionary
-        dictionaryWithDictionary:[NotificationResponseBuilder
-                                     buildDictionary:BuildNotification()]];
+        dictionaryWithDictionary:
+            [NotificationResponseBuilder
+                buildActivatedDictionary:BuildNotification()]];
   }
 
   NSUserNotificationCenter* notification_center() {
diff --git a/chrome/browser/policy/cloud/device_management_service_browsertest.cc b/chrome/browser/policy/cloud/device_management_service_browsertest.cc
index ea48555..4fdb04d 100644
--- a/chrome/browser/policy/cloud/device_management_service_browsertest.cc
+++ b/chrome/browser/policy/cloud/device_management_service_browsertest.cc
@@ -57,7 +57,7 @@
   } else if (request.has_unregister_request()) {
     response.mutable_unregister_response();
   } else if (request.has_policy_request()) {
-    response.mutable_policy_response()->add_response();
+    response.mutable_policy_response()->add_responses();
   } else if (request.has_auto_enrollment_request()) {
     response.mutable_auto_enrollment_response();
   } else if (request.has_app_install_report_request()) {
@@ -189,7 +189,7 @@
   job->SetClientID("testid");
   em::DeviceServiceApiAccessRequest* request =
       job->GetRequest()->mutable_service_api_access_request();
-  request->add_auth_scope("authScope4Test");
+  request->add_auth_scopes("authScope4Test");
   request->set_oauth2_client_id("oauth2ClientId4Test");
   job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
                         base::Unretained(this)));
@@ -209,7 +209,7 @@
   job->SetClientID("testid");
   em::DevicePolicyRequest* request =
       job->GetRequest()->mutable_policy_request();
-  request->add_request()->set_policy_type(dm_protocol::kChromeUserPolicyType);
+  request->add_requests()->set_policy_type(dm_protocol::kChromeUserPolicyType);
   job->Start(base::Bind(&DeviceManagementServiceIntegrationTest::OnJobDone,
                         base::Unretained(this)));
   run_loop.Run();
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
index 42c13d9b..7a86f0c4 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -336,7 +336,7 @@
     em::PolicyData policy_data;
     policy_data.set_policy_type(dm_protocol::kChromeUserPolicyType);
     em::PolicyFetchResponse* policy_response =
-        policy_blob.mutable_policy_response()->add_response();
+        policy_blob.mutable_policy_response()->add_responses();
     ASSERT_TRUE(
         policy_data.SerializeToString(policy_response->mutable_policy_data()));
     fetch_request->SendResponse(DM_STATUS_SUCCESS, policy_blob);
diff --git a/chrome/browser/policy/policy_conversions.cc b/chrome/browser/policy/policy_conversions.cc
index 007dc90..5603480b 100644
--- a/chrome/browser/policy/policy_conversions.cc
+++ b/chrome/browser/policy/policy_conversions.cc
@@ -129,6 +129,60 @@
   return known_policy_iterator->second;
 }
 
+// Create a description of the policy |policy_name| using |policy| and the
+// optional errors in |errors| to determine the status of each policy. If
+// |convert_values| is true, converts the values to show them in javascript.
+// |known_policy_schemas| contains |Schema|s for known policies in the same
+// policy namespace of |map|. A policy without an entry in
+// |known_policy_schemas| is an unknown policy.
+Value GetPolicyValue(
+    const std::string& policy_name,
+    const policy::PolicyMap::Entry& policy,
+    policy::PolicyErrorMap* errors,
+    bool convert_values,
+    const base::Optional<PolicyToSchemaMap>& known_policy_schemas) {
+  base::Optional<policy::Schema> known_policy_schema =
+      GetKnownPolicySchema(known_policy_schemas, policy_name);
+  Value value(Value::Type::DICTIONARY);
+  value.SetKey("value", CopyAndMaybeConvert(*policy.value, convert_values,
+                                            known_policy_schema));
+  value.SetKey(
+      "scope",
+      Value((policy.scope == policy::POLICY_SCOPE_USER) ? "user" : "machine"));
+  value.SetKey("level", Value((policy.level == policy::POLICY_LEVEL_RECOMMENDED)
+                                  ? "recommended"
+                                  : "mandatory"));
+  value.SetKey("source", Value(kPolicySources[policy.source].key));
+  base::string16 error;
+  if (!known_policy_schema.has_value()) {
+    // We don't know what this policy is. This is an important error to
+    // show.
+    error = l10n_util::GetStringUTF16(IDS_POLICY_UNKNOWN);
+  } else {
+    // The PolicyMap contains errors about retrieving the policy, while the
+    // PolicyErrorMap contains validation errors. Give priority to PolicyMap.
+    error = policy.GetLocalizedErrors(
+        base::BindRepeating(&l10n_util::GetStringUTF16));
+    if (error.empty())
+      error = errors->GetErrors(policy_name);
+  }
+  if (!error.empty())
+    value.SetKey("error", Value(error));
+
+  if (!policy.conflicts.empty()) {
+    Value conflict_values(Value::Type::LIST);
+    for (const auto& conflict : policy.conflicts) {
+      base::Value conflicted_policy_value = GetPolicyValue(
+          policy_name, conflict, errors, convert_values, known_policy_schemas);
+      conflict_values.GetList().push_back(std::move(conflicted_policy_value));
+    }
+
+    value.SetKey("conflicts", std::move(conflict_values));
+  }
+
+  return value;
+}
+
 // Inserts a description of each policy in |map| into |values|, using the
 // optional errors in |errors| to determine the status of each policy. If
 // |convert_values| is true, converts the values to show them in javascript.
@@ -148,35 +202,8 @@
     const PolicyMap::Entry& policy = entry.second;
     if (policy.scope == policy::POLICY_SCOPE_USER && !with_user_policies)
       continue;
-
-    base::Optional<policy::Schema> known_policy_schema =
-        GetKnownPolicySchema(known_policy_schemas, policy_name);
-    Value value(Value::Type::DICTIONARY);
-    value.SetKey("value", CopyAndMaybeConvert(*policy.value, convert_values,
-                                              known_policy_schema));
-    value.SetKey("scope", Value((policy.scope == policy::POLICY_SCOPE_USER)
-                                    ? "user"
-                                    : "machine"));
-    value.SetKey("level",
-                 Value((policy.level == policy::POLICY_LEVEL_RECOMMENDED)
-                           ? "recommended"
-                           : "mandatory"));
-    value.SetKey("source", Value(kPolicySources[policy.source].key));
-    base::string16 error;
-    if (!known_policy_schema.has_value()) {
-      // We don't know what this policy is. This is an important error to
-      // show.
-      error = l10n_util::GetStringUTF16(IDS_POLICY_UNKNOWN);
-    } else {
-      // The PolicyMap contains errors about retrieving the policy, while the
-      // PolicyErrorMap contains validation errors. Give priority to PolicyMap.
-      error = policy.GetLocalizedErrors(
-          base::BindRepeating(&l10n_util::GetStringUTF16));
-      if (error.empty())
-        error = errors->GetErrors(policy_name);
-    }
-    if (!error.empty())
-      value.SetKey("error", Value(error));
+    base::Value value = GetPolicyValue(policy_name, policy, errors,
+                                       convert_values, known_policy_schemas);
     values->SetKey(policy_name, std::move(value));
   }
 }
diff --git a/chrome/browser/policy/test/policy_testserver.py b/chrome/browser/policy/test/policy_testserver.py
index b3c8128..24360a3 100644
--- a/chrome/browser/policy/test/policy_testserver.py
+++ b/chrome/browser/policy/test/policy_testserver.py
@@ -574,9 +574,9 @@
       return error
 
     key_update_request = msg.device_state_key_update_request
-    if len(key_update_request.server_backed_state_key) > 0:
+    if len(key_update_request.server_backed_state_keys) > 0:
       self.server.UpdateStateKeys(token_info['device_token'],
-                                  key_update_request.server_backed_state_key)
+                                  key_update_request.server_backed_state_keys)
 
     # See whether the |username| for the client is known. During policy
     # validation, the client verifies that the policy blob is bound to the
@@ -590,12 +590,12 @@
     # If this is a |publicaccount| request, use the |settings_entity_id| from
     # the request as the |username|. This is required to validate policy for
     # extensions in device-local accounts.
-    for request in msg.policy_request.request:
+    for request in msg.policy_request.requests:
       if request.policy_type == 'google/chromeos/publicaccount':
         username = request.settings_entity_id
 
     response = dm.DeviceManagementResponse()
-    for request in msg.policy_request.request:
+    for request in msg.policy_request.requests:
       if (request.policy_type in
              ('google/android/user',
               'google/chromeos/device',
@@ -603,7 +603,7 @@
               'google/chromeos/user',
               'google/chrome/user',
               'google/chrome/machine-level-user')):
-        fetch_response = response.policy_response.response.add()
+        fetch_response = response.policy_response.responses.add()
         self.ProcessCloudPolicy(request, token_info, fetch_response, username)
       elif (request.policy_type in
              ('google/chrome/extension',
@@ -640,7 +640,7 @@
     auto_enrollment_response = dm.DeviceAutoEnrollmentResponse()
 
     if msg.modulus == 1:
-      auto_enrollment_response.hash.extend(
+      auto_enrollment_response.hashes.extend(
           self.server.GetMatchingStateKeyHashes(msg.modulus, msg.remainder))
     elif msg.modulus == 2:
       auto_enrollment_response.expected_modulus = 4
@@ -739,7 +739,7 @@
       available_licenses = policy['available_licenses']
       selection_mode = dm.CheckDeviceLicenseResponse.USER_SELECTION
       for license_type in available_licenses:
-        license = license_response.license_availability.add()
+        license = license_response.license_availabilities.add()
         license.license_type.license_type = LICENSE_TYPES[license_type]
         license.available_licenses = available_licenses[license_type]
     license_response.license_selection_mode = (selection_mode)
@@ -999,7 +999,7 @@
       # Reuse the extension policy request, to trigger the same signature
       # type in the response.
       request.settings_entity_id = settings_entity_id
-      fetch_response = response.response.add()
+      fetch_response = response.responses.add()
       self.ProcessCloudPolicy(request, token_info, fetch_response, username)
       # Don't do key rotations for these messages.
       fetch_response.ClearField('new_public_key')
diff --git a/chrome/browser/printing/cloud_print/privet_local_printer_lister_unittest.cc b/chrome/browser/printing/cloud_print/privet_local_printer_lister_unittest.cc
index 4c967f0d..ec884a040 100644
--- a/chrome/browser/printing/cloud_print/privet_local_printer_lister_unittest.cc
+++ b/chrome/browser/printing/cloud_print/privet_local_printer_lister_unittest.cc
@@ -22,9 +22,9 @@
 
 using local_discovery::TestServiceDiscoveryClient;
 
-using testing::StrictMock;
-using testing::AtLeast;
 using testing::_;
+using testing::AtLeast;
+using testing::StrictMock;
 
 namespace cloud_print {
 
@@ -81,12 +81,14 @@
     0x03, 0x04,
 };
 
-const char kInfoIsLocalPrinter[] = "{"
+const char kInfoIsLocalPrinter[] =
+    "{"
     "\"api\" : [ \"/privet/printer/submitdoc\" ],"
     "\"x-privet-token\" : \"sample\""
     "}";
 
-const char kInfoIsNotLocalPrinter[] = "{"
+const char kInfoIsNotLocalPrinter[] =
+    "{"
     "\"api\" : [ \"/privet/register\" ],"
     "\"x-privet-token\" : \"sample\""
     "}";
@@ -116,20 +118,14 @@
   PrivetLocalPrinterListerTest()
       : test_service_discovery_client_(
             base::MakeRefCounted<TestServiceDiscoveryClient>()),
-        test_shared_url_loader_factory_(
-            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-                &test_url_loader_factory_)),
-        http_asynchronous_factory_impl_(test_shared_url_loader_factory_) {
+        http_asynchronous_factory_impl_(
+            test_url_loader_factory_.GetSafeWeakWrapper()) {
     local_printer_lister_ = std::make_unique<PrivetLocalPrinterLister>(
-        test_service_discovery_client_.get(), test_shared_url_loader_factory_,
-        &delegate_);
+        test_service_discovery_client_.get(),
+        test_url_loader_factory_.GetSafeWeakWrapper(), &delegate_);
     test_service_discovery_client_->Start();
   }
 
-  ~PrivetLocalPrinterListerTest() override {
-    test_shared_url_loader_factory_->Detach();
-  }
-
   void SimulateReceive(const uint8_t* packet, size_t size) {
     test_service_discovery_client_->SimulateReceive(packet, size);
     base::RunLoop().RunUntilIdle();
@@ -146,8 +142,6 @@
   std::unique_ptr<PrivetLocalPrinterLister> local_printer_lister_;
   StrictMock<MockLocalPrinterListerDelegate> delegate_;
   network::TestURLLoaderFactory test_url_loader_factory_;
-  scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
-      test_shared_url_loader_factory_;
   cloud_print::PrivetHTTPAsynchronousFactoryImpl
       http_asynchronous_factory_impl_;
 };
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc
index 137a2370..9035338 100644
--- a/chrome/browser/profiles/profile_browsertest.cc
+++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -346,13 +346,6 @@
         temp_dir.GetPath(), &delegate, Profile::CREATE_MODE_SYNCHRONOUS));
     CheckChromeVersion(profile.get(), true);
 
-#if defined(OS_CHROMEOS)
-    // Make sure session is marked as initialized.
-    user_manager::User* user =
-        chromeos::ProfileHelper::Get()->GetUserByProfile(profile.get());
-    EXPECT_TRUE(user->profile_ever_initialized());
-#endif
-
     // Creating a profile causes an implicit connection attempt to a Mojo
     // service, which occurs as part of a new task. Before deleting |profile|,
     // ensure this task runs to prevent a crash.
@@ -410,12 +403,6 @@
     // Wait for the profile to be created.
     observer.Wait();
     CheckChromeVersion(profile.get(), true);
-#if defined(OS_CHROMEOS)
-    // Make sure session is marked as initialized.
-    user_manager::User* user =
-        chromeos::ProfileHelper::Get()->GetUserByProfile(profile.get());
-    EXPECT_TRUE(user->profile_ever_initialized());
-#endif
   }
 
   FlushIoTaskRunnerAndSpinThreads();
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index db1989f..dcbbb455 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -689,17 +689,6 @@
   dom_distiller::RegisterViewerSource(this);
 
 #if defined(OS_CHROMEOS)
-  // Finished profile initialization - let the UserManager know so it can
-  // mark the session as initialized. Need to do this before we restart below
-  // so we don't get in a weird state where we restart before the session is
-  // marked as initialized and so try to initialize it again.
-  if (!chromeos::ProfileHelper::IsSigninProfile(this) &&
-      !chromeos::ProfileHelper::IsLockScreenAppProfile(this)) {
-    chromeos::ProfileHelper* profile_helper = chromeos::ProfileHelper::Get();
-    user_manager::UserManager::Get()->OnProfileInitialized(
-        profile_helper->GetUserByProfile(this));
-  }
-
   MigrateSigninScopedDeviceId(this);
 
   if (chromeos::UserSessionManager::GetInstance()
diff --git a/chrome/browser/resources/chromeos/camera/.eslintrc.js b/chrome/browser/resources/chromeos/camera/.eslintrc.js
new file mode 100644
index 0000000..1172dbf7
--- /dev/null
+++ b/chrome/browser/resources/chromeos/camera/.eslintrc.js
@@ -0,0 +1,171 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+const googleRules = {
+  'no-cond-assign': 0,
+  'no-irregular-whitespace': 2,
+  'no-unexpected-multiline': 2,
+  'valid-jsdoc': [
+    2,
+    {
+      requireParamDescription: false,
+      requireReturnDescription: false,
+      requireReturn: false,
+      prefer: {returns: 'return'},
+    },
+  ],
+  'curly': [2, 'multi-line'],
+  'guard-for-in': 2,
+  'no-caller': 2,
+  'no-extend-native': 2,
+  'no-extra-bind': 2,
+  'no-invalid-this': 2,
+  'no-multi-spaces': 2,
+  'no-multi-str': 2,
+  'no-new-wrappers': 2,
+  'no-throw-literal': 2,
+  'no-with': 2,
+  'prefer-promise-reject-errors': 2,
+  'no-unused-vars': [2, {args: 'none'}],
+  'array-bracket-newline': 0,
+  'array-bracket-spacing': [2, 'never'],
+  'array-element-newline': 0,
+  'block-spacing': [2, 'never'],
+  'brace-style': 2,
+  'camelcase': [2, {properties: 'never'}],
+  'comma-dangle': [2, 'always-multiline'],
+  'comma-spacing': 2,
+  'comma-style': 2,
+  'computed-property-spacing': 2,
+  'eol-last': 2,
+  'func-call-spacing': 2,
+  'indent': [
+    'error',
+    2,
+    {
+      'CallExpression': {
+        'arguments': 2,
+      },
+      'FunctionDeclaration': {
+        'body': 1,
+        'parameters': 2,
+      },
+      'FunctionExpression': {
+        'body': 1,
+        'parameters': 2,
+      },
+      'MemberExpression': 2,
+      'ObjectExpression': 1,
+      'SwitchCase': 1,
+      'ignoredNodes': [
+        'ConditionalExpression',
+      ],
+    },
+  ],
+  'key-spacing': 2,
+  'keyword-spacing': 2,
+  'linebreak-style': 2,
+  'max-len': [
+    2,
+    {
+      code: 80,
+      tabWidth: 2,
+      ignoreUrls: true,
+      ignorePattern: '^goog.(module|require)',
+    },
+  ],
+  'new-cap': 2,
+  'no-array-constructor': 2,
+  'no-mixed-spaces-and-tabs': 2,
+  'no-multiple-empty-lines': [2, {max: 2}],
+  'no-new-object': 2,
+  'no-tabs': 2,
+  'no-trailing-spaces': 2,
+  'object-curly-spacing': 2,
+  'one-var': [
+    2,
+    {
+      // Quote the keys to make clang-format format it correctly.
+      'var': 'never',
+      'let': 'never',
+      'const': 'never',
+    },
+  ],
+  'padded-blocks': [2, 'never'],
+  'quote-props': [2, 'consistent'],
+  'quotes': [2, 'single', {allowTemplateLiterals: true}],
+  'require-jsdoc': [
+    2,
+    {
+      require: {
+        FunctionDeclaration: true,
+        MethodDefinition: true,
+        ClassDeclaration: true,
+      },
+    },
+  ],
+  'semi': 2,
+  'semi-spacing': 2,
+  'space-before-blocks': 2,
+  'space-before-function-paren': [
+    2,
+    {
+      asyncArrow: 'always',
+      anonymous: 'never',
+      named: 'never',
+    },
+  ],
+  'spaced-comment': [2, 'always'],
+
+  // It's not available yet in the bundled eslint version in Chrome.
+  // 'switch-colon-spacing': 2,
+
+  'arrow-parens': [2, 'always'],
+  'constructor-super': 2,
+  'generator-star-spacing': [2, 'after'],
+  'no-new-symbol': 2,
+  'no-this-before-super': 2,
+  'no-var': 2,
+  'prefer-const': ['error', {destructuring: 'all'}],
+  'prefer-rest-params': 2,
+  'prefer-spread': 2,
+  'rest-spread-spacing': 2,
+  'yield-star-spacing': [2, 'after'],
+};
+
+/* global module */
+module.exports = {
+  'root': true,
+  'env': {
+    'browser': true,
+    'es6': true,
+    'webextensions': true,
+  },
+  'parserOptions': {
+    'ecmaVersion': 2017,
+  },
+  'extends': 'eslint:recommended',
+  'globals': {
+    'ImageCapture': 'readable',
+    'webkitRequestFileSystem': 'readable',
+  },
+  'rules': Object.assign({}, googleRules, {
+    'curly': [2, 'multi-line', 'consistent'],
+    'no-console': [2, {allow: ['warn', 'error']}],
+
+    // We are using 2 spaces before trailing line comments. The option
+    // |ignoreEOLComments| is not supported yet in the bundled eslint.
+    'no-multi-spaces': 0,
+
+    // TODO(shik): temporarily disable the rules we violate (b/117810572).
+    'indent': 0,                        // 5 errors
+    'valid-jsdoc': 0,                   // 1 error
+    'max-len': 0,                       // 2 errors
+    'no-redeclare': 0,                  // 5 errors
+    'no-var': 0,                        // 273 errors
+    'prefer-rest-params': 0,            // 3 errors
+    'prefer-const': 0,                  // 17 errors
+    'prefer-promise-reject-errors': 0,  // 1 error
+  }),
+};
diff --git a/chrome/browser/resources/chromeos/camera/Makefile b/chrome/browser/resources/chromeos/camera/Makefile
index 8e511a7..9e357b1 100644
--- a/chrome/browser/resources/chromeos/camera/Makefile
+++ b/chrome/browser/resources/chromeos/camera/Makefile
@@ -117,6 +117,7 @@
 	src/js/nav.js \
 	src/js/scrollbar.js \
 	src/js/sound.js \
+	src/js/state.js \
 	src/js/toast.js \
 	src/js/tooltip.js \
 	src/js/util.js \
diff --git a/chrome/browser/resources/chromeos/camera/src/js/main.js b/chrome/browser/resources/chromeos/camera/src/js/main.js
index 36457946..043b6b4 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/main.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/main.js
@@ -58,8 +58,7 @@
  * @return {boolean} Whether applicable or not.
  */
 cca.App.useGalleryApp = function() {
-  return chrome.fileManagerPrivate &&
-      document.body.classList.contains('ext-fs');
+  return chrome.fileManagerPrivate && cca.state.get('ext-fs');
 };
 
 /**
@@ -90,7 +89,7 @@
     element.addEventListener('keypress', (event) =>
         cca.util.getShortcutIdentifier(event) == 'Enter' && element.click());
 
-    var css = element.getAttribute('data-css');
+    var css = element.getAttribute('data-state');
     var key = element.getAttribute('data-key');
     var payload = () => {
       var keys = {};
@@ -99,7 +98,7 @@
     };
     element.addEventListener('change', (event) => {
       if (css) {
-        document.body.classList.toggle(css, element.checked);
+        cca.state.set(css, element.checked);
       }
       if (event.isTrusted) {
         element.save();
@@ -139,7 +138,7 @@
       }
     });
   }).then((external) => {
-    document.body.classList.toggle('ext-fs', external);
+    cca.state.set('ext-fs', external);
     this.model_.addObserver(this.galleryButton_);
     if (!cca.App.useGalleryApp()) {
       this.model_.addObserver(this.browserView_);
diff --git a/chrome/browser/resources/chromeos/camera/src/js/nav.js b/chrome/browser/resources/chromeos/camera/src/js/nav.js
index 1984c536..bbe928c9 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/nav.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/nav.js
@@ -69,7 +69,7 @@
  * @private
  */
 cca.nav.isShown_ = function(index) {
-  return document.body.classList.contains(cca.nav.views_[index].root.id);
+  return cca.state.get(cca.nav.views_[index].root.id);
 };
 
 /**
@@ -82,7 +82,7 @@
 cca.nav.show_ = function(index) {
   var view = cca.nav.views_[index];
   if (!cca.nav.isShown_(index)) {
-    document.body.classList.add(view.root.id);
+    cca.state.set(view.root.id, true);
     view.layout();
     if (index > cca.nav.topmostIndex_) {
       if (cca.nav.topmostIndex_ >= 0) {
@@ -110,7 +110,7 @@
     }
     cca.nav.topmostIndex_ = next;
   }
-  document.body.classList.remove(cca.nav.views_[index].root.id);
+  cca.state.set(cca.nav.views_[index].root.id, false);
 };
 
 /**
diff --git a/chrome/browser/resources/chromeos/camera/src/js/state.js b/chrome/browser/resources/chromeos/camera/src/js/state.js
new file mode 100644
index 0000000..a9c67d7
--- /dev/null
+++ b/chrome/browser/resources/chromeos/camera/src/js/state.js
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+/**
+ * Namespace for the Camera app.
+ */
+var cca = cca || {};
+
+/**
+ * Namespace for the app state.
+ */
+cca.state = cca.state || {};
+
+/**
+ * Checks if the specified state exists.
+ * @param {string} state State to be checked.
+ * @return {boolean} Whether the state exists.
+ */
+cca.state.get = function(state) {
+  return document.body.classList.contains(state);
+};
+
+/**
+ * Sets the specified state on or off.
+ * @param {string} state State to be set.
+ * @param {boolean} val True to set the state on, false otherwise.
+ */
+cca.state.set = function(state, val) {
+  document.body.classList.toggle(state, val);
+};
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
index 9b4a3cd..78eff316 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
@@ -145,14 +145,8 @@
 
 cca.views.Camera.prototype = {
   __proto__: cca.views.View.prototype,
-  get streaming() {
-    return document.body.classList.contains('streaming');
-  },
-  get taking() {
-    return document.body.classList.contains('taking');
-  },
   get recordMode() {
-    return document.body.classList.contains('record-mode');
+    return cca.state.get('record-mode');
   },
 };
 
@@ -169,10 +163,10 @@
  * @private
  */
 cca.views.Camera.prototype.onShutterButtonClicked_ = function(event) {
-  if (!this.streaming) {
+  if (!cca.state.get('streaming')) {
     return;
   }
-  if (this.taking) {
+  if (cca.state.get('taking')) {
     // End the prior ongoing take if any; a new take shouldn't be started
     // until the prior one is ended.
     this.endTake_();
@@ -199,9 +193,10 @@
 cca.views.Camera.prototype.updateShutterLabel_ = function() {
   var label;
   if (this.recordMode) {
-    label = this.taking ? 'record_video_stop_button' : 'record_video_start_button';
+    label = cca.state.get('taking') ?
+        'record_video_stop_button' : 'record_video_start_button';
   } else {
-    label = (this.taking && document.body.classList.contains('timer')) ?
+    label = (cca.state.get('taking') && cca.state.get('timer')) ?
         'take_photo_cancel_button' : 'take_photo_button';
   }
   this.shutterButton_.setAttribute('aria-label', chrome.i18n.getMessage(label));
@@ -230,7 +225,7 @@
  * @private
  */
 cca.views.Camera.prototype.beginTake_ = function() {
-  document.body.classList.add('taking');
+  cca.state.set('taking', true);
   this.updateShutterLabel_();
 
   cca.views.camera.timertick.start().then(() => {
@@ -285,7 +280,7 @@
   }).catch(console.error).finally(() => {
     // Re-enable UI controls after finishing the take.
     this.take_ = null;
-    document.body.classList.remove('taking');
+    cca.state.set('taking', false);
     this.updateShutterLabel_();
   });
 };
@@ -331,7 +326,7 @@
     };
     enableAudio(true);
     this.mediaRecorder_.start();
-    enableAudio(document.body.classList.contains('mic'));
+    enableAudio(cca.state.get('mic'));
     this.recordTime_.start();
   });
 };
@@ -441,7 +436,7 @@
   // Wait for ongoing 'start' and 'take' done before restarting camera.
   return Promise.all([
     this.started_,
-    Promise.resolve(!this.taking || this.endTake_()),
+    Promise.resolve(!cca.state.get('taking') || this.endTake_()),
   ]).finally(() => {
     this.preview_.stop();
     this.mediaRecorder_ = null;
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/layout.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/layout.js
index cafc67b..843b263 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/layout.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/layout.js
@@ -106,10 +106,10 @@
  * Updates the layout for video-size or window-size changes.
  */
 cca.views.camera.Layout.prototype.update = function() {
-  // TODO(yuli): Check if the app runs on a tablet display.
+  // TODO(yuli): Replace tablet-landscape with full-wnd/vert-orien.
   var fullWindow = cca.util.isWindowFullSize();
   var tabletLandscape = fullWindow && (window.innerWidth > window.innerHeight);
-  document.body.classList.toggle('tablet-landscape', tabletLandscape);
+  cca.state.set('tablet-landscape', tabletLandscape);
 
   var [letterboxW, letterboxH] = this.updatePreviewSize_();
   var [halfW, halfH] = [letterboxW / 2, letterboxH / 2];
@@ -128,11 +128,11 @@
     var [, leastShutter] = dimens(true);
     return (measure > leastShutter) && (measure < leastShutter * 2);
   };
-  if (document.body.classList.toggle('shift-preview-left',
+  if (cca.state.set('shift-preview-left',
       fullWindow && tabletLandscape && accommodate(letterboxW))) {
     [rightBox, leftBox] = [letterboxW, 0];
   }
-  if (document.body.classList.toggle('shift-preview-top',
+  if (cca.state.set('shift-preview-top',
       fullWindow && !tabletLandscape && accommodate(letterboxH))) {
     [bottomBox, topBox] = [letterboxH, 0];
   }
@@ -146,7 +146,7 @@
   };
   var shift = (stripe, name, measure, shutter) => {
     var [preset, least, gap, baseline] = dimens(shutter);
-    if (document.body.classList.toggle('shift-' + name + '-stripe',
+    if (cca.state.set('shift-' + name + '-stripe',
         measure > gap && measure < preset)) {
       baseline = calc(measure, least);
       stripe.setProperty(name, baseline + 'px');
@@ -156,7 +156,7 @@
   };
   var symm = (stripe, name, measure, shutterBaseline) => {
     if (measure && shutterBaseline) {
-      document.body.classList.add('shift-' + name + '-stripe');
+      cca.state.set('shift-' + name + '-stripe', true);
       stripe.setProperty(name, shutterBaseline + 'px');
       return true;
     }
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
index fc6c8bd2..edfd383b 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/options.js
@@ -106,8 +106,7 @@
 
 cca.views.camera.Options.prototype = {
   get newStreamRequestDisabled() {
-    return !document.body.classList.contains('streaming') ||
-        document.body.classList.contains('taking');
+    return !cca.state.get('streaming') || cca.state.get('taking');
   },
 };
 
@@ -120,10 +119,9 @@
   if (this.newStreamRequestDisabled) {
     return;
   }
-  document.body.classList.toggle('record-mode', record);
-  document.body.classList.add('mode-switching');
-  this.onNewStreamNeeded_().then(
-      () => document.body.classList.remove('mode-switching'));
+  cca.state.set('record-mode', record);
+  cca.state.set('mode-switching', true);
+  this.onNewStreamNeeded_().then(() => cca.state.set('mode-switching', false));
 };
 
 /**
@@ -258,7 +256,7 @@
   this.videoDevices_.then((devices) => {
     multi = devices.length >= 2;
   }).catch(console.error).finally(() => {
-    document.body.classList.toggle('multi-camera', multi);
+    cca.state.set('multi-camera', multi);
     this.refreshingVideoDeviceIds_ = false;
   });
 };
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/preview.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/preview.js
index 60f4a38..e64a103 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/preview.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/preview.js
@@ -146,7 +146,7 @@
       }
     }, 100);
     this.stream_ = stream;
-    document.body.classList.add('streaming');
+    cca.state.set('streaming', true);
   });
 };
 
@@ -164,7 +164,7 @@
     this.stream_.getVideoTracks()[0].stop();
     this.stream_ = null;
   }
-  document.body.classList.remove('streaming');
+  cca.state.set('streaming', false);
 };
 
 /**
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/timertick.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/timertick.js
index 250d0e9..74db9a7 100644
--- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/timertick.js
+++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/timertick.js
@@ -36,7 +36,7 @@
  */
 cca.views.camera.timertick.start = function() {
   cca.views.camera.timertick.cancel_ = null;
-  if (!document.body.classList.contains('timer')) {
+  if (!cca.state.get('timer')) {
     return Promise.resolve();
   }
   return new Promise((resolve, reject) => {
@@ -51,7 +51,7 @@
       reject();
     };
 
-    var tickCounter = document.body.classList.contains('_10sec') ? 10 : 3;
+    var tickCounter = cca.state.get('_10sec') ? 10 : 3;
     var onTimerTick = () => {
       if (tickCounter == 0) {
         resolve();
diff --git a/chrome/browser/resources/chromeos/camera/src/views/main.html b/chrome/browser/resources/chromeos/camera/src/views/main.html
index c32e9dee..f902321a 100644
--- a/chrome/browser/resources/chromeos/camera/src/views/main.html
+++ b/chrome/browser/resources/chromeos/camera/src/views/main.html
@@ -12,6 +12,7 @@
     <script src="../js/util.js"></script>
     <script src="../js/toast.js"></script>
     <script src="../js/tooltip.js"></script>
+    <script src="../js/state.js"></script>
     <script src="../js/sound.js"></script>
     <script src="../js/scrollbar.js"></script>
     <script src="../js/gallerybutton.js"></script>
@@ -56,8 +57,8 @@
       </div>
       <div class="top-stripe right-stripe buttons">
         <input type="checkbox" id="toggle-mic" tabindex="0"
-               i18n-label="toggle_mic_button" data-css="mic" data-key="toggleMic"
-               checked>
+               i18n-label="toggle_mic_button" data-state="mic"
+               data-key="toggleMic" checked>
       </div>
       <div class="top-stripe left-stripe buttons">
         <button id="open-settings" tabindex="0"
@@ -65,12 +66,12 @@
       </div>
       <div class="left-stripe options-group buttons">
         <input type="checkbox" id="toggle-mirror" tabindex="0"
-               i18n-label="toggle_mirror_button" data-css="mirror" checked>
+               i18n-label="toggle_mirror_button" data-state="mirror" checked>
         <input type="checkbox" id="toggle-grid" tabindex="0"
-               i18n-label="toggle_grid_button" data-css="grid"
+               i18n-label="toggle_grid_button" data-state="grid"
                data-key="toggleGrid">
         <input type="checkbox" id="toggle-timer" tabindex="0"
-               i18n-label="toggle_timer_button" data-css="timer"
+               i18n-label="toggle_timer_button" data-state="timer"
                data-key="toggleTimer">
       </div>
       <div class="bottom-stripe left-stripe buttons circle">
@@ -139,17 +140,17 @@
         </div>
         <label class="menu-item circle" for="grid-3x3">
           <input class="icon" id="grid-3x3" type="radio" tabindex="0"
-                 name="gridtype" data-css="_3x3" data-key="toggle3x3" checked>
+                 name="gridtype" data-state="_3x3" data-key="toggle3x3" checked>
           <span i18n-content="label_grid_3x3" i18n-aria="aria_grid_3x3"></span>
         </label>
         <label class="menu-item circle" for="grid-4x4">
           <input class="icon" id="grid-4x4" type="radio" tabindex="0"
-                 name="gridtype" data-css="_4x4" data-key="toggle4x4">
+                 name="gridtype" data-state="_4x4" data-key="toggle4x4">
           <span i18n-content="label_grid_4x4" i18n-aria="aria_grid_4x4"></span>
         </label>
         <label class="menu-item circle" for="grid-golden">
           <input class="icon" id="grid-golden" type="radio" tabindex="0"
-                 name="gridtype" data-css="golden" data-key="toggleGolden">
+                 name="gridtype" data-state="golden" data-key="toggleGolden">
           <span i18n-content="label_grid_golden"></span>
         </label>
       </div>
@@ -162,12 +163,13 @@
         </div>
         <label class="menu-item circle" for="timer-3s">
           <input class="icon" id="timer-3s" type="radio" tabindex="0"
-                 name="timerdur" data-css="_3sec" data-key="toggle3sec" checked>
+                 name="timerdur" data-state="_3sec" data-key="toggle3sec"
+                 checked>
           <span i18n-content="label_timer_3s"></span>
         </label>
         <label class="menu-item circle" for="timer-10s">
           <input class="icon" id="timer-10s" type="radio" tabindex="0"
-                 name="timerdur" data-css="_10sec" data-key="toggle10sec">
+                 name="timerdur" data-state="_10sec" data-key="toggle10sec">
           <span i18n-content="label_timer_10s"></span>
         </label>
       </div>
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js
index 7f2ced07..c1c84aa2 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.js
+++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -272,6 +272,8 @@
       if (this.unifiedConsentEnabled && this.syncStatus &&
           !!this.syncStatus.setupInProgress && this.didAbort_ &&
           !this.setupCancelConfirmed_) {
+        chrome.metricsPrivate.recordUserAction(
+            'Signin_Signin_BackOnAdvancedSyncSettings');
         // Yield so that other |currentRouteChanged| observers are called,
         // before triggering another navigation (and another round of observers
         // firing). Triggering navigation from within an observer leads to some
diff --git a/chrome/browser/safe_browsing/advanced_protection_status_manager.cc b/chrome/browser/safe_browsing/advanced_protection_status_manager.cc
index 0bce90c..17bb8779 100644
--- a/chrome/browser/safe_browsing/advanced_protection_status_manager.cc
+++ b/chrome/browser/safe_browsing/advanced_protection_status_manager.cc
@@ -245,7 +245,7 @@
 }
 
 bool AdvancedProtectionStatusManager::IsPrimaryAccount(
-    const AccountInfo& account_info) {
+    const CoreAccountInfo& account_info) {
   return !account_info.account_id.empty() &&
          account_info.account_id == GetPrimaryAccountId();
 }
diff --git a/chrome/browser/safe_browsing/advanced_protection_status_manager.h b/chrome/browser/safe_browsing/advanced_protection_status_manager.h
index cb61211..aeaeda3 100644
--- a/chrome/browser/safe_browsing/advanced_protection_status_manager.h
+++ b/chrome/browser/safe_browsing/advanced_protection_status_manager.h
@@ -107,7 +107,7 @@
   // Sets |last_refresh_| to now and persists it.
   void UpdateLastRefreshTime();
 
-  bool IsPrimaryAccount(const AccountInfo& account_info);
+  bool IsPrimaryAccount(const CoreAccountInfo& account_info);
 
   // Decodes |id_token| to get advanced protection status.
   void OnGetIDToken(const std::string& account_id, const std::string& id_token);
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
index 1645dff7..d4930b8 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
@@ -106,11 +106,12 @@
     // Ensure that the stub user is signed in.
 #if defined(OS_CHROMEOS)
     // On ChromeOS, the stub user is signed in by default on browsertests.
-    AccountInfo account_info =
+    CoreAccountInfo account_info =
         identity_test_env()->identity_manager()->GetPrimaryAccountInfo();
 #else
-    AccountInfo account_info = identity_test_env()->MakePrimaryAccountAvailable(
-        user_manager::kStubUserEmail);
+    CoreAccountInfo account_info =
+        identity_test_env()->MakePrimaryAccountAvailable(
+            user_manager::kStubUserEmail);
 #endif
     ASSERT_EQ(account_info.email, user_manager::kStubUserEmail);
 
diff --git a/chrome/browser/sessions/better_session_restore_browsertest.cc b/chrome/browser/sessions/better_session_restore_browsertest.cc
index bb00b86..095c989 100644
--- a/chrome/browser/sessions/better_session_restore_browsertest.cc
+++ b/chrome/browser/sessions/better_session_restore_browsertest.cc
@@ -528,14 +528,8 @@
 
 #if BUILDFLAG(ENABLE_BACKGROUND_MODE)
 
-// Flaky on Windows and Linux: https://crbug.com/931778.
-#if defined(OS_WIN) || defined(OS_LINUX)
-#define MAYBE_CookiesClearedOnBrowserClose DISABLED_CookiesClearedOnBrowserClose
-#else
-#define MAYBE_CookiesClearedOnBrowserClose CookiesClearedOnBrowserClose
-#endif
 IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
-                       MAYBE_CookiesClearedOnBrowserClose) {
+                       CookiesClearedOnBrowserClose) {
   StoreDataWithPage("cookies.html");
   // Normally cookies are restored.
   Browser* new_browser = QuitBrowserAndRestore(browser(), false);
diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc
index 3670587..bfa14cd 100644
--- a/chrome/browser/sessions/session_data_deleter.cc
+++ b/chrome/browser/sessions/session_data_deleter.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/dom_storage_context.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/storage_usage_info.h"
 #include "net/cookies/cookie_util.h"
@@ -26,6 +25,11 @@
 
 namespace {
 
+bool OriginMatcher(const GURL& origin, storage::SpecialStoragePolicy* policy) {
+  return policy->IsStorageSessionOnly(origin) &&
+         !policy->IsStorageProtected(origin);
+}
+
 class SessionDataDeleter
     : public base::RefCountedThreadSafe<SessionDataDeleter> {
  public:
@@ -38,12 +42,6 @@
   friend class base::RefCountedThreadSafe<SessionDataDeleter>;
   ~SessionDataDeleter();
 
-  // Deletes the local storage described by |usages| for origins which are
-  // session-only.
-  void ClearSessionOnlyLocalStorage(
-      content::StoragePartition* storage_partition,
-      const std::vector<content::StorageUsageInfo>& usages);
-
   // Takes the result of a CookieManager::GetAllCookies() method, and
   // initiates deletion of all cookies that are session only by the
   // storage policy of the constructor.
@@ -66,10 +64,16 @@
 
 void SessionDataDeleter::Run(content::StoragePartition* storage_partition) {
   if (storage_policy_.get() && storage_policy_->HasSessionOnlyOrigins()) {
-    storage_partition->GetDOMStorageContext()->GetLocalStorageUsage(
-        base::Bind(&SessionDataDeleter::ClearSessionOnlyLocalStorage,
-                   this,
-                   storage_partition));
+    // Cookies are not origin scoped, so they are handled separately.
+    const uint32_t removal_mask =
+        content::StoragePartition::REMOVE_DATA_MASK_ALL &
+        ~content::StoragePartition::REMOVE_DATA_MASK_COOKIES;
+    storage_partition->ClearData(
+        removal_mask, content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL,
+        base::BindRepeating(&OriginMatcher),
+        /*cookie_deletion_filter=*/nullptr,
+        /*perform_storage_cleanup=*/false, base::Time(), base::Time::Max(),
+        base::DoNothing());
   }
 
   storage_partition->GetNetworkContext()->GetCookieManager(
@@ -120,20 +124,6 @@
 
 SessionDataDeleter::~SessionDataDeleter() {}
 
-void SessionDataDeleter::ClearSessionOnlyLocalStorage(
-    content::StoragePartition* storage_partition,
-    const std::vector<content::StorageUsageInfo>& usages) {
-  DCHECK(storage_policy_.get());
-  DCHECK(storage_policy_->HasSessionOnlyOrigins());
-  for (size_t i = 0; i < usages.size(); ++i) {
-    const content::StorageUsageInfo& usage = usages[i];
-    if (!storage_policy_->IsStorageSessionOnly(usage.origin.GetURL()))
-      continue;
-    storage_partition->GetDOMStorageContext()->DeleteLocalStorage(
-        usage.origin, base::DoNothing());
-  }
-}
-
 }  // namespace
 
 void DeleteSessionOnlyData(Profile* profile) {
diff --git a/chrome/browser/shell_integration_mac.mm b/chrome/browser/shell_integration_mac.mm
index 7d0b430..972263575 100644
--- a/chrome/browser/shell_integration_mac.mm
+++ b/chrome/browser/shell_integration_mac.mm
@@ -7,6 +7,7 @@
 #include "base/mac/bundle_locations.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/mac_util.h"
+#include "base/mac/scoped_cftyperef.h"
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/common/channel_info.h"
 #include "components/version_info/version_info.h"
@@ -34,17 +35,15 @@
 // application for the given protocol.
 bool IsIdentifierDefaultProtocolClient(NSString* identifier,
                                        NSString* protocol) {
-  CFStringRef default_client_cf =
-      LSCopyDefaultHandlerForURLScheme(base::mac::NSToCFCast(protocol));
-  NSString* default_client = static_cast<NSString*>(
-      base::mac::CFTypeRefToNSObjectAutorelease(default_client_cf));
+  base::ScopedCFTypeRef<CFStringRef> default_client(
+      LSCopyDefaultHandlerForURLScheme(base::mac::NSToCFCast(protocol)));
   if (!default_client)
     return false;
 
   // We need to ensure we do the comparison case-insensitive as LS doesn't
   // persist the case of our bundle id.
   NSComparisonResult result =
-      [default_client caseInsensitiveCompare:identifier];
+      [base::mac::CFToNSCast(default_client) caseInsensitiveCompare:identifier];
   return result == NSOrderedSame;
 }
 
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 6cc275d..7243922 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -6127,6 +6127,10 @@
 // pattern matching.
 using SSLUICaptivePortalListTest = SSLUITest;
 
+INSTANTIATE_TEST_CASE_P(,
+                        SSLUICaptivePortalListTest,
+                        ::testing::Values(false, true));
+
 std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig>
 MakeCaptivePortalConfig(int version_id,
                         const std::set<std::string>& spki_hashes) {
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service_unittest.cc b/chrome/browser/supervised_user/child_accounts/child_account_service_unittest.cc
index 2f5b233c..14305fb 100644
--- a/chrome/browser/supervised_user/child_accounts/child_account_service_unittest.cc
+++ b/chrome/browser/supervised_user/child_accounts/child_account_service_unittest.cc
@@ -6,14 +6,16 @@
 
 #include "base/bind.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
-#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
-#include "chrome/browser/signin/gaia_cookie_manager_service_test_util.h"
+#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/supervised_user/child_accounts/child_account_service_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/signin/core/browser/list_accounts_test_utils.h"
 #include "components/signin/core/browser/test_signin_client.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
+#include "services/identity/public/cpp/accounts_cookie_mutator.h"
+#include "services/identity/public/cpp/identity_manager.h"
+#include "services/identity/public/cpp/identity_test_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -32,27 +34,36 @@
     TestingProfile::Builder builder;
     builder.AddTestingFactory(ChromeSigninClientFactory::GetInstance(),
                               base::BindRepeating(&BuildTestSigninClient));
-    builder.AddTestingFactory(
-        GaiaCookieManagerServiceFactory::GetInstance(),
-        base::BindRepeating(&BuildGaiaCookieManagerServiceWithURLLoader,
-                            &test_url_loader_factory_));
-    profile_ = builder.Build();
-    gaia_cookie_manager_service_ =
-        GaiaCookieManagerServiceFactory::GetForProfile(profile_.get());
+    profile_ = IdentityTestEnvironmentProfileAdaptor::
+        CreateProfileForIdentityTestEnvironment(builder);
   }
 
  protected:
+  network::TestURLLoaderFactory* GetTestURLLoaderFactory() {
+    auto* signin_client =
+        ChromeSigninClientFactory::GetForProfile(profile_.get());
+    return static_cast<TestSigninClient*>(signin_client)
+        ->test_url_loader_factory();
+  }
+
+  identity::AccountsCookieMutator* GetAccountsCookieMutator() {
+    IdentityTestEnvironmentProfileAdaptor identity_test_env_profile_adaptor(
+        profile_.get());
+    return identity_test_env_profile_adaptor.identity_test_env()
+        ->identity_manager()
+        ->GetAccountsCookieMutator();
+  }
+
   content::TestBrowserThreadBundle thread_bundle_;
 
-  // test_url_loader_factory_ is declared before profile_ to guarantee that the
-  // former outlives the latter.
-  network::TestURLLoaderFactory test_url_loader_factory_;
   std::unique_ptr<TestingProfile> profile_;
-  GaiaCookieManagerService* gaia_cookie_manager_service_;
 };
 
 TEST_F(ChildAccountServiceTest, GetGoogleAuthState) {
-  signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
+  auto* accounts_cookie_mutator = GetAccountsCookieMutator();
+  auto* test_url_loader_factory = GetTestURLLoaderFactory();
+
+  signin::SetListAccountsResponseNoAccounts(test_url_loader_factory);
 
   ChildAccountService* child_account_service =
       ChildAccountServiceFactory::GetForProfile(profile_.get());
@@ -74,8 +85,8 @@
        /* valid = */ true,
        /* is_signed_out = */ false,
        /* verified = */ true},
-      &test_url_loader_factory_);
-  gaia_cookie_manager_service_->TriggerListAccounts();
+      test_url_loader_factory);
+  accounts_cookie_mutator->TriggerCookieJarUpdate();
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(ChildAccountService::AuthState::AUTHENTICATED,
             child_account_service->GetGoogleAuthState());
@@ -86,8 +97,8 @@
        /* valid = */ false,
        /* is_signed_out = */ false,
        /* verified = */ true},
-      &test_url_loader_factory_);
-  gaia_cookie_manager_service_->TriggerListAccounts();
+      test_url_loader_factory);
+  accounts_cookie_mutator->TriggerCookieJarUpdate();
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(ChildAccountService::AuthState::NOT_AUTHENTICATED,
             child_account_service->GetGoogleAuthState());
@@ -98,8 +109,8 @@
        /* valid = */ true,
        /* is_signed_out = */ true,
        /* verified = */ true},
-      &test_url_loader_factory_);
-  gaia_cookie_manager_service_->TriggerListAccounts();
+      test_url_loader_factory);
+  accounts_cookie_mutator->TriggerCookieJarUpdate();
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(ChildAccountService::AuthState::NOT_AUTHENTICATED,
             child_account_service->GetGoogleAuthState());
diff --git a/chrome/browser/sync/test/integration/secondary_account_helper.cc b/chrome/browser/sync/test/integration/secondary_account_helper.cc
index 4a52cbc..89e998c 100644
--- a/chrome/browser/sync/test/integration/secondary_account_helper.cc
+++ b/chrome/browser/sync/test/integration/secondary_account_helper.cc
@@ -6,16 +6,13 @@
 
 #include "base/bind.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/chrome_signin_client.h"
-#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
+#include "chrome/browser/signin/gaia_cookie_manager_service_test_util.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "content/public/browser/storage_partition.h"
 #include "services/identity/public/cpp/identity_manager.h"
 #include "services/identity/public/cpp/identity_test_utils.h"
 #include "services/identity/public/cpp/primary_account_mutator.h"
-#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
-#include "services/network/test/test_url_loader_factory.h"
 
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
@@ -29,27 +26,17 @@
 
 namespace {
 
-std::unique_ptr<KeyedService> BuildSigninClientWithURLLoader(
-    network::TestURLLoaderFactory* test_url_loader_factory,
-    content::BrowserContext* context) {
-  Profile* profile = Profile::FromBrowserContext(context);
-  auto signin_client = std::make_unique<ChromeSigninClient>(profile);
-  signin_client->SetURLLoaderFactoryForTest(
-      test_url_loader_factory->GetSafeWeakWrapper());
-  return signin_client;
-}
-
 void OnWillCreateBrowserContextServices(
     network::TestURLLoaderFactory* test_url_loader_factory,
     content::BrowserContext* context) {
-  ChromeSigninClientFactory::GetInstance()->SetTestingFactory(
-      context, base::BindRepeating(&BuildSigninClientWithURLLoader,
+  GaiaCookieManagerServiceFactory::GetInstance()->SetTestingFactory(
+      context, base::BindRepeating(&BuildGaiaCookieManagerServiceWithURLLoader,
                                    test_url_loader_factory));
 }
 
 }  // namespace
 
-ScopedSigninClientFactory SetUpSigninClient(
+ScopedGaiaCookieManagerServiceFactory SetUpGaiaCookieManagerService(
     network::TestURLLoaderFactory* test_url_loader_factory) {
   return BrowserContextDependencyManager::GetInstance()
       ->RegisterWillCreateBrowserContextServicesCallbackForTesting(
diff --git a/chrome/browser/sync/test/integration/secondary_account_helper.h b/chrome/browser/sync/test/integration/secondary_account_helper.h
index 3bab2a83..e7d74c4 100644
--- a/chrome/browser/sync/test/integration/secondary_account_helper.h
+++ b/chrome/browser/sync/test/integration/secondary_account_helper.h
@@ -23,15 +23,15 @@
 
 namespace secondary_account_helper {
 
-using ScopedSigninClientFactory = std::unique_ptr<
+using ScopedGaiaCookieManagerServiceFactory = std::unique_ptr<
     base::CallbackList<void(content::BrowserContext*)>::Subscription>;
 
-// Sets up a factory to create a SigninClient which uses the
+// Sets up a factory to create a GaiaCookieManagerService which uses the
 // provided |test_url_loader_factory| for cookie-related requests. Meant to be
 // called from SetUpInProcessBrowserTestFixture. The caller should hold on to
 // the returned object for the duration of the test, e.g. store it in a member
 // of the test fixture class.
-ScopedSigninClientFactory SetUpSigninClient(
+ScopedGaiaCookieManagerServiceFactory SetUpGaiaCookieManagerService(
     network::TestURLLoaderFactory* test_url_loader_factory);
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
index 0059c984..a987cd01 100644
--- a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
@@ -38,8 +38,9 @@
   ~SingleClientSecondaryAccountSyncTest() override {}
 
   void SetUpInProcessBrowserTestFixture() override {
-    test_signin_client_factory_ =
-        secondary_account_helper::SetUpSigninClient(&test_url_loader_factory_);
+    test_gaia_cookie_manager_factory_ =
+        secondary_account_helper::SetUpGaiaCookieManagerService(
+            &test_url_loader_factory_);
   }
 
   void SetUpOnMainThread() override {
@@ -54,8 +55,8 @@
  private:
   base::test::ScopedFeatureList features_;
 
-  secondary_account_helper::ScopedSigninClientFactory
-      test_signin_client_factory_;
+  secondary_account_helper::ScopedGaiaCookieManagerServiceFactory
+      test_gaia_cookie_manager_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SingleClientSecondaryAccountSyncTest);
 };
diff --git a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
index 322085c18..ccb19d7 100644
--- a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
@@ -296,9 +296,7 @@
   WaitForURLOnServer(GURL(chrome::kChromeUIHistoryURL));
 }
 
-// Disabling due to flakiness on all platforms, crbug.com/930413.
-IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest,
-                       DISABLED_NavigateThenCloseTab) {
+IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, NavigateThenCloseTab) {
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
   ASSERT_TRUE(CheckInitialState(0));
 
diff --git a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
index b430a9f1..bbc80bc 100644
--- a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
@@ -1116,8 +1116,9 @@
   ~SingleClientWalletSecondaryAccountSyncTest() override {}
 
   void SetUpInProcessBrowserTestFixture() override {
-    test_signin_client_factory_ =
-        secondary_account_helper::SetUpSigninClient(&test_url_loader_factory_);
+    test_gaia_cookie_manager_factory_ =
+        secondary_account_helper::SetUpGaiaCookieManagerService(
+            &test_url_loader_factory_);
   }
 
   void SetUpOnMainThread() override {
@@ -1130,8 +1131,8 @@
   Profile* profile() { return GetProfile(0); }
 
  private:
-  secondary_account_helper::ScopedSigninClientFactory
-      test_signin_client_factory_;
+  secondary_account_helper::ScopedGaiaCookieManagerServiceFactory
+      test_gaia_cookie_manager_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SingleClientWalletSecondaryAccountSyncTest);
 };
diff --git a/chrome/browser/translate/chrome_translate_client.cc b/chrome/browser/translate/chrome_translate_client.cc
index 3ede756..dd1d9874 100644
--- a/chrome/browser/translate/chrome_translate_client.cc
+++ b/chrome/browser/translate/chrome_translate_client.cc
@@ -185,7 +185,6 @@
   return chrome_translate_client->GetTranslateManager();
 }
 
-// static
 void ChromeTranslateClient::GetTranslateLanguages(
     content::WebContents* web_contents,
     std::string* source,
@@ -193,19 +192,14 @@
   DCHECK(source != NULL);
   DCHECK(target != NULL);
 
-  ChromeTranslateClient* chrome_translate_client =
-      FromWebContents(web_contents);
-  if (!chrome_translate_client)
-    return;
-
   *source = translate::TranslateDownloadManager::GetLanguageCode(
-      chrome_translate_client->GetLanguageState().original_language());
+      GetLanguageState().original_language());
 
   Profile* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
   std::unique_ptr<translate::TranslatePrefs> translate_prefs =
       CreateTranslatePrefs(profile->GetPrefs());
-  if (!web_contents->GetBrowserContext()->IsOffTheRecord()) {
+  if (!profile->IsOffTheRecord()) {
     std::string auto_translate_language =
         translate::TranslateManager::GetAutoTargetLanguage(
             *source, translate_prefs.get());
@@ -264,7 +258,8 @@
     return false;
   }
 
-  ShowTranslateBubbleResult result = ShowBubble(step, error_type);
+  ShowTranslateBubbleResult result =
+      ShowBubble(step, source_language, target_language, error_type);
   if (result != ShowTranslateBubbleResult::SUCCESS &&
       step == translate::TRANSLATE_STEP_BEFORE_TRANSLATE) {
     translate_manager_->RecordTranslateEvent(
@@ -406,6 +401,8 @@
 
 ShowTranslateBubbleResult ChromeTranslateClient::ShowBubble(
     translate::TranslateStep step,
+    const std::string& source_language,
+    const std::string& target_language,
     translate::TranslateErrors::Type error_type) {
   DCHECK(translate_manager_);
 // The bubble is implemented only on the desktop platforms.
@@ -415,7 +412,9 @@
   // |browser| might be NULL when testing. In this case, Show(...) should be
   // called because the implementation for testing is used.
   if (!browser) {
-    return TranslateBubbleFactory::Show(NULL, web_contents(), step, error_type);
+    return TranslateBubbleFactory::Show(NULL, web_contents(), step,
+                                        source_language, target_language,
+                                        error_type);
   }
 
   if (web_contents() != browser->tab_strip_model()->GetActiveWebContents())
@@ -437,6 +436,7 @@
   }
 
   return TranslateBubbleFactory::Show(browser->window(), web_contents(), step,
+                                      source_language, target_language,
                                       error_type);
 #else
   NOTREACHED();
diff --git a/chrome/browser/translate/chrome_translate_client.h b/chrome/browser/translate/chrome_translate_client.h
index 2dcb15d..f5de9c8 100644
--- a/chrome/browser/translate/chrome_translate_client.h
+++ b/chrome/browser/translate/chrome_translate_client.h
@@ -70,9 +70,9 @@
       content::WebContents* web_contents);
 
   // Gets |source| and |target| language for translation.
-  static void GetTranslateLanguages(content::WebContents* web_contents,
-                                    std::string* source,
-                                    std::string* target);
+  void GetTranslateLanguages(content::WebContents* web_contents,
+                             std::string* source,
+                             std::string* target);
 
   // Gets the associated TranslateManager.
   translate::TranslateManager* GetTranslateManager();
@@ -133,6 +133,8 @@
   // Shows the translate bubble.
   ShowTranslateBubbleResult ShowBubble(
       translate::TranslateStep step,
+      const std::string& source_language,
+      const std::string& target_language,
       translate::TranslateErrors::Type error_type);
 
   translate::ContentTranslateDriver translate_driver_;
diff --git a/chrome/browser/translate/translate_manager_render_view_host_unittest.cc b/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
index d4424ec..7aaeacb 100644
--- a/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
+++ b/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
@@ -82,6 +82,8 @@
       BrowserWindow* window,
       content::WebContents* web_contents,
       translate::TranslateStep step,
+      const std::string& source_language,
+      const std::string& target_language,
       translate::TranslateErrors::Type error_type) override {
     if (model_) {
       model_->SetViewState(
@@ -91,11 +93,6 @@
 
     ChromeTranslateClient* chrome_translate_client =
         ChromeTranslateClient::FromWebContents(web_contents);
-    std::string source_language =
-        chrome_translate_client->GetLanguageState().original_language();
-    std::string target_language =
-        translate::TranslateDownloadManager::GetLanguageCode(
-            g_browser_process->GetApplicationLocale());
 
     std::unique_ptr<translate::TranslateUIDelegate> ui_delegate(
         new translate::TranslateUIDelegate(
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
index 4de7f00..6046328 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
@@ -103,6 +103,6 @@
   }
 }
 
-INSTANTIATE_TEST_CASE_P(, ArcAppShortcutsSearchProviderTest, testing::Bool());
+INSTANTIATE_TEST_SUITE_P(, ArcAppShortcutsSearchProviderTest, testing::Bool());
 
 }  // namespace app_list
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 137a9991..78274008 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -908,6 +908,11 @@
   ChromeTranslateClient* chrome_translate_client =
       ChromeTranslateClient::FromWebContents(web_contents);
 
+  std::string source_language;
+  std::string target_language;
+  chrome_translate_client->GetTranslateLanguages(web_contents, &source_language,
+                                                 &target_language);
+
   translate::TranslateStep step = translate::TRANSLATE_STEP_BEFORE_TRANSLATE;
   if (chrome_translate_client) {
     if (chrome_translate_client->GetLanguageState().translation_pending())
@@ -918,7 +923,8 @@
       step = translate::TRANSLATE_STEP_AFTER_TRANSLATE;
   }
   ShowTranslateBubbleResult result = browser->window()->ShowTranslateBubble(
-      web_contents, step, translate::TranslateErrors::NONE, true);
+      web_contents, step, source_language, target_language,
+      translate::TranslateErrors::NONE, true);
   if (result != ShowTranslateBubbleResult::SUCCESS)
     translate::ReportUiAction(TranslateBubbleResultToUiEvent(result));
 }
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 763b177..f43018b7 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -341,6 +341,8 @@
   virtual ShowTranslateBubbleResult ShowTranslateBubble(
       content::WebContents* contents,
       translate::TranslateStep step,
+      const std::string& source_language,
+      const std::string& target_language,
       translate::TranslateErrors::Type error_type,
       bool is_user_gesture) = 0;
 
diff --git a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h
index f4488b3..ac2b13f 100644
--- a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h
+++ b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h
@@ -25,7 +25,8 @@
 // notification response action, clicking on it, clicking on a button etc.
 @interface NotificationResponseBuilder : NSObject
 
-+ (NSDictionary*)buildDictionary:(NSUserNotification*)notification;
++ (NSDictionary*)buildActivatedDictionary:(NSUserNotification*)notification;
++ (NSDictionary*)buildDismissedDictionary:(NSUserNotification*)notification;
 
 @end
 
diff --git a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.mm b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.mm
index fe41aea..fd8c75b 100644
--- a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.mm
+++ b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.mm
@@ -9,7 +9,8 @@
 
 @implementation NotificationResponseBuilder
 
-+ (NSDictionary*)buildDictionary:(NSUserNotification*)notification {
++ (NSDictionary*)buildDictionary:(NSUserNotification*)notification
+                       dismissed:(BOOL)dismissed {
   NSString* origin =
       [[notification userInfo]
           objectForKey:notification_constants::kNotificationOrigin]
@@ -36,16 +37,18 @@
       objectForKey:notification_constants::kNotificationHasSettingsButton];
 
   // Closed notifications are not activated.
+  NSUserNotificationActivationType activationType =
+      dismissed ? NSUserNotificationActivationTypeNone
+                : notification.activationType;
   NotificationOperation operation =
-      notification.activationType == NSUserNotificationActivationTypeNone
+      activationType == NSUserNotificationActivationTypeNone
           ? NOTIFICATION_CLOSE
           : NOTIFICATION_CLICK;
   int buttonIndex = notification_constants::kNotificationInvalidButtonIndex;
 
   // Determine whether the user clicked on a button, and if they did, whether it
   // was a developer-provided button or the  Settings button.
-  if (notification.activationType ==
-      NSUserNotificationActivationTypeActionButtonClicked) {
+  if (activationType == NSUserNotificationActivationTypeActionButtonClicked) {
     NSArray* alternateButtons = @[];
     if ([notification
             respondsToSelector:@selector(_alternateActionButtonTitles)]) {
@@ -93,4 +96,14 @@
   };
 }
 
++ (NSDictionary*)buildActivatedDictionary:(NSUserNotification*)notification {
+  return [NotificationResponseBuilder buildDictionary:notification
+                                            dismissed:NO];
+}
+
++ (NSDictionary*)buildDismissedDictionary:(NSUserNotification*)notification {
+  return [NotificationResponseBuilder buildDictionary:notification
+                                            dismissed:YES];
+}
+
 @end
diff --git a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac_unittest.mm b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac_unittest.mm
index 5392dbf3..e1baa61 100644
--- a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac_unittest.mm
+++ b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac_unittest.mm
@@ -61,7 +61,7 @@
                   forKey:@"_activationType"];
 
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
 
   NSNumber* operation =
       [response objectForKey:notification_constants::kNotificationOperation];
@@ -83,7 +83,7 @@
   [notification setValue:@(NSUserNotificationActivationTypeActionButtonClicked)
                   forKey:@"_activationType"];
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
 
   NSNumber* operation =
       [response objectForKey:notification_constants::kNotificationOperation];
@@ -109,7 +109,7 @@
   [notification setValue:[NSNumber numberWithInt:0]
                   forKey:@"_alternateActionIndex"];
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
 
   NSNumber* operation =
       [response objectForKey:notification_constants::kNotificationOperation];
@@ -134,7 +134,7 @@
                   forKey:@"_alternateActionIndex"];
 
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
 
   NSNumber* operation =
       [response objectForKey:notification_constants::kNotificationOperation];
@@ -162,7 +162,7 @@
                   forKey:@"_alternateActionIndex"];
 
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
 
   NSNumber* operation =
       [response objectForKey:notification_constants::kNotificationOperation];
@@ -184,7 +184,7 @@
                   forKey:@"_activationType"];
 
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
 
   NSNumber* operation =
       [response objectForKey:notification_constants::kNotificationOperation];
@@ -211,7 +211,7 @@
                   forKey:@"_alternateActionIndex"];
 
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
 
   NSNumber* operation =
       [response objectForKey:notification_constants::kNotificationOperation];
@@ -220,3 +220,26 @@
   EXPECT_EQ(NOTIFICATION_CLICK, operation.intValue);
   EXPECT_EQ(1, buttonIndex.intValue);
 }
+
+TEST_F(NotificationResponseBuilderMacTest, TestNotificationClickAndClose) {
+  base::scoped_nsobject<NotificationBuilder> builder =
+      NewTestBuilder(NotificationHandler::Type::WEB_PERSISTENT);
+  NSUserNotification* notification = [builder buildUserNotification];
+  // This will be set by the notification center in didDismissAlert if a
+  // notification has been clicked before. Make sure that we do not handle that
+  // as a click event. See crbug.com/924414.
+  [notification setValue:@(NSUserNotificationActivationTypeContentsClicked)
+                  forKey:@"_activationType"];
+
+  NSDictionary* response =
+      [NotificationResponseBuilder buildDismissedDictionary:notification];
+
+  NSNumber* operation =
+      [response objectForKey:notification_constants::kNotificationOperation];
+  NSNumber* buttonIndex =
+      [response objectForKey:notification_constants::kNotificationButtonIndex];
+
+  EXPECT_EQ(NOTIFICATION_CLOSE, operation.intValue);
+  EXPECT_EQ(notification_constants::kNotificationInvalidButtonIndex,
+            buttonIndex.intValue);
+}
diff --git a/chrome/browser/ui/cocoa/notifications/notification_service_delegate.mm b/chrome/browser/ui/cocoa/notifications/notification_service_delegate.mm
index 0d529ae..078da87 100644
--- a/chrome/browser/ui/cocoa/notifications/notification_service_delegate.mm
+++ b/chrome/browser/ui/cocoa/notifications/notification_service_delegate.mm
@@ -66,7 +66,7 @@
 - (void)userNotificationCenter:(NSUserNotificationCenter*)center
        didActivateNotification:(NSUserNotification*)notification {
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildActivatedDictionary:notification];
   [[connection_ remoteObjectProxy] notificationClick:response];
 }
 
@@ -74,9 +74,20 @@
 - (void)userNotificationCenter:(NSUserNotificationCenter*)center
                didDismissAlert:(NSUserNotification*)notification {
   NSDictionary* response =
-      [NotificationResponseBuilder buildDictionary:notification];
+      [NotificationResponseBuilder buildDismissedDictionary:notification];
   [[connection_ remoteObjectProxy] notificationClick:response];
   [transactionHandler_ closeTransactionIfNeeded];
 }
 
+// _NSUserNotificationCenterDelegatePrivate:
+- (void)userNotificationCenter:(NSUserNotificationCenter*)center
+    didRemoveDeliveredNotifications:(NSArray*)notifications {
+  for (NSUserNotification* notification in notifications) {
+    NSDictionary* response =
+        [NotificationResponseBuilder buildDismissedDictionary:notification];
+    [[connection_ remoteObjectProxy] notificationClick:response];
+  }
+  [transactionHandler_ closeTransactionIfNeeded];
+}
+
 @end
diff --git a/chrome/browser/ui/passwords/google_password_manager_navigation_throttle_browsertest.cc b/chrome/browser/ui/passwords/google_password_manager_navigation_throttle_browsertest.cc
index fbaa21c..b1b6155a 100644
--- a/chrome/browser/ui/passwords/google_password_manager_navigation_throttle_browsertest.cc
+++ b/chrome/browser/ui/passwords/google_password_manager_navigation_throttle_browsertest.cc
@@ -80,7 +80,7 @@
 #if defined(OS_CHROMEOS)
     // In browser tests, the profile may already be authenticated with stub
     // account |user_manager::kStubUserEmail|.
-    AccountInfo info =
+    CoreAccountInfo info =
         IdentityManagerFactory::GetForProfile(profile)->GetPrimaryAccountInfo();
     username = info.email;
 #endif
diff --git a/chrome/browser/ui/translate/translate_bubble_factory.cc b/chrome/browser/ui/translate/translate_bubble_factory.cc
index 7ac2a74..3d3361fd 100644
--- a/chrome/browser/ui/translate/translate_bubble_factory.cc
+++ b/chrome/browser/ui/translate/translate_bubble_factory.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ui/translate/translate_bubble_factory.h"
 
+#include <string>
+
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
 
@@ -13,11 +15,14 @@
     BrowserWindow* window,
     content::WebContents* web_contents,
     translate::TranslateStep step,
+    const std::string& source_language,
+    const std::string& target_language,
     translate::TranslateErrors::Type error_type) {
   // |window| might be null when testing.
   if (!window)
     return ShowTranslateBubbleResult::BROWSER_WINDOW_NOT_VALID;
-  return window->ShowTranslateBubble(web_contents, step, error_type, false);
+  return window->ShowTranslateBubble(web_contents, step, source_language,
+                                     target_language, error_type, false);
 }
 
 }  // namespace
@@ -30,13 +35,17 @@
     BrowserWindow* window,
     content::WebContents* web_contents,
     translate::TranslateStep step,
+    const std::string& source_language,
+    const std::string& target_language,
     translate::TranslateErrors::Type error_type) {
   if (current_factory_) {
     return current_factory_->ShowImplementation(window, web_contents, step,
-                                                error_type);
+                                                source_language,
+                                                target_language, error_type);
   }
 
-  return ShowDefault(window, web_contents, step, error_type);
+  return ShowDefault(window, web_contents, step, source_language,
+                     target_language, error_type);
 }
 
 // static
diff --git a/chrome/browser/ui/translate/translate_bubble_factory.h b/chrome/browser/ui/translate/translate_bubble_factory.h
index 5efb6f0..08411051 100644
--- a/chrome/browser/ui/translate/translate_bubble_factory.h
+++ b/chrome/browser/ui/translate/translate_bubble_factory.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_UI_TRANSLATE_TRANSLATE_BUBBLE_FACTORY_H_
 #define CHROME_BROWSER_UI_TRANSLATE_TRANSLATE_BUBBLE_FACTORY_H_
 
+#include <string>
+
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/ui/translate/translate_bubble_model.h"
 #include "components/translate/core/common/translate_errors.h"
@@ -27,6 +29,8 @@
       BrowserWindow* window,
       content::WebContents* web_contents,
       translate::TranslateStep step,
+      const std::string& source_language,
+      const std::string& target_language,
       translate::TranslateErrors::Type error_type);
 
   // Sets the factory to change the behavior how to show the bubble.
@@ -39,6 +43,8 @@
       BrowserWindow* window,
       content::WebContents* web_contents,
       translate::TranslateStep step,
+      const std::string& source_language,
+      const std::string& target_language,
       translate::TranslateErrors::Type error_type) = 0;
 
  private:
diff --git a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc
index 3ce85b2..6f3c8e5 100644
--- a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc
+++ b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc
@@ -58,6 +58,7 @@
 // text depends on the |view_state| of the dialog.
 std::unique_ptr<views::Label> CreateTitle(
     LocalCardMigrationDialogState view_state,
+    LocalCardMigrationDialogView* dialog_view,
     int card_list_size) {
   int message_id;
   switch (view_state) {
@@ -81,7 +82,9 @@
   title->SetFontList(gfx::FontList().Derive(kMigrationDialogTitleFontSize,
                                             gfx::Font::NORMAL,
                                             gfx::Font::Weight::NORMAL));
-  title->SetEnabledColor(gfx::kGoogleGrey900);
+  title->SetEnabledColor(dialog_view->GetNativeTheme()->SystemDarkModeEnabled()
+                             ? gfx::kGoogleGrey200
+                             : gfx::kGoogleGrey900);
   constexpr int kMigrationDialogTitleLineHeight = 20;
   title->SetMultiLine(true);
   title->SetLineHeight(kMigrationDialogTitleLineHeight);
@@ -161,7 +164,9 @@
 }
 
 // Create the view containing the |tip_message| shown to the user.
-std::unique_ptr<views::View> CreateTip(const base::string16& tip_message) {
+std::unique_ptr<views::View> CreateTip(
+    const base::string16& tip_message,
+    LocalCardMigrationDialogView* dialog_view) {
   ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
   // Set up the tip text container with inset, background and a solid border.
   auto tip_text_container = std::make_unique<views::View>();
@@ -173,23 +178,36 @@
   tip_text_container->SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::kHorizontal, gfx::Insets(container_insets),
       container_child_space));
-  tip_text_container->SetBackground(
-      views::CreateSolidBackground(gfx::kGoogleGrey050));
-  constexpr int kTipValuePromptBorderThickness = 1;
-  tip_text_container->SetBorder(views::CreateSolidBorder(
-      kTipValuePromptBorderThickness, gfx::kGoogleGrey100));
+  tip_text_container->SetBackground(views::CreateSolidBackground(
+      dialog_view->GetNativeTheme()->SystemDarkModeEnabled()
+          ? gfx::kGoogleGrey800
+          : gfx::kGoogleGrey050));
+
+  // If in dark mode, do not add the border.
+  if (!dialog_view->GetNativeTheme()->SystemDarkModeEnabled()) {
+    constexpr int kTipValuePromptBorderThickness = 1;
+    tip_text_container->SetBorder(views::CreateSolidBorder(
+        kTipValuePromptBorderThickness, gfx::kGoogleGrey100));
+  }
 
   auto* lightbulb_outline_image = new views::ImageView();
   constexpr int kTipImageSize = 16;
-  lightbulb_outline_image->SetImage(
-      gfx::CreateVectorIcon(vector_icons::kLightbulbOutlineIcon, kTipImageSize,
-                            gfx::kGoogleYellow700));
+  lightbulb_outline_image->SetImage(gfx::CreateVectorIcon(
+      vector_icons::kLightbulbOutlineIcon, kTipImageSize,
+      dialog_view->GetNativeTheme()->SystemDarkModeEnabled()
+          ? gfx::kGoogleYellow300
+          : gfx::kGoogleYellow700));
   lightbulb_outline_image->SetVerticalAlignment(views::ImageView::LEADING);
   tip_text_container->AddChildView(lightbulb_outline_image);
 
   auto* tip = new views::Label(tip_message, CONTEXT_BODY_TEXT_SMALL,
                                ChromeTextStyle::STYLE_SECONDARY);
   tip->SetMultiLine(true);
+  // If it is in dark mode, set the font color to GG200 since it is on a lighter
+  // shade of grey background.
+  if (dialog_view->GetNativeTheme()->SystemDarkModeEnabled()) {
+    tip->SetEnabledColor(gfx::kGoogleGrey200);
+  }
   tip->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   tip->SizeToFit(
       provider->GetDistanceMetric(DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH) -
@@ -232,7 +250,7 @@
     if (view_state == LocalCardMigrationDialogState::kFinished &&
         card_list_size <= kShowTipMessageCardNumberLimit) {
       feedback_view->AddChildView(
-          CreateTip(controller->GetTipMessage()).release());
+          CreateTip(controller->GetTipMessage(), dialog_view).release());
     }
   }
 
@@ -462,14 +480,17 @@
   auto* image = new views::ImageView();
   constexpr int kImageBorderBottom = 8;
   image->SetBorder(views::CreateEmptyBorder(0, 0, kImageBorderBottom, 0));
-  image->SetImage(rb.GetImageSkiaNamed(IDR_AUTOFILL_MIGRATION_DIALOG_HEADER));
+  image->SetImage(
+      rb.GetImageSkiaNamed(GetNativeTheme()->SystemDarkModeEnabled()
+                               ? IDR_AUTOFILL_MIGRATION_DIALOG_HEADER_DARK
+                               : IDR_AUTOFILL_MIGRATION_DIALOG_HEADER));
   image->SetAccessibleName(
       l10n_util::GetStringUTF16(IDS_AUTOFILL_GOOGLE_PAY_LOGO_ACCESSIBLE_NAME));
   AddChildView(image);
 
   LocalCardMigrationDialogState view_state = controller_->GetViewState();
-  AddChildView(
-      CreateTitle(view_state, controller_->GetCardList().size()).release());
+  AddChildView(CreateTitle(view_state, this, controller_->GetCardList().size())
+                   .release());
 
   if (view_state == LocalCardMigrationDialogState::kOffered) {
     offer_view_ = new LocalCardMigrationOfferView(controller_, this);
diff --git a/chrome/browser/ui/views/autofill/migratable_card_view.cc b/chrome/browser/ui/views/autofill/migratable_card_view.cc
index 3fdd34f..abe3f94 100644
--- a/chrome/browser/ui/views/autofill/migratable_card_view.cc
+++ b/chrome/browser/ui/views/autofill/migratable_card_view.cc
@@ -64,8 +64,9 @@
       CONTEXT_BODY_TEXT_SMALL, ChromeTextStyle::STYLE_RED);
 
   checkbox_uncheck_text_container_->AddChildView(checkbox_uncheck_text_);
-  checkbox_uncheck_text_container_->SetBackground(
-      views::CreateSolidBackground(gfx::kGoogleGrey050));
+  checkbox_uncheck_text_container_->SetBackground(views::CreateSolidBackground(
+      GetNativeTheme()->SystemDarkModeEnabled() ? gfx::kGoogleGrey800
+                                                : gfx::kGoogleGrey050));
   checkbox_uncheck_text_container_->SetVisible(false);
 
   AddChildView(checkbox_uncheck_text_container_);
@@ -123,15 +124,17 @@
       auto* migration_succeeded_image = new views::ImageView();
       migration_succeeded_image->SetImage(gfx::CreateVectorIcon(
           vector_icons::kCheckCircleIcon, kMigrationResultImageSize,
-          gfx::kGoogleGreen700));
+          GetNativeTheme()->SystemDarkModeEnabled() ? gfx::kGoogleGreen200
+                                                    : gfx::kGoogleGreen700));
       migratable_card_description_view->AddChildView(migration_succeeded_image);
       break;
     }
     case MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD: {
       auto* migration_failed_image = new views::ImageView();
-      migration_failed_image->SetImage(
-          gfx::CreateVectorIcon(vector_icons::kErrorIcon,
-                                kMigrationResultImageSize, gfx::kGoogleRed700));
+      migration_failed_image->SetImage(gfx::CreateVectorIcon(
+          vector_icons::kErrorIcon, kMigrationResultImageSize,
+          GetNativeTheme()->SystemDarkModeEnabled() ? gfx::kGoogleRed300
+                                                    : gfx::kGoogleRed700));
       migratable_card_description_view->AddChildView(migration_failed_image);
       break;
     }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
index a944a85f..c14bd70 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -1041,6 +1041,7 @@
   chrome::Find(app_browser_);
   browser_view_->ShowTranslateBubble(browser_view_->GetActiveWebContents(),
                                      translate::TRANSLATE_STEP_AFTER_TRANSLATE,
+                                     "en", "fr",
                                      translate::TranslateErrors::NONE, true);
 
   EXPECT_TRUE(translate_icon->visible());
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index f8e28fd2..7c49b480 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1421,6 +1421,8 @@
 ShowTranslateBubbleResult BrowserView::ShowTranslateBubble(
     content::WebContents* web_contents,
     translate::TranslateStep step,
+    const std::string& source_language,
+    const std::string& target_language,
     translate::TranslateErrors::Type error_type,
     bool is_user_gesture) {
   if (contents_web_view_->HasFocus() &&
@@ -1442,7 +1444,7 @@
           ->GetPageActionIconView(PageActionIconType::kTranslate);
   TranslateBubbleView::ShowBubble(
       toolbar_button_provider()->GetAnchorView(), translate_icon, web_contents,
-      step, error_type,
+      step, source_language, target_language, error_type,
       is_user_gesture ? TranslateBubbleView::USER_GESTURE
                       : TranslateBubbleView::AUTOMATIC);
 
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index e95e89e..9989c0f 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -382,6 +382,8 @@
   ShowTranslateBubbleResult ShowTranslateBubble(
       content::WebContents* contents,
       translate::TranslateStep step,
+      const std::string& source_language,
+      const std::string& target_language,
       translate::TranslateErrors::Type error_type,
       bool is_user_gesture) override;
 #if BUILDFLAG(ENABLE_ONE_CLICK_SIGNIN)
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc
index 2a36bbe..ff5700f3 100644
--- a/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc
@@ -83,9 +83,9 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  browser_view->ShowTranslateBubble(web_contents,
-                                    translate::TRANSLATE_STEP_AFTER_TRANSLATE,
-                                    translate::TranslateErrors::NONE, true);
+  browser_view->ShowTranslateBubble(
+      web_contents, translate::TRANSLATE_STEP_AFTER_TRANSLATE, "en", "fr",
+      translate::TranslateErrors::NONE, true);
 
   PageActionIconView* icon_view =
       browser_view->toolbar_button_provider()
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index 2d324d3..764c461f 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -88,6 +88,8 @@
     views::Button* highlighted_button,
     content::WebContents* web_contents,
     translate::TranslateStep step,
+    const std::string& source_language,
+    const std::string& target_language,
     translate::TranslateErrors::Type error_type,
     DisplayReason reason) {
   if (translate_bubble_view_) {
@@ -113,11 +115,6 @@
     }
   }
 
-  std::string source_language;
-  std::string target_language;
-  ChromeTranslateClient::GetTranslateLanguages(web_contents, &source_language,
-                                               &target_language);
-
   std::unique_ptr<translate::TranslateUIDelegate> ui_delegate(
       new translate::TranslateUIDelegate(
           ChromeTranslateClient::GetManagerFromWebContents(web_contents)
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.h b/chrome/browser/ui/views/translate/translate_bubble_view.h
index 7cfee0e6..5c9aa5ac 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.h
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.h
@@ -63,6 +63,8 @@
                                    views::Button* highlighted_button,
                                    content::WebContents* web_contents,
                                    translate::TranslateStep step,
+                                   const std::string& source_language,
+                                   const std::string& target_language,
                                    translate::TranslateErrors::Type error_type,
                                    DisplayReason reason);
 
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
index 880f787..5eab4478 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
@@ -112,7 +112,6 @@
 void InlineLoginHandlerChromeOS::SetExtraInitParams(
     base::DictionaryValue& params) {
   const GaiaUrls* const gaia_urls = GaiaUrls::GetInstance();
-  params.SetKey("service", base::Value("chromiumsync"));
   params.SetKey("isNewGaiaFlow", base::Value(true));
   params.SetKey("clientId", base::Value(gaia_urls->oauth2_chrome_client_id()));
 
@@ -120,7 +119,7 @@
   params.SetKey("gaiaPath", base::Value(url.path().substr(1)));
 
   params.SetKey("constrained", base::Value("1"));
-  params.SetKey("flow", base::Value("addaccount"));
+  params.SetKey("flow", base::Value("crosAddAccount"));
 }
 
 void InlineLoginHandlerChromeOS::CompleteLogin(const std::string& email,
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index f8378f4..8b461ee9 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -239,10 +239,6 @@
 // absence of MIME charset specification
 const char kDefaultCharset[] = "intl.charset_default";
 
-// The value to use for Accept-Languages HTTP header when making an HTTP
-// request.
-const char kAcceptLanguages[] = "intl.accept_languages";
-
 // If these change, the corresponding enums in the extension API
 // experimental.fontSettings.json must also change.
 const char* const kWebKitScriptsForFontFamilyMaps[] = {
@@ -538,13 +534,6 @@
 const char kLanguageAllowedInputMethods[] =
     "settings.language.allowed_input_methods";
 
-// A string pref (comma-separated list) set to the preferred language IDs
-// (ex. "en-US,fr,ko").
-const char kLanguagePreferredLanguages[] =
-    "settings.language.preferred_languages";
-const char kLanguagePreferredLanguagesSyncable[] =
-    "settings.language.preferred_languages_syncable";
-
 // A string pref (comma-separated list) set to the preloaded (active) input
 // method IDs (ex. "pinyin,mozc").
 const char kLanguagePreloadEngines[] = "settings.language.preload_engines";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 81a33aa..30f01777 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -74,7 +74,6 @@
 #endif
 
 extern const char kDefaultCharset[];
-extern const char kAcceptLanguages[];
 extern const char kWebKitCommonScript[];
 extern const char kWebKitStandardFontFamily[];
 extern const char kWebKitFixedFontFamily[];
@@ -206,8 +205,6 @@
 extern const char kLanguageCurrentInputMethod[];
 extern const char kLanguagePreviousInputMethod[];
 extern const char kLanguageAllowedInputMethods[];
-extern const char kLanguagePreferredLanguages[];
-extern const char kLanguagePreferredLanguagesSyncable[];
 extern const char kLanguagePreloadEngines[];
 extern const char kLanguagePreloadEnginesSyncable[];
 extern const char kLanguageEnabledImes[];
diff --git a/chrome/credential_provider/gaiacp/BUILD.gn b/chrome/credential_provider/gaiacp/BUILD.gn
index 1b58b31f..c1616f5 100644
--- a/chrome/credential_provider/gaiacp/BUILD.gn
+++ b/chrome/credential_provider/gaiacp/BUILD.gn
@@ -91,6 +91,7 @@
   deps = [
     ":gaia_credential_provider_idl",
     ":static_resources",
+    "../eventlog:gcp_eventlog_messages",
     "//chrome/common:version_header",
     "//chrome/installer/launcher_support",
     "//components/crash/content/app:app",
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc
index 8b674326..e9f6628ac 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc
@@ -275,14 +275,14 @@
 // 'username0' ... 'username8' before failing. At 'username9' the test should
 // fail.
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     AvailableUsername,
     GcpAssociatedUserRunnableGaiaCredentialTest,
     ::testing::Combine(::testing::Range(0, kMaxUsernameAttempts - 2),
                        ::testing::Values(true),
                        ::testing::Values(true, false)));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     UnavailableUsername,
     GcpAssociatedUserRunnableGaiaCredentialTest,
     ::testing::Combine(::testing::Values(kMaxUsernameAttempts - 1),
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc
index 568caec..f010c3c 100644
--- a/chrome/test/base/test_browser_window.cc
+++ b/chrome/test/base/test_browser_window.cc
@@ -178,6 +178,8 @@
 ShowTranslateBubbleResult TestBrowserWindow::ShowTranslateBubble(
     content::WebContents* contents,
     translate::TranslateStep step,
+    const std::string& source_language,
+    const std::string& target_language,
     translate::TranslateErrors::Type error_type,
     bool is_user_gesture) {
   return ShowTranslateBubbleResult::SUCCESS;
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index 74d9029..0bad1a5 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -131,6 +131,8 @@
   ShowTranslateBubbleResult ShowTranslateBubble(
       content::WebContents* contents,
       translate::TranslateStep step,
+      const std::string& source_language,
+      const std::string& target_language,
       translate::TranslateErrors::Type error_type,
       bool is_user_gesture) override;
 #if BUILDFLAG(ENABLE_ONE_CLICK_SIGNIN)
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index cb28e2b..51bf356e 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -116,6 +116,8 @@
     'ChromeExtensionsCapabilityTest.testWaitsForExtensionToLoad',
 ]
 _OS_SPECIFIC_FILTER['linux'] = [
+    # https://bugs.chromium.org/p/chromium/issues/detail?id=932073
+    'ChromeExtensionsCapabilityTest.testWaitsForExtensionToLoad',
 ]
 _OS_SPECIFIC_FILTER['mac'] = [
     # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1927
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc
index 886db73..768cce8a 100644
--- a/chromeos/network/client_cert_resolver.cc
+++ b/chromeos/network/client_cert_resolver.cc
@@ -10,6 +10,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -275,19 +276,20 @@
   return pem_encoded_issuer;
 }
 
-std::vector<CertAndIssuer> CreateSortedCertAndIssuerList(
-    net::ScopedCERTCertificateList certs,
-    base::Time now) {
+void CreateSortedCertAndIssuerList(
+    const NetworkCertLoader::NetworkCertList& network_certs,
+    base::Time now,
+    std::vector<CertAndIssuer>* all_cert_and_issuers,
+    std::vector<CertAndIssuer>* device_wide_cert_and_issuers) {
   // Filter all client certs and determines each certificate's issuer, which is
   // required for the pattern matching.
-  // TODO(crbug.com/781693): Consider moving the filtering of client certs into
-  // NetworkCertLoader. It should not be in ClientCertResolver's responsibility
-  // to decide if a certificate is a valid client certificate or not. Other
-  // consumers of NetworkCertLoader could also use a pre-filtered list (e.g.
-  // NetworkCertMigrator).
-  std::vector<CertAndIssuer> client_certs;
-  for (net::ScopedCERTCertificate& scoped_cert : certs) {
-    CERTCertificate* cert = scoped_cert.get();
+  for (const NetworkCertLoader::NetworkCert& network_cert : network_certs) {
+    // If the caller is interested in device-wide certificates only, skip
+    // user-specific certificates.
+    if (!all_cert_and_issuers && !network_cert.is_device_wide())
+      continue;
+
+    CERTCertificate* cert = network_cert.cert();
     base::Time not_after;
     if (!net::x509_util::GetValidityTimes(cert, nullptr, &not_after) ||
         now > not_after ||
@@ -303,31 +305,42 @@
       continue;
     }
     std::string pem_encoded_issuer = GetPEMEncodedIssuer(cert);
-    client_certs.push_back(CertAndIssuer(std::move(scoped_cert),
-                                         pem_encoded_issuer,
-                                         private_key_nickname.value()));
+    if (all_cert_and_issuers) {
+      all_cert_and_issuers->push_back(
+          CertAndIssuer(net::x509_util::DupCERTCertificate(cert),
+                        pem_encoded_issuer, private_key_nickname.value()));
+    }
+    if (device_wide_cert_and_issuers && network_cert.is_device_wide()) {
+      device_wide_cert_and_issuers->push_back(
+          CertAndIssuer(net::x509_util::DupCERTCertificate(cert),
+                        pem_encoded_issuer, private_key_nickname.value()));
+    }
   }
 
-  std::sort(client_certs.begin(), client_certs.end(), &CompareCertExpiration);
-  return client_certs;
+  if (all_cert_and_issuers) {
+    std::sort(all_cert_and_issuers->begin(), all_cert_and_issuers->end(),
+              &CompareCertExpiration);
+  }
+  if (device_wide_cert_and_issuers) {
+    std::sort(device_wide_cert_and_issuers->begin(),
+              device_wide_cert_and_issuers->end(), &CompareCertExpiration);
+  }
 }
 
-// Searches for matches between |networks| and |all_certs| (for networks
-// configured in user policy) / |system_token_client_certs| (for networks
-// configured in device policy). Returns the matches that were found. Because
-// this calls NSS functions and is potentially slow, it must be run on a worker
-// thread.
+// Searches for matches between |networks| and |network_certs|. Returns the
+// matches that were found. Because this calls NSS functions and is potentially
+// slow, it must be run on a worker thread.
 std::vector<NetworkAndMatchingCert> FindCertificateMatches(
-    net::ScopedCERTCertificateList all_certs,
-    net::ScopedCERTCertificateList system_token_client_certs,
+    NetworkCertLoader::NetworkCertList network_certs,
     const std::vector<NetworkAndCertConfig>& networks,
     base::Time now) {
   std::vector<NetworkAndMatchingCert> matches;
 
-  std::vector<CertAndIssuer> all_client_certs(
-      CreateSortedCertAndIssuerList(std::move(all_certs), now));
-  std::vector<CertAndIssuer> system_client_certs(
-      CreateSortedCertAndIssuerList(std::move(system_token_client_certs), now));
+  std::vector<CertAndIssuer> all_client_cert_and_issuers;
+  std::vector<CertAndIssuer> device_wide_client_cert_and_issuers;
+  CreateSortedCertAndIssuerList(network_certs, now,
+                                &all_client_cert_and_issuers,
+                                &device_wide_client_cert_and_issuers);
 
   for (const NetworkAndCertConfig& network_and_cert_config : networks) {
     // Use only certs from the system token if the source of the client cert
@@ -335,8 +348,8 @@
     std::vector<CertAndIssuer>* client_certs =
         network_and_cert_config.cert_config.onc_source ==
                 ::onc::ONC_SOURCE_DEVICE_POLICY
-            ? &system_client_certs
-            : &all_client_certs;
+            ? &device_wide_client_cert_and_issuers
+            : &all_client_cert_and_issuers;
     auto cert_it = std::find_if(
         client_certs->begin(), client_certs->end(),
         MatchCertWithCertConfig(network_and_cert_config.cert_config));
@@ -456,25 +469,25 @@
 
   // Prepare and sort the list of known client certs. Use only certs from the
   // system token if the source of the client cert config is device policy.
-  std::vector<CertAndIssuer> client_certs;
+  std::vector<CertAndIssuer> client_cert_and_issuers;
   if (client_cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY) {
-    client_certs = CreateSortedCertAndIssuerList(
-        net::x509_util::DupCERTCertificateList(
-            NetworkCertLoader::Get()->system_token_client_certs()),
-        base::Time::Now());
+    CreateSortedCertAndIssuerList(
+        NetworkCertLoader::Get()->client_certs(), base::Time::Now(),
+        nullptr /* all_cert_and_issuers */,
+        &client_cert_and_issuers /* device_wide_cert_and_issuers */);
   } else {
-    client_certs = CreateSortedCertAndIssuerList(
-        net::x509_util::DupCERTCertificateList(
-            NetworkCertLoader::Get()->all_certs()),
-        base::Time::Now());
+    CreateSortedCertAndIssuerList(
+        NetworkCertLoader::Get()->client_certs(), base::Time::Now(),
+        &client_cert_and_issuers /* all_cert_and_issuers */,
+        nullptr /* device_wide_cert_and_issuers */);
   }
 
   // Search for a certificate matching the pattern or reference.
-  std::vector<CertAndIssuer>::iterator cert_it =
-      std::find_if(client_certs.begin(), client_certs.end(),
-                   MatchCertWithCertConfig(client_cert_config));
+  std::vector<CertAndIssuer>::iterator cert_it = std::find_if(
+      client_cert_and_issuers.begin(), client_cert_and_issuers.end(),
+      MatchCertWithCertConfig(client_cert_config));
 
-  if (cert_it == client_certs.end()) {
+  if (cert_it == client_cert_and_issuers.end()) {
     VLOG(1) << "Couldn't find a matching client cert";
     client_cert::SetEmptyShillProperties(client_cert_type, shill_properties);
     return false;
@@ -547,8 +560,7 @@
   }
 }
 
-void ClientCertResolver::OnCertificatesLoaded(
-    const net::ScopedCERTCertificateList& cert_list) {
+void ClientCertResolver::OnCertificatesLoaded() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   VLOG(2) << "OnCertificatesLoaded.";
   if (!ClientCertificatesLoaded())
@@ -652,10 +664,8 @@
       FROM_HERE,
       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
       base::BindOnce(&FindCertificateMatches,
-                     net::x509_util::DupCERTCertificateList(
-                         NetworkCertLoader::Get()->all_certs()),
-                     net::x509_util::DupCERTCertificateList(
-                         NetworkCertLoader::Get()->system_token_client_certs()),
+                     NetworkCertLoader::CloneNetworkCertList(
+                         NetworkCertLoader::Get()->client_certs()),
                      networks_to_resolve, Now()),
       base::BindOnce(&ClientCertResolver::ConfigureCertificates,
                      weak_ptr_factory_.GetWeakPtr()));
diff --git a/chromeos/network/client_cert_resolver.h b/chromeos/network/client_cert_resolver.h
index 9b08195a..3988a2a 100644
--- a/chromeos/network/client_cert_resolver.h
+++ b/chromeos/network/client_cert_resolver.h
@@ -95,8 +95,7 @@
   void NetworkConnectionStateChanged(const NetworkState* network) override;
 
   // NetworkCertLoader::Observer overrides
-  void OnCertificatesLoaded(
-      const net::ScopedCERTCertificateList& cert_list) override;
+  void OnCertificatesLoaded() override;
 
   // NetworkPolicyObserver overrides
   void PolicyAppliedToNetwork(const std::string& service_path) override;
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
index 61d30a02..21ab3b8 100644
--- a/chromeos/network/client_cert_resolver_unittest.cc
+++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -99,11 +99,19 @@
   void SetUp() override {
     ASSERT_TRUE(test_nssdb_.is_open());
     ASSERT_TRUE(test_system_nssdb_.is_open());
-
-    // Use the same DB for public and private slot.
-    test_nsscertdb_.reset(new net::NSSCertDatabaseChromeOS(
+    // Use the same slot as public and private slot for the user's
+    // NSSCertDatabse for testing.
+    test_nsscertdb_ = std::make_unique<net::NSSCertDatabaseChromeOS>(
         crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())),
-        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot()))));
+        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())));
+    // Create a NSSCertDatabase for the system slot. While NetworkCertLoader
+    // does not care about the public slot in this database, NSSCertDatabase
+    // requires a public slot. Pass the system slot there for testing.
+    test_system_nsscertdb_ = std::make_unique<net::NSSCertDatabaseChromeOS>(
+        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())),
+        crypto::ScopedPK11Slot() /* private_slot */);
+    test_system_nsscertdb_->SetSystemSlot(
+        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())));
 
     DBusThreadManager::Initialize();
     service_test_ =
@@ -138,6 +146,7 @@
  protected:
   void StartNetworkCertLoader() {
     network_cert_loader_->SetUserNSSDB(test_nsscertdb_.get());
+    network_cert_loader_->SetSystemNSSDB(test_system_nsscertdb_.get());
     if (test_client_cert_.get()) {
       int slot_id = 0;
       const std::string pkcs11_id =
@@ -206,9 +215,6 @@
   }
 
   void SetupTestCertInSystemToken(const std::string& prefix) {
-    test_nsscertdb_->SetSystemSlot(
-        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())));
-
     net::ImportClientCertAndKeyFromFile(
         net::GetTestCertsDirectory(), prefix + ".pem", prefix + ".pk8",
         test_system_nssdb_.slot(), &test_client_cert_);
@@ -414,6 +420,7 @@
   std::unique_ptr<ClientCertResolver> client_cert_resolver_;
   NetworkCertLoader* network_cert_loader_ = nullptr;
   std::unique_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_;
+  std::unique_ptr<net::NSSCertDatabaseChromeOS> test_system_nsscertdb_;
 
  private:
   // ClientCertResolver::Observer:
@@ -631,7 +638,8 @@
 
   StartNetworkCertLoader();
   scoped_task_environment_.RunUntilIdle();
-  EXPECT_EQ(1U, network_cert_loader_->system_token_client_certs().size());
+  ASSERT_EQ(1U, network_cert_loader_->client_certs().size());
+  EXPECT_TRUE(network_cert_loader_->client_certs()[0].is_device_wide());
 
   // Verify that the resolver positively matched the pattern in the policy with
   // the test client cert and configured the network.
@@ -670,7 +678,8 @@
 
   StartNetworkCertLoader();
   scoped_task_environment_.RunUntilIdle();
-  EXPECT_EQ(1U, network_cert_loader_->system_token_client_certs().size());
+  ASSERT_EQ(1U, network_cert_loader_->client_certs().size());
+  EXPECT_TRUE(network_cert_loader_->client_certs()[0].is_device_wide());
 
   // Verify that the resolver positively matched the pattern in the policy with
   // the test client cert and configured the network.
@@ -710,7 +719,8 @@
   network_properties_changed_count_ = 0;
   StartNetworkCertLoader();
   scoped_task_environment_.RunUntilIdle();
-  EXPECT_EQ(0U, network_cert_loader_->system_token_client_certs().size());
+  ASSERT_EQ(1U, network_cert_loader_->client_certs().size());
+  EXPECT_FALSE(network_cert_loader_->client_certs()[0].is_device_wide());
 
   // Verify that no client certificate was configured.
   std::string pkcs11_id;
@@ -806,7 +816,7 @@
   // Pretend that certificates have changed. One resolving task should still be
   // queued.
   static_cast<NetworkCertLoader::Observer*>(client_cert_resolver_.get())
-      ->OnCertificatesLoaded(NetworkCertLoader::Get()->all_certs());
+      ->OnCertificatesLoaded();
   EXPECT_TRUE(client_cert_resolver_->IsAnyResolveTaskRunning());
 
   scoped_task_environment_.RunUntilIdle();
diff --git a/chromeos/network/network_cert_loader.cc b/chromeos/network/network_cert_loader.cc
index 53088d1..12ad5aca 100644
--- a/chromeos/network/network_cert_loader.cc
+++ b/chromeos/network/network_cert_loader.cc
@@ -5,15 +5,19 @@
 #include "chromeos/network/network_cert_loader.h"
 
 #include <algorithm>
+#include <initializer_list>
 #include <memory>
+#include <set>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/containers/flat_set.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/task/post_task.h"
+#include "chromeos/network/certificate_helper.h"
 #include "crypto/nss_util.h"
 #include "crypto/scoped_nss_types.h"
 #include "net/cert/cert_database.h"
@@ -23,10 +27,73 @@
 
 namespace chromeos {
 
-// Caches certificates from a NSSCertDatabase. Handles reloading of certificates
-// on update notifications and provides status flags (loading / loaded).
-// NetworkCertLoader can use multiple CertCaches to combine certificates from
-// multiple sources.
+namespace {
+
+enum class NetworkCertType {
+  kAuthorityCertificate,
+  kClientCertificate,
+  kOther
+};
+
+NetworkCertType GetNetworkCertType(CERTCertificate* cert) {
+  net::CertType type = certificate::GetCertType(cert);
+  if (type == net::USER_CERT)
+    return NetworkCertType::kClientCertificate;
+  if (type == net::CA_CERT)
+    return NetworkCertType::kAuthorityCertificate;
+  VLOG(2) << "Ignoring cert type: " << type;
+  return NetworkCertType::kOther;
+}
+
+// Returns all authority certificats provided by |policy_certificate_provider|
+// as a list of NetworkCerts.
+NetworkCertLoader::NetworkCertList GetPolicyProvidedAuthorities(
+    const PolicyCertificateProvider* policy_certificate_provider,
+    bool device_wide) {
+  NetworkCertLoader::NetworkCertList result;
+  if (!policy_certificate_provider)
+    return result;
+  for (const auto& certificate :
+       policy_certificate_provider->GetAllAuthorityCertificates()) {
+    net::ScopedCERTCertificate x509_cert =
+        net::x509_util::CreateCERTCertificateFromX509Certificate(
+            certificate.get());
+    if (!x509_cert) {
+      LOG(ERROR) << "Unable to create CERTCertificate";
+      continue;
+    }
+    result.push_back(
+        NetworkCertLoader::NetworkCert(std::move(x509_cert), device_wide));
+  }
+  return result;
+}
+
+// Combines all NetworkCerts from all |network_cert_lists| to a resulting list,
+// avoiding duplicates.
+NetworkCertLoader::NetworkCertList CombineNetworkCertLists(
+    std::initializer_list<const NetworkCertLoader::NetworkCertList*>
+        network_cert_lists) {
+  size_t total_size = 0;
+  for (const NetworkCertLoader::NetworkCertList* list : network_cert_lists)
+    total_size += list->size();
+  NetworkCertLoader::NetworkCertList result;
+  result.reserve(total_size);
+  std::set<const CERTCertificate*> already_added_certs;
+  for (const NetworkCertLoader::NetworkCertList* list : network_cert_lists) {
+    for (const NetworkCertLoader::NetworkCert& network_cert : *list) {
+      if (already_added_certs.insert(network_cert.cert()).second)
+        result.push_back(network_cert.Clone());
+    }
+  }
+  return result;
+}
+
+}  // namespace
+
+// Caches certificates from a single slot of a NSSCertDatabase. Handles
+// reloading of certificates on update notifications and provides status flags
+// (loading / loaded). NetworkCertLoader can use multiple CertCaches to combine
+// certificates from multiple sources.
 class NetworkCertLoader::CertCache : public net::CertDatabase::Observer {
  public:
   explicit CertCache(base::RepeatingClosure certificates_updated_callback)
@@ -37,9 +104,14 @@
     net::CertDatabase::GetInstance()->RemoveObserver(this);
   }
 
-  void SetNSSDB(net::NSSCertDatabase* nss_database) {
+  void SetNSSDBAndSlot(net::NSSCertDatabase* nss_database,
+                       crypto::ScopedPK11Slot slot,
+                       bool is_slot_device_wide) {
     CHECK(!nss_database_);
+    CHECK(slot);
     nss_database_ = nss_database;
+    slot_ = std::move(slot);
+    is_slot_device_wide_ = is_slot_device_wide;
 
     // Start observing cert database for changes.
     // Observing net::CertDatabase is preferred over observing |nss_database_|
@@ -61,17 +133,21 @@
     LoadCertificates();
   }
 
-  const net::ScopedCERTCertificateList& cert_list() const { return cert_list_; }
+  const NetworkCertList& authority_certs() const { return authority_certs_; }
+
+  const NetworkCertList& client_certs() const { return client_certs_; }
+
+  bool is_initialized() const { return nss_database_; }
 
   bool initial_load_running() const {
     return nss_database_ && !initial_load_finished_;
   }
 
-  bool initial_load_finished() const { return initial_load_finished_; }
+  bool certificates_update_running() const {
+    return certificates_update_running_;
+  }
 
-  // Returns true if the underlying NSSCertDatabase has access to the system
-  // slot.
-  bool has_system_certificates() const { return has_system_certificates_; }
+  bool initial_load_finished() const { return initial_load_finished_; }
 
  private:
   // Trigger a certificate load. If a certificate loading task is already in
@@ -80,6 +156,9 @@
     DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
     VLOG(1) << "LoadCertificates: " << certificates_update_running_;
 
+    if (!nss_database_)
+      return;
+
     if (certificates_update_running_) {
       certificates_update_required_ = true;
       return;
@@ -88,12 +167,10 @@
     certificates_update_running_ = true;
     certificates_update_required_ = false;
 
-    if (nss_database_) {
-      has_system_certificates_ =
-          static_cast<bool>(nss_database_->GetSystemSlot());
-      nss_database_->ListCerts(base::BindOnce(&CertCache::UpdateCertificates,
-                                              weak_factory_.GetWeakPtr()));
-    }
+    nss_database_->ListCertsInSlot(
+        base::BindOnce(&CertCache::UpdateCertificates,
+                       weak_factory_.GetWeakPtr()),
+        slot_.get());
   }
 
   // Called if a certificate load task is finished.
@@ -102,13 +179,23 @@
     DCHECK(certificates_update_running_);
     VLOG(1) << "UpdateCertificates: " << cert_list.size();
 
-    // Ignore any existing certificates.
-    cert_list_ = std::move(cert_list);
+    authority_certs_.clear();
+    client_certs_.clear();
+    for (auto& cert : cert_list) {
+      NetworkCertType type = GetNetworkCertType(cert.get());
+      if (type == NetworkCertType::kAuthorityCertificate) {
+        authority_certs_.push_back(
+            NetworkCert(std::move(cert), is_slot_device_wide_));
+      } else if (type == NetworkCertType::kClientCertificate) {
+        client_certs_.push_back(
+            NetworkCert(std::move(cert), is_slot_device_wide_));
+      }
+    }
 
     initial_load_finished_ = true;
+    certificates_update_running_ = false;
     certificates_updated_callback_.Run();
 
-    certificates_update_running_ = false;
     if (certificates_update_required_)
       LoadCertificates();
   }
@@ -116,8 +203,6 @@
   // To be called when certificates have been updated.
   base::RepeatingClosure certificates_updated_callback_;
 
-  bool has_system_certificates_ = false;
-
   // This is true after certificates have been loaded initially.
   bool initial_load_finished_ = false;
   // This is true if a notification about certificate DB changes arrived while
@@ -130,8 +215,18 @@
   // The NSS certificate database from which the certificates should be loaded.
   net::NSSCertDatabase* nss_database_ = nullptr;
 
-  // Cached Certificates loaded from the database.
-  net::ScopedCERTCertificateList cert_list_;
+  // The slot from which certificates are listed.
+  crypto::ScopedPK11Slot slot_;
+
+  // true if |slot_| is available device-wide, so certificates listed from it
+  // can be used for shared networks.
+  bool is_slot_device_wide_ = false;
+
+  // Authority Certificates loaded from the database.
+  NetworkCertList authority_certs_;
+
+  // Client Certificates loaded from the database.
+  NetworkCertList client_certs_;
 
   THREAD_CHECKER(thread_checker_);
 
@@ -140,47 +235,22 @@
   DISALLOW_COPY_AND_ASSIGN(CertCache);
 };
 
-namespace {
+NetworkCertLoader::NetworkCert::NetworkCert(net::ScopedCERTCertificate cert,
+                                            bool device_wide)
+    : cert_(std::move(cert)), device_wide_(device_wide) {}
 
-// Goes through all certificates in |certs| and copies those certificates
-// which are on the system slot to a new list.
-net::ScopedCERTCertificateList FilterSystemTokenCertificates(
-    net::ScopedCERTCertificateList certs,
-    const net::NSSCertDatabase* cert_db) {
-  VLOG(1) << "FilterSystemTokenCertificates";
+NetworkCertLoader::NetworkCert::NetworkCert(NetworkCert&& other) = default;
 
-  // Only keep certificates which are on the system slot.
-  certs.erase(
-      std::remove_if(certs.begin(), certs.end(),
-                     [cert_db](const net::ScopedCERTCertificate& cert) {
-                       return !cert_db->IsCertificateOnSystemSlot(cert.get());
-                     }),
-      certs.end());
-  return certs;
+NetworkCertLoader::NetworkCert::~NetworkCert() = default;
+
+NetworkCertLoader::NetworkCert& NetworkCertLoader::NetworkCert::operator=(
+    NetworkCert&& other) = default;
+
+NetworkCertLoader::NetworkCert NetworkCertLoader::NetworkCert::Clone() const {
+  return NetworkCert(net::x509_util::DupCERTCertificate(cert_.get()),
+                     device_wide_);
 }
 
-void AddPolicyProvidedAuthorities(
-    const PolicyCertificateProvider* policy_certificate_provider,
-    net::ScopedCERTCertificateList* out_certs) {
-  DCHECK(out_certs);
-  if (!policy_certificate_provider)
-    return;
-  for (const auto& certificate :
-       policy_certificate_provider->GetAllAuthorityCertificates()) {
-    net::ScopedCERTCertificate x509_cert =
-        net::x509_util::CreateCERTCertificateFromX509Certificate(
-            certificate.get());
-    if (!x509_cert) {
-      LOG(ERROR) << "Unable to create CERTCertificate";
-      continue;
-    }
-
-    out_certs->push_back(std::move(x509_cert));
-  }
-}
-
-}  // namespace
-
 static NetworkCertLoader* g_cert_loader = nullptr;
 static bool g_force_hardware_backed_for_test = false;
 
@@ -209,40 +279,60 @@
 }
 
 NetworkCertLoader::NetworkCertLoader() : weak_factory_(this) {
-  system_cert_cache_ = std::make_unique<CertCache>(base::BindRepeating(
+  system_slot_cert_cache_ = std::make_unique<CertCache>(base::BindRepeating(
       &NetworkCertLoader::OnCertCacheUpdated, base::Unretained(this)));
-  user_cert_cache_ = std::make_unique<CertCache>(base::BindRepeating(
-      &NetworkCertLoader::OnCertCacheUpdated, base::Unretained(this)));
+  user_private_slot_cert_cache_ =
+      std::make_unique<CertCache>(base::BindRepeating(
+          &NetworkCertLoader::OnCertCacheUpdated, base::Unretained(this)));
+  user_public_slot_cert_cache_ =
+      std::make_unique<CertCache>(base::BindRepeating(
+          &NetworkCertLoader::OnCertCacheUpdated, base::Unretained(this)));
 }
 
 NetworkCertLoader::~NetworkCertLoader() {
-  DCHECK(policy_certificate_providers_.empty());
+  DCHECK(!device_policy_certificate_provider_);
+  DCHECK(!user_policy_certificate_provider_);
 }
 
 void NetworkCertLoader::SetSystemNSSDB(
     net::NSSCertDatabase* system_slot_database) {
-  system_cert_cache_->SetNSSDB(system_slot_database);
+  system_slot_cert_cache_->SetNSSDBAndSlot(
+      system_slot_database, system_slot_database->GetSystemSlot(),
+      true /* is_slot_device_wide */);
 }
 
 void NetworkCertLoader::SetUserNSSDB(net::NSSCertDatabase* user_database) {
-  user_cert_cache_->SetNSSDB(user_database);
+  // The private slot can be absent.
+  crypto::ScopedPK11Slot private_slot = user_database->GetPrivateSlot();
+  if (private_slot) {
+    user_private_slot_cert_cache_->SetNSSDBAndSlot(
+        user_database, std::move(private_slot),
+        false /* is_slot_device_wide */);
+  }
+  user_public_slot_cert_cache_->SetNSSDBAndSlot(
+      user_database, user_database->GetPublicSlot(),
+      false /* is_slot_device_wide */);
 }
 
-void NetworkCertLoader::AddPolicyCertificateProvider(
-    PolicyCertificateProvider* policy_certificate_provider) {
-  policy_certificate_provider->AddPolicyProvidedCertsObserver(this);
-  policy_certificate_providers_.push_back(policy_certificate_provider);
+void NetworkCertLoader::SetDevicePolicyCertificateProvider(
+    PolicyCertificateProvider* device_policy_certificate_provider) {
+  if (device_policy_certificate_provider_) {
+    device_policy_certificate_provider_->RemovePolicyProvidedCertsObserver(
+        this);
+  }
+  device_policy_certificate_provider_ = device_policy_certificate_provider;
+  if (device_policy_certificate_provider_)
+    device_policy_certificate_provider_->AddPolicyProvidedCertsObserver(this);
   UpdateCertificates();
 }
 
-void NetworkCertLoader::RemovePolicyCertificateProvider(
-    PolicyCertificateProvider* policy_certificate_provider) {
-  auto iter = std::find(policy_certificate_providers_.begin(),
-                        policy_certificate_providers_.end(),
-                        policy_certificate_provider);
-  DCHECK(iter != policy_certificate_providers_.end());
-  policy_certificate_providers_.erase(iter);
-  policy_certificate_provider->RemovePolicyProvidedCertsObserver(this);
+void NetworkCertLoader::SetUserPolicyCertificateProvider(
+    PolicyCertificateProvider* user_policy_certificate_provider) {
+  if (user_policy_certificate_provider_)
+    user_policy_certificate_provider_->RemovePolicyProvidedCertsObserver(this);
+  user_policy_certificate_provider_ = user_policy_certificate_provider;
+  if (user_policy_certificate_provider_)
+    user_policy_certificate_provider_->AddPolicyProvidedCertsObserver(this);
   UpdateCertificates();
 }
 
@@ -263,17 +353,51 @@
 }
 
 bool NetworkCertLoader::initial_load_of_any_database_running() const {
-  return system_cert_cache_->initial_load_running() ||
-         user_cert_cache_->initial_load_running();
+  return system_slot_cert_cache_->initial_load_running() ||
+         user_private_slot_cert_cache_->initial_load_running() ||
+         user_public_slot_cert_cache_->initial_load_running();
 }
 
 bool NetworkCertLoader::initial_load_finished() const {
-  return system_cert_cache_->initial_load_finished() ||
-         user_cert_cache_->initial_load_finished();
+  return system_slot_cert_cache_->initial_load_finished() ||
+         user_cert_database_load_finished();
 }
 
 bool NetworkCertLoader::user_cert_database_load_finished() const {
-  return user_cert_cache_->initial_load_finished();
+  if (!user_public_slot_cert_cache_->is_initialized())
+    return false;
+
+  // The private slot is optional, so it's possible that the private slot cert
+  // cache is not initialized. In this case, only care about the public slot
+  // cert cache's state.
+  if (!user_private_slot_cert_cache_->is_initialized())
+    return user_public_slot_cert_cache_->initial_load_finished();
+
+  return user_private_slot_cert_cache_->initial_load_finished() &&
+         user_public_slot_cert_cache_->initial_load_finished();
+}
+
+// static
+net::ScopedCERTCertificateList
+NetworkCertLoader::GetAllCertsFromNetworkCertList(
+    const NetworkCertList& network_cert_list) {
+  net::ScopedCERTCertificateList result;
+  result.reserve(network_cert_list.size());
+  for (const NetworkCert& network_cert : network_cert_list) {
+    result.push_back(net::x509_util::DupCERTCertificate(network_cert.cert()));
+  }
+  return result;
+}
+
+// static
+NetworkCertLoader::NetworkCertList NetworkCertLoader::CloneNetworkCertList(
+    const NetworkCertList& network_cert_list) {
+  NetworkCertList result;
+  result.reserve(network_cert_list.size());
+  for (const NetworkCert& network_cert : network_cert_list) {
+    result.push_back(network_cert.Clone());
+  }
+  return result;
 }
 
 // static
@@ -319,54 +443,14 @@
   if (is_shutting_down_)
     return;
 
-  // If user_cert_cache_ has access to system certificates and it has already
-  // finished its initial load, it will contain system certificates which we can
-  // filter.
-  if (user_cert_cache_->initial_load_finished() &&
-      user_cert_cache_->has_system_certificates()) {
-    base::PostTaskWithTraitsAndReplyWithResult(
-        FROM_HERE,
-        {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
-        base::BindOnce(&FilterSystemTokenCertificates,
-                       net::x509_util::DupCERTCertificateList(
-                           user_cert_cache_->cert_list()),
-                       user_cert_cache_->nss_database()),
-        base::BindOnce(&NetworkCertLoader::StoreCertsFromCache,
-                       weak_factory_.GetWeakPtr(),
-                       net::x509_util::DupCERTCertificateList(
-                           user_cert_cache_->cert_list())));
-  } else {
-    // The user's cert cache does not contain system certificates.
-    net::ScopedCERTCertificateList system_token_client_certs =
-        net::x509_util::DupCERTCertificateList(system_cert_cache_->cert_list());
-    net::ScopedCERTCertificateList all_certs_from_cache =
-        net::x509_util::DupCERTCertificateList(user_cert_cache_->cert_list());
-    all_certs_from_cache.reserve(all_certs_from_cache.size() +
-                                 system_token_client_certs.size());
-    for (const net::ScopedCERTCertificate& cert : system_token_client_certs) {
-      all_certs_from_cache.push_back(
-          net::x509_util::DupCERTCertificate(cert.get()));
-    }
-    StoreCertsFromCache(std::move(all_certs_from_cache),
-                        std::move(system_token_client_certs));
+  if (system_slot_cert_cache_->certificates_update_running() ||
+      user_private_slot_cert_cache_->certificates_update_running() ||
+      user_public_slot_cert_cache_->certificates_update_running()) {
+    // Don't spam the observers - wait for the pending updates to be triggered.
+    return;
   }
-}
-
-void NetworkCertLoader::StoreCertsFromCache(
-    net::ScopedCERTCertificateList all_certs_from_cache,
-    net::ScopedCERTCertificateList system_token_client_certs) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  VLOG(1) << "StoreCertsFromCache: " << all_certs_from_cache.size() << " ("
-          << system_token_client_certs.size()
-          << " client certs on system slot)";
-
-  // Ignore any existing certificates.
-  all_certs_from_cache_ = std::move(all_certs_from_cache);
-  system_token_client_certs_ = std::move(system_token_client_certs);
 
   certs_from_cache_loaded_ = true;
-
   UpdateCertificates();
 }
 
@@ -379,40 +463,37 @@
   // Only trigger a notification to observers if one of the |CertCache|s has
   // already loaded certificates. Don't trigger notifications if policy-provided
   // certificates change before that.
-  // TODO(https://crbug.com/888451): When we handle client and authority
+  // TODO(https://crbug.com/888451): Now that we handle client and authority
   // certificates separately in NetworkCertLoader, we could fire different
   // notifications for policy-provided cert changes instead of holding back
-  // notifications. Note that it is possible that only |system_cert_cache_| has
-  // loaded certificates (e.g. on the ChromeOS sign-in screen), and it is also
-  // possible that only |user_cert_cache_| has loaded certificates (e.g. if the
-  // system slot is not available for some reason, but a primary user has signed
-  // in).
+  // notifications.
   if (!certs_from_cache_loaded_)
     return;
 
-  // Copy |all_certs_from_cache_| into |all_certs_|, ignoring any existing
-  // certificates.
-  all_certs_.clear();
-  all_certs_.reserve(all_certs_from_cache_.size());
-  for (const net::ScopedCERTCertificate& cert : all_certs_from_cache_)
-    all_certs_.push_back(net::x509_util::DupCERTCertificate(cert.get()));
+  NetworkCertList user_policy_authorities = GetPolicyProvidedAuthorities(
+      user_policy_certificate_provider_, false /* device_wide */);
+  NetworkCertList device_policy_authorities = GetPolicyProvidedAuthorities(
+      device_policy_certificate_provider_, true /* device_wide */);
+  all_authority_certs_ = CombineNetworkCertLists(
+      {&system_slot_cert_cache_->authority_certs(),
+       &user_public_slot_cert_cache_->authority_certs(),
+       &user_private_slot_cert_cache_->authority_certs(),
+       &user_policy_authorities, &device_policy_authorities});
 
-  // Add policy-provided certificates.
-  // TODO(https://crbug.com/888451): Instead of putting authorities and client
-  // certs into |all_certs_| and then filtering in NetworkCertificateHandler, we
-  // should separate the two categories here in |NetworkCertLoader| already
-  // (pmarko@).
-  for (const PolicyCertificateProvider* policy_certificate_provider :
-       policy_certificate_providers_) {
-    AddPolicyProvidedAuthorities(policy_certificate_provider, &all_certs_);
-  }
+  all_client_certs_ =
+      CombineNetworkCertLists({&system_slot_cert_cache_->client_certs(),
+                               &user_public_slot_cert_cache_->client_certs(),
+                               &user_private_slot_cert_cache_->client_certs()});
 
+  VLOG(1) << "OnCertCacheUpdated (all_authority_certs="
+          << all_authority_certs_.size()
+          << ", all_client_certs=" << all_client_certs_.size() << ")";
   NotifyCertificatesLoaded();
 }
 
 void NetworkCertLoader::NotifyCertificatesLoaded() {
   for (auto& observer : observers_)
-    observer.OnCertificatesLoaded(all_certs_);
+    observer.OnCertificatesLoaded();
 }
 
 void NetworkCertLoader::OnPolicyProvidedCertsChanged(
diff --git a/chromeos/network/network_cert_loader.h b/chromeos/network/network_cert_loader.h
index e0b6afb4..ab7ba9fe 100644
--- a/chromeos/network/network_cert_loader.h
+++ b/chromeos/network/network_cert_loader.h
@@ -40,15 +40,38 @@
  public:
   class Observer {
    public:
-    // Called when the certificates, passed for convenience as |all_certs|,
-    // have completed loading.
-    virtual void OnCertificatesLoaded(
-        const net::ScopedCERTCertificateList& all_certs) = 0;
+    // Called when the certificates have completed loading or have been updated.
+    virtual void OnCertificatesLoaded() = 0;
 
    protected:
     virtual ~Observer() {}
   };
 
+  // Holds a certificate that can be used in network configs along with
+  // additional information.
+  class NetworkCert final {
+   public:
+    NetworkCert(net::ScopedCERTCertificate cert, bool device_wide);
+    NetworkCert(NetworkCert&& other);
+    ~NetworkCert();
+    NetworkCert& operator=(NetworkCert&& other);
+
+    CERTCertificate* cert() const { return cert_.get(); }
+    // Returns true if this certificate is available device-wide (so it can be
+    // used in shared network configs).
+    bool is_device_wide() const { return device_wide_; }
+    NetworkCert Clone() const;
+
+   private:
+    net::ScopedCERTCertificate cert_;
+    bool device_wide_;
+
+    DISALLOW_COPY_AND_ASSIGN(NetworkCert);
+  };
+
+  // A list of NetworkCerts.
+  using NetworkCertList = std::vector<NetworkCert>;
+
   // Sets the global instance. Must be called before any calls to Get().
   static void Initialize();
 
@@ -92,19 +115,17 @@
   // (system and user) databases.
   void SetUserNSSDB(net::NSSCertDatabase* user_database);
 
-  // Adds the passed |PolicyCertificateProvider| and starts using the authority
-  // certificates provided by it. NetworkCertLoader registers itself as Observer
-  // on |policy_certificate_provider|, so the caller must ensure to call
-  // |RemovePolicyCertificateProvider| before |policy_certificate_provider| is
-  // destroyed or before |NetworkCertLoader| is shut down.
-  void AddPolicyCertificateProvider(
-      PolicyCertificateProvider* policy_certificate_provider);
+  // Sets the PolicyCertificateProvider for device policy (its authority
+  // certificates will be available device-wide). Call with nullptr to remove it
+  // again.
+  void SetDevicePolicyCertificateProvider(
+      PolicyCertificateProvider* device_policy_certificate_provider);
 
-  // Removes the passed |PolicyCertificateProvider| and stops using authority
-  // certificates provided by it. |policy_certificate_provider| must have been
-  // added using |AddPolicyCertificateProvider| before.
-  void RemovePolicyCertificateProvider(
-      PolicyCertificateProvider* policy_certificate_provider);
+  // Sets the PolicyCertificateProvider for user policy (its authority
+  // certificates will not be available device-wide). Call with nullptr to
+  // remove it again.
+  void SetUserPolicyCertificateProvider(
+      PolicyCertificateProvider* device_user_certificate_provider);
 
   void AddObserver(NetworkCertLoader::Observer* observer);
   void RemoveObserver(NetworkCertLoader::Observer* observer);
@@ -133,20 +154,29 @@
   // Returns true if certificates from a user NSS database have been loaded.
   bool user_cert_database_load_finished() const;
 
-  // Returns all certificates. This will be empty until certificates_loaded() is
-  // true.
-  const net::ScopedCERTCertificateList& all_certs() const {
+  // Returns authority certificates usable for network configurations. This will
+  // be empty until certificates_loaded() is true.
+  const NetworkCertList& authority_certs() const {
     DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-    return all_certs_;
+    return all_authority_certs_;
   }
 
-  // Returns certificates from the system token. This will be empty until
-  // certificates_loaded() is true.
-  const net::ScopedCERTCertificateList& system_token_client_certs() const {
+  // Returns client certificates usable for network configuration. This will be
+  // empty until certificates_loaded() is true.
+  const NetworkCertList& client_certs() const {
     DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-    return system_token_client_certs_;
+    return all_client_certs_;
   }
 
+  // Returns all certificates from |network_cert_list|, ignoring if they're
+  // device-wide or not.
+  static net::ScopedCERTCertificateList GetAllCertsFromNetworkCertList(
+      const NetworkCertList& network_cert_list);
+
+  // Clones a vector of |NetworkCert|s.
+  static NetworkCertList CloneNetworkCertList(
+      const NetworkCertList& network_cert_list);
+
   // Called in tests if |IsCertificateHardwareBacked()| should always return
   // true.
   static void ForceHardwareBackedForTesting();
@@ -161,13 +191,6 @@
   // potentially changed.
   void OnCertCacheUpdated();
 
-  // Called as a result of |OnCertCacheUpdated|. This is a separate function,
-  // because |OnCertCacheUpdated| may trigger a background task for filtering
-  // certificates.
-  void StoreCertsFromCache(
-      net::ScopedCERTCertificateList all_certs,
-      net::ScopedCERTCertificateList system_token_client_certs);
-
   // Called when policy-provided certificates or cache-based certificates (see
   // |all_certs_from_cache_|) have potentially changed.
   void UpdateCertificates();
@@ -186,24 +209,26 @@
   base::ObserverList<Observer>::Unchecked observers_;
 
   // Cache for certificates from the system-token NSSCertDatabase.
-  std::unique_ptr<CertCache> system_cert_cache_;
-  // Cache for certificates from the user-specific NSSCertDatabase.
-  std::unique_ptr<CertCache> user_cert_cache_;
+  std::unique_ptr<CertCache> system_slot_cert_cache_;
+  // Cache for certificates from the user-specific NSSCertDatabase, listing
+  // certificates from the private slot.
+  std::unique_ptr<CertCache> user_private_slot_cert_cache_;
+  // Cache for certificates from the user-specific NSSCertDatabase, listing
+  // certificates from the public slot.
+  std::unique_ptr<CertCache> user_public_slot_cert_cache_;
 
-  // Cached certificates loaded from the database(s) and policy-pushed Authority
-  // certificates.
-  net::ScopedCERTCertificateList all_certs_;
+  // Client certificates.
+  NetworkCertList all_client_certs_;
 
-  // Cached certificates loaded from the database(s).
-  net::ScopedCERTCertificateList all_certs_from_cache_;
-
-  // Cached certificates from system token.
-  net::ScopedCERTCertificateList system_token_client_certs_;
+  // Authority certs from |cached_certs_| extended by authority certs provided
+  // by the policy certificate providers.
+  NetworkCertList all_authority_certs_;
 
   // True if |StoreCertsFromCache()| was called before.
   bool certs_from_cache_loaded_ = false;
 
-  std::vector<const PolicyCertificateProvider*> policy_certificate_providers_;
+  PolicyCertificateProvider* device_policy_certificate_provider_ = nullptr;
+  PolicyCertificateProvider* user_policy_certificate_provider_ = nullptr;
 
   THREAD_CHECKER(thread_checker_);
 
diff --git a/chromeos/network/network_cert_loader_unittest.cc b/chromeos/network/network_cert_loader_unittest.cc
index 45daaf49..065caf7 100644
--- a/chromeos/network/network_cert_loader_unittest.cc
+++ b/chromeos/network/network_cert_loader_unittest.cc
@@ -79,31 +79,38 @@
   net::CertificateList authority_certificates_;
 };
 
-bool IsCertInCertificateList(CERTCertificate* cert,
-                             const net::ScopedCERTCertificateList& cert_list) {
-  for (const auto& cert_list_element : cert_list) {
-    if (net::x509_util::IsSameCertificate(cert_list_element.get(), cert))
+bool IsCertInCertificateList(
+    CERTCertificate* cert,
+    bool device_wide,
+    const std::vector<NetworkCertLoader::NetworkCert>& network_cert_list) {
+  for (const auto& network_cert : network_cert_list) {
+    if (device_wide == network_cert.is_device_wide() &&
+        net::x509_util::IsSameCertificate(network_cert.cert(), cert)) {
       return true;
+    }
   }
   return false;
 }
 
-bool IsCertInCertificateList(const net::X509Certificate* cert,
-                             const net::ScopedCERTCertificateList& cert_list) {
-  for (const auto& cert_list_element : cert_list) {
-    if (net::x509_util::IsSameCertificate(cert_list_element.get(), cert))
+bool IsCertInCertificateList(
+    const net::X509Certificate* cert,
+    bool device_wide,
+    const std::vector<NetworkCertLoader::NetworkCert>& network_cert_list) {
+  for (const auto& network_cert : network_cert_list) {
+    if (device_wide == network_cert.is_device_wide() &&
+        net::x509_util::IsSameCertificate(network_cert.cert(), cert)) {
       return true;
+    }
   }
   return false;
 }
 
 size_t CountCertOccurencesInCertificateList(
     CERTCertificate* cert,
-    const net::ScopedCERTCertificateList& cert_list) {
+    const std::vector<NetworkCertLoader::NetworkCert>& network_cert_list) {
   size_t count = 0;
-  for (net::ScopedCERTCertificateList::const_iterator it = cert_list.begin();
-       it != cert_list.end(); ++it) {
-    if (net::x509_util::IsSameCertificate(it->get(), cert))
+  for (const auto& network_cert : network_cert_list) {
+    if (net::x509_util::IsSameCertificate(network_cert.cert(), cert))
       ++count;
   }
   return count;
@@ -144,7 +151,8 @@
   ~NetworkCertLoaderTest() override = default;
 
   void SetUp() override {
-    ASSERT_TRUE(primary_db_.is_open());
+    ASSERT_TRUE(primary_public_slot_db_.is_open());
+    ASSERT_TRUE(primary_private_slot_db_.is_open());
 
     NetworkCertLoader::Initialize();
     cert_loader_ = NetworkCertLoader::Get();
@@ -157,19 +165,12 @@
   }
 
  protected:
+  // Initializes |primary_certdb_| as a NSSCertDatabse based on
+  // |primary_public_slot_db| and |primary_private_slot_db| and starts the
+  // NetworkCertLoader with it.
   void StartCertLoaderWithPrimaryDB() {
-    CreateCertDatabase(&primary_db_, &primary_certdb_);
-    cert_loader_->SetUserNSSDB(primary_certdb_.get());
-
-    scoped_task_environment_.RunUntilIdle();
-    GetAndResetCertificatesLoadedEventsCount();
-  }
-
-  // Starts the cert loader with a primary cert database which has access to the
-  // system token.
-  void StartCertLoaderWithPrimaryDBAndSystemToken() {
-    CreateCertDatabase(&primary_db_, &primary_certdb_);
-    AddSystemToken(primary_certdb_.get());
+    CreateCertDatabase(&primary_public_slot_db_, &primary_private_slot_db_,
+                       &primary_certdb_);
     cert_loader_->SetUserNSSDB(primary_certdb_.get());
 
     scoped_task_environment_.RunUntilIdle();
@@ -178,8 +179,7 @@
 
   // NetworkCertLoader::Observer:
   // The test keeps count of times the observer method was called.
-  void OnCertificatesLoaded(
-      const net::ScopedCERTCertificateList& cert_list) override {
+  void OnCertificatesLoaded() override {
     EXPECT_TRUE(certificates_loaded_events_count_ == 0);
     certificates_loaded_events_count_++;
   }
@@ -192,13 +192,24 @@
     return result;
   }
 
-  void CreateCertDatabase(crypto::ScopedTestNSSDB* db,
+  // Creates a TestNSSCertDatabase in *|certdb|, using the (mandatory)
+  // |public_slot_db| for the public slot and the (optional) |private_slot_db|
+  // as the private slot.
+  void CreateCertDatabase(crypto::ScopedTestNSSDB* public_slot_db,
+                          crypto::ScopedTestNSSDB* private_slot_db,
                           std::unique_ptr<TestNSSCertDatabase>* certdb) {
-    ASSERT_TRUE(db->is_open());
+    ASSERT_TRUE(public_slot_db && public_slot_db->is_open());
 
-    certdb->reset(new TestNSSCertDatabase(
-        crypto::ScopedPK11Slot(PK11_ReferenceSlot(db->slot())),
-        crypto::ScopedPK11Slot(PK11_ReferenceSlot(db->slot()))));
+    crypto::ScopedPK11Slot scoped_public_slot(
+        PK11_ReferenceSlot(public_slot_db->slot()));
+    crypto::ScopedPK11Slot scoped_private_slot;
+    if (private_slot_db) {
+      ASSERT_TRUE(private_slot_db->is_open());
+      scoped_private_slot =
+          crypto::ScopedPK11Slot(PK11_ReferenceSlot(private_slot_db->slot()));
+    }
+    *certdb = std::make_unique<TestNSSCertDatabase>(
+        std::move(scoped_public_slot), std::move(scoped_private_slot));
   }
 
   void ImportCACert(const std::string& cert_file,
@@ -261,10 +272,10 @@
 
   NetworkCertLoader* cert_loader_;
 
-  // The user is primary as the one whose certificates NetworkCertLoader
-  // handles, it has nothing to do with crypto::InitializeNSSForChromeOSUser
-  // is_primary_user parameter (which is irrelevant for these tests).
-  crypto::ScopedTestNSSDB primary_db_;
+  // The NSSCertDatabse and underlying slots for the primary user (because
+  // NetworkCertLoader uses device-wide certs and primary user's certs).
+  crypto::ScopedTestNSSDB primary_private_slot_db_;
+  crypto::ScopedTestNSSDB primary_public_slot_db_;
   std::unique_ptr<TestNSSCertDatabase> primary_certdb_;
 
   // Additional NSS DB simulating the system token.
@@ -285,14 +296,19 @@
   EXPECT_FALSE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
 
-  CreateCertDatabase(&primary_db_, &primary_certdb_);
+  CreateCertDatabase(&primary_public_slot_db_, &primary_private_slot_db_,
+                     &primary_certdb_);
+  net::ScopedCERTCertificateList certs;
+  ImportCACert("root_ca_cert.pem", primary_certdb_.get(), &certs);
+  scoped_task_environment_.RunUntilIdle();
+
   cert_loader_->SetUserNSSDB(primary_certdb_.get());
 
   EXPECT_FALSE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
   EXPECT_TRUE(cert_loader_->initial_load_of_any_database_running());
-  EXPECT_TRUE(cert_loader_->all_certs().empty());
-  EXPECT_TRUE(cert_loader_->system_token_client_certs().empty());
+  EXPECT_TRUE(cert_loader_->authority_certs().empty());
+  EXPECT_TRUE(cert_loader_->client_certs().empty());
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
@@ -302,9 +318,10 @@
   EXPECT_TRUE(cert_loader_->user_cert_database_load_finished());
   EXPECT_FALSE(cert_loader_->initial_load_of_any_database_running());
 
-  // Default CA cert roots should get loaded.
-  EXPECT_FALSE(cert_loader_->all_certs().empty());
-  EXPECT_TRUE(cert_loader_->system_token_client_certs().empty());
+  // Default CA cert roots should get loaded but not be available in
+  // NetworkCertLoader.
+  EXPECT_EQ(1U, cert_loader_->authority_certs().size());
+  EXPECT_TRUE(cert_loader_->client_certs().empty());
 }
 
 TEST_F(NetworkCertLoaderTest, BasicOnlySystemDB) {
@@ -312,13 +329,19 @@
   EXPECT_FALSE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
 
-  CreateCertDatabase(&system_db_, &system_certdb_);
+  CreateCertDatabase(&system_db_, nullptr /* private_slot_db */,
+                     &system_certdb_);
+  AddSystemToken(system_certdb_.get());
+  net::ScopedCERTCertificateList certs;
+  ImportCACert("root_ca_cert.pem", system_certdb_.get(), &certs);
+  scoped_task_environment_.RunUntilIdle();
+
   cert_loader_->SetSystemNSSDB(system_certdb_.get());
 
   EXPECT_FALSE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
-  EXPECT_TRUE(cert_loader_->initial_load_of_any_database_running());
-  EXPECT_TRUE(cert_loader_->all_certs().empty());
+  EXPECT_TRUE(cert_loader_->authority_certs().empty());
+  EXPECT_TRUE(cert_loader_->client_certs().empty());
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
@@ -328,21 +351,27 @@
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
   EXPECT_FALSE(cert_loader_->initial_load_of_any_database_running());
 
-  // Default CA cert roots should get loaded.
-  EXPECT_FALSE(cert_loader_->all_certs().empty());
+  // Default CA cert roots should get loaded, but not be exposed through
+  // NetworkCertLoader.
+  EXPECT_EQ(1U, cert_loader_->authority_certs().size());
+  EXPECT_TRUE(cert_loader_->client_certs().empty());
 }
 
 // Tests the NetworkCertLoader with a system DB and then with an additional user
 // DB which does not have access to the system token.
 TEST_F(NetworkCertLoaderTest, SystemAndUnaffiliatedUserDB) {
-  CreateCertDatabase(&system_db_, &system_certdb_);
+  CreateCertDatabase(&system_db_, nullptr /* private_slot_db */,
+                     &system_certdb_);
+  AddSystemToken(system_certdb_.get());
   net::ScopedCERTCertificate system_token_cert(ImportClientCertAndKey(
       system_certdb_.get(), system_db_.slot(), TEST_CLIENT_CERT_1));
   ASSERT_TRUE(system_token_cert);
 
-  CreateCertDatabase(&primary_db_, &primary_certdb_);
+  CreateCertDatabase(&primary_public_slot_db_, &primary_private_slot_db_,
+                     &primary_certdb_);
   net::ScopedCERTCertificate user_token_cert(ImportClientCertAndKey(
-      primary_certdb_.get(), primary_db_.slot(), TEST_CLIENT_CERT_2));
+      primary_certdb_.get(), primary_private_slot_db_.slot(),
+      TEST_CLIENT_CERT_2));
   ASSERT_TRUE(user_token_cert);
 
   scoped_task_environment_.RunUntilIdle();
@@ -356,8 +385,7 @@
   EXPECT_FALSE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
   EXPECT_TRUE(cert_loader_->initial_load_of_any_database_running());
-  EXPECT_TRUE(cert_loader_->all_certs().empty());
-  EXPECT_TRUE(cert_loader_->system_token_client_certs().empty());
+  EXPECT_TRUE(cert_loader_->client_certs().empty());
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
@@ -366,19 +394,17 @@
   EXPECT_TRUE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
   EXPECT_FALSE(cert_loader_->initial_load_of_any_database_running());
+  EXPECT_EQ(1U, cert_loader_->client_certs().size());
 
-  EXPECT_TRUE(IsCertInCertificateList(
-      system_token_cert.get(), cert_loader_->system_token_client_certs()));
   EXPECT_TRUE(IsCertInCertificateList(system_token_cert.get(),
-                                      cert_loader_->all_certs()));
+                                      true /* device_wide */,
+                                      cert_loader_->client_certs()));
 
   cert_loader_->SetUserNSSDB(primary_certdb_.get());
 
   EXPECT_TRUE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
   EXPECT_TRUE(cert_loader_->initial_load_of_any_database_running());
-  EXPECT_FALSE(cert_loader_->all_certs().empty());
-  EXPECT_FALSE(cert_loader_->system_token_client_certs().empty());
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
@@ -387,24 +413,31 @@
   EXPECT_TRUE(cert_loader_->initial_load_finished());
   EXPECT_TRUE(cert_loader_->user_cert_database_load_finished());
   EXPECT_FALSE(cert_loader_->initial_load_of_any_database_running());
+  EXPECT_EQ(2U, cert_loader_->client_certs().size());
 
-  EXPECT_FALSE(IsCertInCertificateList(
-      user_token_cert.get(), cert_loader_->system_token_client_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(user_token_cert.get(),
+                                       true /* device_wide */,
+                                       cert_loader_->client_certs()));
   EXPECT_TRUE(IsCertInCertificateList(user_token_cert.get(),
-                                      cert_loader_->all_certs()));
+                                      false /* device_wide */,
+                                      cert_loader_->client_certs()));
 }
 
 // Tests the NetworkCertLoader with a system DB and then with an additional user
 // DB which has access to the system token.
 TEST_F(NetworkCertLoaderTest, SystemAndAffiliatedUserDB) {
-  CreateCertDatabase(&system_db_, &system_certdb_);
+  CreateCertDatabase(&system_db_, nullptr /* private_slot_db */,
+                     &system_certdb_);
+  AddSystemToken(system_certdb_.get());
   net::ScopedCERTCertificate system_token_cert(ImportClientCertAndKey(
       system_certdb_.get(), system_db_.slot(), TEST_CLIENT_CERT_1));
   ASSERT_TRUE(system_token_cert);
 
-  CreateCertDatabase(&primary_db_, &primary_certdb_);
+  CreateCertDatabase(&primary_public_slot_db_, &primary_private_slot_db_,
+                     &primary_certdb_);
   net::ScopedCERTCertificate user_token_cert(ImportClientCertAndKey(
-      primary_certdb_.get(), primary_db_.slot(), TEST_CLIENT_CERT_2));
+      primary_certdb_.get(), primary_private_slot_db_.slot(),
+      TEST_CLIENT_CERT_2));
   ASSERT_TRUE(user_token_cert);
 
   AddSystemToken(primary_certdb_.get());
@@ -419,8 +452,7 @@
   EXPECT_FALSE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
   EXPECT_TRUE(cert_loader_->initial_load_of_any_database_running());
-  EXPECT_TRUE(cert_loader_->all_certs().empty());
-  EXPECT_TRUE(cert_loader_->system_token_client_certs().empty());
+  EXPECT_TRUE(cert_loader_->client_certs().empty());
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
@@ -429,19 +461,17 @@
   EXPECT_TRUE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
   EXPECT_FALSE(cert_loader_->initial_load_of_any_database_running());
+  EXPECT_EQ(1U, cert_loader_->client_certs().size());
 
-  EXPECT_TRUE(IsCertInCertificateList(
-      system_token_cert.get(), cert_loader_->system_token_client_certs()));
   EXPECT_TRUE(IsCertInCertificateList(system_token_cert.get(),
-                                      cert_loader_->all_certs()));
+                                      true /* device_wide */,
+                                      cert_loader_->client_certs()));
 
   cert_loader_->SetUserNSSDB(primary_certdb_.get());
 
   EXPECT_TRUE(cert_loader_->initial_load_finished());
   EXPECT_FALSE(cert_loader_->user_cert_database_load_finished());
   EXPECT_TRUE(cert_loader_->initial_load_of_any_database_running());
-  EXPECT_FALSE(cert_loader_->all_certs().empty());
-  EXPECT_FALSE(cert_loader_->system_token_client_certs().empty());
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
@@ -450,11 +480,41 @@
   EXPECT_TRUE(cert_loader_->initial_load_finished());
   EXPECT_TRUE(cert_loader_->user_cert_database_load_finished());
   EXPECT_FALSE(cert_loader_->initial_load_of_any_database_running());
+  EXPECT_EQ(2U, cert_loader_->client_certs().size());
 
-  EXPECT_FALSE(IsCertInCertificateList(
-      user_token_cert.get(), cert_loader_->system_token_client_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(user_token_cert.get(),
+                                       true /* device_wide */,
+                                       cert_loader_->client_certs()));
+  EXPECT_TRUE(IsCertInCertificateList(user_token_cert.get(),
+                                      false /* device_wide */,
+                                      cert_loader_->client_certs()));
   EXPECT_EQ(1U, CountCertOccurencesInCertificateList(
-                    user_token_cert.get(), cert_loader_->all_certs()));
+                    user_token_cert.get(), cert_loader_->client_certs()));
+}
+
+// Tests that NetworkCertLoader does not list certs twice if they appear on
+// multiple slots.
+TEST_F(NetworkCertLoaderTest, DeduplicatesCerts) {
+  // Use the same slot as public and private slot.
+  crypto::ScopedTestNSSDB* single_slot_db = &primary_public_slot_db_;
+  CreateCertDatabase(single_slot_db /* public_slot_db */,
+                     single_slot_db /* private_slot_db */, &primary_certdb_);
+  net::ScopedCERTCertificateList certs;
+  ImportCACert("root_ca_cert.pem", primary_certdb_.get(), &certs);
+  scoped_task_environment_.RunUntilIdle();
+
+  cert_loader_->SetUserNSSDB(primary_certdb_.get());
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
+
+  EXPECT_TRUE(cert_loader_->initial_load_finished());
+  EXPECT_TRUE(cert_loader_->user_cert_database_load_finished());
+  EXPECT_FALSE(cert_loader_->initial_load_of_any_database_running());
+
+  // Default CA cert roots should get loaded but not be available in
+  // NetworkCertLoader.
+  EXPECT_EQ(1U, cert_loader_->authority_certs().size());
+  EXPECT_TRUE(cert_loader_->client_certs().empty());
 }
 
 TEST_F(NetworkCertLoaderTest, UpdateCertListOnNewCert) {
@@ -465,16 +525,16 @@
 
   // Certs are loaded asynchronously, so the new cert should not yet be in the
   // cert list.
-  EXPECT_FALSE(
-      IsCertInCertificateList(certs[0].get(), cert_loader_->all_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(certs[0].get(), false /* device_wide */,
+                                       cert_loader_->client_certs()));
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
   EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 
   // The certificate list should be updated now, as the message loop's been run.
-  EXPECT_TRUE(
-      IsCertInCertificateList(certs[0].get(), cert_loader_->all_certs()));
+  EXPECT_TRUE(IsCertInCertificateList(certs[0].get(), false /* device_wide */,
+                                      cert_loader_->authority_certs()));
 
   EXPECT_FALSE(cert_loader_->IsCertificateHardwareBacked(certs[0].get()));
 }
@@ -484,15 +544,18 @@
   std::unique_ptr<TestNSSCertDatabase> secondary_certdb;
 
   StartCertLoaderWithPrimaryDB();
-  CreateCertDatabase(&secondary_db, &secondary_certdb);
+  CreateCertDatabase(&secondary_db /* public_slot_db */,
+                     &secondary_db /* private_slot_db */, &secondary_certdb);
 
   net::ScopedCERTCertificateList certs;
   ImportCACert("root_ca_cert.pem", secondary_certdb.get(), &certs);
 
   scoped_task_environment_.RunUntilIdle();
 
-  EXPECT_FALSE(
-      IsCertInCertificateList(certs[0].get(), cert_loader_->all_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(certs[0].get(), false /* device_wide */,
+                                       cert_loader_->client_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(certs[0].get(), true /* device_wide */,
+                                       cert_loader_->client_certs()));
 }
 
 TEST_F(NetworkCertLoaderTest, ClientLoaderUpdateOnNewClientCert) {
@@ -506,25 +569,32 @@
   scoped_task_environment_.RunUntilIdle();
   EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 
-  EXPECT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_TRUE(IsCertInCertificateList(cert.get(), false /* device_wide */,
+                                      cert_loader_->client_certs()));
 }
 
 TEST_F(NetworkCertLoaderTest, ClientLoaderUpdateOnNewClientCertInSystemToken) {
-  StartCertLoaderWithPrimaryDBAndSystemToken();
+  CreateCertDatabase(&system_db_ /* public_slot_db */,
+                     nullptr /* private_slot_db */, &system_certdb_);
+  AddSystemToken(system_certdb_.get());
+  scoped_task_environment_.RunUntilIdle();
 
-  EXPECT_TRUE(cert_loader_->system_token_client_certs().empty());
+  cert_loader_->SetSystemNSSDB(system_certdb_.get());
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
+
+  EXPECT_TRUE(cert_loader_->client_certs().empty());
   net::ScopedCERTCertificate cert(ImportClientCertAndKey(
-      primary_certdb_.get(), primary_certdb_->GetSystemSlot().get()));
+      system_certdb_.get(), system_certdb_->GetSystemSlot().get()));
   ASSERT_TRUE(cert);
 
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
   scoped_task_environment_.RunUntilIdle();
   EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 
-  EXPECT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
-  EXPECT_EQ(1U, cert_loader_->system_token_client_certs().size());
-  EXPECT_TRUE(IsCertInCertificateList(
-      cert.get(), cert_loader_->system_token_client_certs()));
+  EXPECT_EQ(1U, cert_loader_->client_certs().size());
+  EXPECT_TRUE(IsCertInCertificateList(cert.get(), true /* device_wide */,
+                                      cert_loader_->client_certs()));
 }
 
 TEST_F(NetworkCertLoaderTest, NoUpdateOnNewClientCertInSecondaryDb) {
@@ -532,7 +602,8 @@
   std::unique_ptr<TestNSSCertDatabase> secondary_certdb;
 
   StartCertLoaderWithPrimaryDB();
-  CreateCertDatabase(&secondary_db, &secondary_certdb);
+  CreateCertDatabase(&secondary_db /* public_slot_db */,
+                     &secondary_db /* private_slot_db */, &secondary_certdb);
 
   net::ScopedCERTCertificate cert(
       ImportClientCertAndKey(secondary_certdb.get()));
@@ -540,7 +611,10 @@
 
   scoped_task_environment_.RunUntilIdle();
 
-  EXPECT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(cert.get(), false /* device_wide */,
+                                       cert_loader_->client_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(cert.get(), true /* device_wide */,
+                                       cert_loader_->client_certs()));
 }
 
 TEST_F(NetworkCertLoaderTest, UpdatedOnCertRemoval) {
@@ -553,7 +627,8 @@
   scoped_task_environment_.RunUntilIdle();
 
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
-  ASSERT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  ASSERT_TRUE(IsCertInCertificateList(cert.get(), false /* device_wide */,
+                                      cert_loader_->client_certs()));
 
   primary_certdb_->DeleteCertAndKey(cert.get());
 
@@ -561,7 +636,8 @@
   scoped_task_environment_.RunUntilIdle();
   EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 
-  ASSERT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  ASSERT_FALSE(IsCertInCertificateList(cert.get(), false /* device_wide */,
+                                       cert_loader_->client_certs()));
 }
 
 TEST_F(NetworkCertLoaderTest, UpdatedOnCACertTrustChange) {
@@ -572,8 +648,8 @@
 
   scoped_task_environment_.RunUntilIdle();
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
-  ASSERT_TRUE(
-      IsCertInCertificateList(certs[0].get(), cert_loader_->all_certs()));
+  ASSERT_TRUE(IsCertInCertificateList(certs[0].get(), false /* device_wide */,
+                                      cert_loader_->authority_certs()));
 
   // The value that should have been set by |ImportCACert|.
   ASSERT_EQ(net::NSSCertDatabase::TRUST_DEFAULT,
@@ -597,20 +673,24 @@
   FakePolicyCertificateProvider device_policy_certs_provider;
 
   // Setting the cert provider triggers an update.
-  cert_loader_->AddPolicyCertificateProvider(&device_policy_certs_provider);
+  cert_loader_->SetDevicePolicyCertificateProvider(
+      &device_policy_certs_provider);
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 
   // When policy changes, an update is triggered too.
-  EXPECT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(cert.get(), true /* device_wide */,
+                                       cert_loader_->authority_certs()));
   device_policy_certs_provider.SetAuthorityCertificates({cert});
   device_policy_certs_provider.NotifyObservers();
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
-  EXPECT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_TRUE(IsCertInCertificateList(cert.get(), true /* device_wide */,
+                                      cert_loader_->authority_certs()));
 
   // Removing the cert provider triggers an update.
-  cert_loader_->RemovePolicyCertificateProvider(&device_policy_certs_provider);
+  cert_loader_->SetDevicePolicyCertificateProvider(nullptr);
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
-  EXPECT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(cert.get(), true /* device_wide */,
+                                       cert_loader_->authority_certs()));
 }
 
 TEST_F(NetworkCertLoaderTest, UpdateOnTwoPolicyCertificateProviders) {
@@ -631,27 +711,32 @@
   FakePolicyCertificateProvider user_policy_certs_provider;
   user_policy_certs_provider.SetAuthorityCertificates({user_policy_cert});
 
-  // Adding a first policy certificate provider triggers an update. In this test
-  // case, the device policy certs provider already contains a cert.
-  cert_loader_->AddPolicyCertificateProvider(&device_policy_certs_provider);
+  // Adding a device policy certificate provider triggers an update. In this
+  // test case, the device policy certs provider already contains a cert.
+  cert_loader_->SetDevicePolicyCertificateProvider(
+      &device_policy_certs_provider);
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
   EXPECT_TRUE(IsCertInCertificateList(device_policy_cert.get(),
-                                      cert_loader_->all_certs()));
+                                      true /* device_wide */,
+                                      cert_loader_->authority_certs()));
   EXPECT_FALSE(IsCertInCertificateList(user_policy_cert.get(),
-                                       cert_loader_->all_certs()));
+                                       false /* device_wide */,
+                                       cert_loader_->authority_certs()));
 
-  // Adding a second policy certificate provider triggers an update. In this
+  // Adding a user policy certificate provider triggers an update. In this
   // test case, the user policy certs provider already contains a cert.
-  cert_loader_->AddPolicyCertificateProvider(&user_policy_certs_provider);
+  cert_loader_->SetUserPolicyCertificateProvider(&user_policy_certs_provider);
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
   EXPECT_TRUE(IsCertInCertificateList(device_policy_cert.get(),
-                                      cert_loader_->all_certs()));
+                                      true /* device_wide */,
+                                      cert_loader_->authority_certs()));
   EXPECT_TRUE(IsCertInCertificateList(user_policy_cert.get(),
-                                      cert_loader_->all_certs()));
+                                      false /* device_wide */,
+                                      cert_loader_->authority_certs()));
 
-  cert_loader_->RemovePolicyCertificateProvider(&user_policy_certs_provider);
+  cert_loader_->SetDevicePolicyCertificateProvider(nullptr);
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
-  cert_loader_->RemovePolicyCertificateProvider(&device_policy_certs_provider);
+  cert_loader_->SetUserPolicyCertificateProvider(nullptr);
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 }
 
@@ -666,23 +751,27 @@
 
   // Setting the cert provider does not trigger an update yet, because the
   // NetworkCertLoader has not been set to use a system or user NSS Database.
-  cert_loader_->AddPolicyCertificateProvider(&device_policy_certs_provider);
+  cert_loader_->SetDevicePolicyCertificateProvider(
+      &device_policy_certs_provider);
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
 
   // Same when the policy changes.
-  EXPECT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(cert.get(), true /* device_wide */,
+                                       cert_loader_->authority_certs()));
   device_policy_certs_provider.SetAuthorityCertificates({cert});
   device_policy_certs_provider.NotifyObservers();
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
 
   // After starting the NetworkCertLoader, the policy-provided cert is there.
   StartCertLoaderWithPrimaryDB();
-  EXPECT_TRUE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_TRUE(IsCertInCertificateList(cert.get(), true /* device_wide */,
+                                      cert_loader_->authority_certs()));
 
   // Removing the cert provider triggers an update.
-  cert_loader_->RemovePolicyCertificateProvider(&device_policy_certs_provider);
+  cert_loader_->SetDevicePolicyCertificateProvider(nullptr);
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
-  EXPECT_FALSE(IsCertInCertificateList(cert.get(), cert_loader_->all_certs()));
+  EXPECT_FALSE(IsCertInCertificateList(cert.get(), true /* device_wide */,
+                                       cert_loader_->authority_certs()));
 }
 
 TEST_F(NetworkCertLoaderTest, NoUpdateWhenShuttingDown) {
@@ -691,13 +780,14 @@
   FakePolicyCertificateProvider device_policy_certs_provider;
 
   // Setting the cert provider triggers an update.
-  cert_loader_->AddPolicyCertificateProvider(&device_policy_certs_provider);
+  cert_loader_->SetDevicePolicyCertificateProvider(
+      &device_policy_certs_provider);
   ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
 
   // Removing the cert provider does not trigger an update if the shutdown
   // procedure has started.
   cert_loader_->set_is_shutting_down();
-  cert_loader_->RemovePolicyCertificateProvider(&device_policy_certs_provider);
+  cert_loader_->SetDevicePolicyCertificateProvider(nullptr);
   ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
 }
 
diff --git a/chromeos/network/network_cert_migrator.cc b/chromeos/network/network_cert_migrator.cc
index 4af79fc..be3ea49 100644
--- a/chromeos/network/network_cert_migrator.cc
+++ b/chromeos/network/network_cert_migrator.cc
@@ -6,6 +6,7 @@
 
 #include <cert.h>
 #include <string>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -37,10 +38,9 @@
 class NetworkCertMigrator::MigrationTask
     : public base::RefCounted<MigrationTask> {
  public:
-  MigrationTask(const net::ScopedCERTCertificateList& certs,
+  MigrationTask(net::ScopedCERTCertificateList certs,
                 const base::WeakPtr<NetworkCertMigrator>& cert_migrator)
-      : certs_(net::x509_util::DupCERTCertificateList(certs)),
-        cert_migrator_(cert_migrator) {}
+      : certs_(std::move(certs)), cert_migrator_(cert_migrator) {}
 
   void Run(const NetworkStateHandler::NetworkStateList& networks) {
     // Request properties for each network that could be configured with a
@@ -203,8 +203,10 @@
   // Run the migration process to fix missing or incorrect slot ids of client
   // certificates.
   VLOG(2) << "Start certificate migration of network configurations.";
-  scoped_refptr<MigrationTask> helper(new MigrationTask(
-      NetworkCertLoader::Get()->all_certs(), weak_ptr_factory_.GetWeakPtr()));
+  scoped_refptr<MigrationTask> helper(base::MakeRefCounted<MigrationTask>(
+      NetworkCertLoader::GetAllCertsFromNetworkCertList(
+          NetworkCertLoader::Get()->client_certs()),
+      weak_ptr_factory_.GetWeakPtr()));
   NetworkStateHandler::NetworkStateList networks;
   network_state_handler_->GetNetworkListByType(
       NetworkTypePattern::Default(),
@@ -215,8 +217,7 @@
   helper->Run(networks);
 }
 
-void NetworkCertMigrator::OnCertificatesLoaded(
-    const net::ScopedCERTCertificateList& cert_list) {
+void NetworkCertMigrator::OnCertificatesLoaded() {
   NetworkListChanged();
 }
 
diff --git a/chromeos/network/network_cert_migrator.h b/chromeos/network/network_cert_migrator.h
index c766327a..cb28411 100644
--- a/chromeos/network/network_cert_migrator.h
+++ b/chromeos/network/network_cert_migrator.h
@@ -35,8 +35,7 @@
   void NetworkListChanged() override;
 
   // NetworkCertLoader::Observer overrides
-  void OnCertificatesLoaded(
-      const net::ScopedCERTCertificateList& cert_list) override;
+  void OnCertificatesLoaded() override;
 
   // Unowned associated NetworkStateHandler* (global or test instance).
   NetworkStateHandler* network_state_handler_;
diff --git a/chromeos/network/network_cert_migrator_unittest.cc b/chromeos/network/network_cert_migrator_unittest.cc
index 8d9a45da..e433e0dd 100644
--- a/chromeos/network/network_cert_migrator_unittest.cc
+++ b/chromeos/network/network_cert_migrator_unittest.cc
@@ -50,13 +50,19 @@
   void SetUp() override {
     ASSERT_TRUE(test_system_nssdb_.is_open());
     ASSERT_TRUE(test_user_nssdb_.is_open());
-    // Use the same DB for public and private slot.
-    test_system_nsscertdb_.reset(new net::NSSCertDatabaseChromeOS(
-        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())),
-        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot()))));
-    test_user_nsscertdb_.reset(new net::NSSCertDatabaseChromeOS(
+    // Use the same slot as public and private slot for the user's
+    // NSSCertDatabse for testing.
+    test_user_nsscertdb_ = std::make_unique<net::NSSCertDatabaseChromeOS>(
         crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_user_nssdb_.slot())),
-        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_user_nssdb_.slot()))));
+        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_user_nssdb_.slot())));
+    // Create a NSSCertDatabase for the system slot. While NetworkCertLoader
+    // does not care about the public slot in this database, NSSCertDatabase
+    // requires a public slot. Pass the system slot there for testing.
+    test_system_nsscertdb_ = std::make_unique<net::NSSCertDatabaseChromeOS>(
+        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())),
+        crypto::ScopedPK11Slot() /* private_slot */);
+    test_system_nsscertdb_->SetSystemSlot(
+        crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_system_nssdb_.slot())));
 
     DBusThreadManager::Initialize();
     service_test_ =
diff --git a/chromeos/network/network_certificate_handler.cc b/chromeos/network/network_certificate_handler.cc
index 3c41196..1a483e9 100644
--- a/chromeos/network/network_certificate_handler.cc
+++ b/chromeos/network/network_certificate_handler.cc
@@ -14,11 +14,9 @@
 
 namespace {
 
-// Root CA certificates that are built into Chrome use this token name.
-const char kRootCertificateTokenName[] = "Builtin Object Token";
-
 NetworkCertificateHandler::Certificate GetCertificate(CERTCertificate* cert,
-                                                      net::CertType type) {
+                                                      net::CertType type,
+                                                      bool is_device_wide) {
   NetworkCertificateHandler::Certificate result;
 
   result.hash =
@@ -44,6 +42,8 @@
 
   result.hardware_backed = NetworkCertLoader::IsCertificateHardwareBacked(cert);
 
+  // TODO(https://crbug.com/904362): Forward is_device_wide to the UI.
+
   return result;
 }
 
@@ -59,7 +59,7 @@
 NetworkCertificateHandler::NetworkCertificateHandler() {
   NetworkCertLoader::Get()->AddObserver(this);
   if (NetworkCertLoader::Get()->initial_load_finished())
-    OnCertificatesLoaded(NetworkCertLoader::Get()->all_certs());
+    OnCertificatesLoaded();
 }
 
 NetworkCertificateHandler::~NetworkCertificateHandler() {
@@ -76,50 +76,37 @@
   observer_list_.RemoveObserver(observer);
 }
 
-void NetworkCertificateHandler::OnCertificatesLoaded(
-    const net::ScopedCERTCertificateList& cert_list) {
-  ProcessCertificates(cert_list);
-}
-
-void NetworkCertificateHandler::ProcessCertificates(
-    const net::ScopedCERTCertificateList& cert_list) {
-  user_certificates_.clear();
-  server_ca_certificates_.clear();
-
-  // Add certificates to the appropriate list.
-  for (const auto& cert_ref : cert_list) {
-    CERTCertificate* cert = cert_ref.get();
-    net::CertType type = certificate::GetCertType(cert);
-    switch (type) {
-      case net::USER_CERT:
-        user_certificates_.push_back(GetCertificate(cert, type));
-        break;
-      case net::CA_CERT: {
-        // Exclude root CA certificates that are built into Chrome.
-        std::string token_name = certificate::GetCertTokenName(cert);
-        if (token_name != kRootCertificateTokenName)
-          server_ca_certificates_.push_back(GetCertificate(cert, type));
-        else
-          VLOG(2) << "Ignoring root cert";
-        break;
-      }
-      default:
-        // Ignore other certificates.
-        VLOG(2) << "Ignoring cert type: " << type;
-        break;
-    }
-  }
-
+void NetworkCertificateHandler::AddAuthorityCertificateForTest(
+    const std::string& issued_to) {
+  Certificate cert;
+  cert.issued_to = issued_to;
+  cert.issued_to_ascii = issued_to;
+  server_ca_certificates_.push_back(cert);
   for (auto& observer : observer_list_)
     observer.OnCertificatesChanged();
 }
 
-void NetworkCertificateHandler::SetCertificatesForTest(
-    const net::ScopedCERTCertificateList& cert_list) {
-  ProcessCertificates(cert_list);
+void NetworkCertificateHandler::OnCertificatesLoaded() {
+  ProcessCertificates(NetworkCertLoader::Get()->authority_certs(),
+                      NetworkCertLoader::Get()->client_certs());
 }
 
-void NetworkCertificateHandler::NotifyCertificatsChangedForTest() {
+void NetworkCertificateHandler::ProcessCertificates(
+    const NetworkCertLoader::NetworkCertList& authority_certs,
+    const NetworkCertLoader::NetworkCertList& client_certs) {
+  client_certificates_.clear();
+  server_ca_certificates_.clear();
+
+  // Add certificates to the appropriate list.
+  for (const auto& network_cert : authority_certs) {
+    server_ca_certificates_.push_back(GetCertificate(
+        network_cert.cert(), net::CA_CERT, network_cert.is_device_wide()));
+  }
+  for (const auto& network_cert : client_certs) {
+    client_certificates_.push_back(GetCertificate(
+        network_cert.cert(), net::USER_CERT, network_cert.is_device_wide()));
+  }
+
   for (auto& observer : observer_list_)
     observer.OnCertificatesChanged();
 }
diff --git a/chromeos/network/network_certificate_handler.h b/chromeos/network/network_certificate_handler.h
index 730f7e6..bc47f2e4 100644
--- a/chromeos/network/network_certificate_handler.h
+++ b/chromeos/network/network_certificate_handler.h
@@ -6,6 +6,7 @@
 #define CHROMEOS_NETWORK_NETWORK_CERTIFICATE_HANDLER_H_
 
 #include <string>
+#include <vector>
 
 #include "base/component_export.h"
 #include "base/macros.h"
@@ -69,25 +70,27 @@
   const std::vector<Certificate>& server_ca_certificates() const {
     return server_ca_certificates_;
   }
-  const std::vector<Certificate>& user_certificates() const {
-    return user_certificates_;
+  const std::vector<Certificate>& client_certificates() const {
+    return client_certificates_;
   }
 
-  void SetCertificatesForTest(const net::ScopedCERTCertificateList& cert_list);
-  void NotifyCertificatsChangedForTest();
+  // Adds a testing certificate to the list of authority ceritificates and
+  // notifies observers that certificates have been updated.
+  void AddAuthorityCertificateForTest(const std::string& issued_to);
 
  private:
   // NetworkCertLoader::Observer
-  void OnCertificatesLoaded(
-      const net::ScopedCERTCertificateList& cert_list) override;
+  void OnCertificatesLoaded() override;
 
-  void ProcessCertificates(const net::ScopedCERTCertificateList& cert_list);
+  void ProcessCertificates(
+      const NetworkCertLoader::NetworkCertList& authority_certs,
+      const NetworkCertLoader::NetworkCertList& client_certs);
 
   base::ObserverList<NetworkCertificateHandler::Observer>::Unchecked
       observer_list_;
 
   std::vector<Certificate> server_ca_certificates_;
-  std::vector<Certificate> user_certificates_;
+  std::vector<Certificate> client_certificates_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkCertificateHandler);
 };
diff --git a/chromeos/network/network_connection_handler_impl.cc b/chromeos/network/network_connection_handler_impl.cc
index 2b1074a..9d3921e 100644
--- a/chromeos/network/network_connection_handler_impl.cc
+++ b/chromeos/network/network_connection_handler_impl.cc
@@ -214,8 +214,7 @@
   logged_in_time_ = base::TimeTicks::Now();
 }
 
-void NetworkConnectionHandlerImpl::OnCertificatesLoaded(
-    const net::ScopedCERTCertificateList& cert_list) {
+void NetworkConnectionHandlerImpl::OnCertificatesLoaded() {
   certificates_loaded_ = true;
   NET_LOG_EVENT("Certificates Loaded", "");
   if (queued_connect_)
diff --git a/chromeos/network/network_connection_handler_impl.h b/chromeos/network/network_connection_handler_impl.h
index cc9f600..e07b1b09 100644
--- a/chromeos/network/network_connection_handler_impl.h
+++ b/chromeos/network/network_connection_handler_impl.h
@@ -44,8 +44,7 @@
   void LoggedInStateChanged() override;
 
   // NetworkCertLoader::Observer
-  void OnCertificatesLoaded(
-      const net::ScopedCERTCertificateList& cert_list) override;
+  void OnCertificatesLoaded() override;
 
  protected:
   void Init(NetworkStateHandler* network_state_handler,
diff --git a/components/OWNERS b/components/OWNERS
index f9d146d..99f4521 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -35,6 +35,7 @@
 # Translation artifacts:
 per-file *.xtb=file://tools/translation/TRANSLATION_OWNERS
 
-# These are for the common case of adding or removing tests. If you're making
-# structural changes, please get a review from one of the overall components
-# OWNERS.
+# This is for the common case of adding or removing tests or files. If you're
+# making structural changes, please get a review from one of the overall
+# components OWNERS.
+per-file BUILD.gn=file://build/OWNERS
diff --git a/components/autofill/core/browser/autofill_profile_sync_util.cc b/components/autofill/core/browser/autofill_profile_sync_util.cc
index 8f6b3ca..f54c161 100644
--- a/components/autofill/core/browser/autofill_profile_sync_util.cc
+++ b/components/autofill/core/browser/autofill_profile_sync_util.cc
@@ -5,14 +5,10 @@
 #include "components/autofill/core/browser/autofill_profile_sync_util.h"
 
 #include "base/guid.h"
-// TODO(crbug.com/904390): Remove when the investigation is over.
-#include "base/metrics/histogram_macros.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/autofill_profile.h"
-// TODO(crbug.com/904390): Remove when the investigation is over.
-#include "components/autofill/core/browser/autofill_profile_comparator.h"
 #include "components/autofill/core/browser/country_names.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/proto/autofill_sync.pb.h"
@@ -239,28 +235,4 @@
   return specifics.guid();
 }
 
-bool IsLocalProfileEqualToServerProfile(
-    const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
-    const AutofillProfile& local_profile,
-    const std::string& app_locale) {
-  AutofillProfileComparator comparator(app_locale);
-  for (const auto& server_profile : server_profiles) {
-    // The same logic as when deciding whether to convert into a new profile in
-    // PersonalDataManager::MergeServerAddressesIntoProfiles.
-    if (comparator.AreMergeable(*server_profile, local_profile) &&
-        (!local_profile.IsVerified() || !server_profile->IsVerified())) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void ReportAutofillProfileAddOrUpdateOrigin(
-    AutofillProfileSyncChangeOrigin origin) {
-  UMA_HISTOGRAM_ENUMERATION("Sync.AutofillProfile.AddOrUpdateOrigin", origin);
-}
-void ReportAutofillProfileDeleteOrigin(AutofillProfileSyncChangeOrigin origin) {
-  UMA_HISTOGRAM_ENUMERATION("Sync.AutofillProfile.DeleteOrigin", origin);
-}
-
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_profile_sync_util.h b/components/autofill/core/browser/autofill_profile_sync_util.h
index 87d677a7..a435952 100644
--- a/components/autofill/core/browser/autofill_profile_sync_util.h
+++ b/components/autofill/core/browser/autofill_profile_sync_util.h
@@ -7,8 +7,6 @@
 
 #include <memory>
 #include <string>
-// TODO(crbug.com/904390): Remove when the investigation is over.
-#include <vector>
 
 namespace syncer {
 struct EntityData;
@@ -42,24 +40,6 @@
 std::string GetStorageKeyFromAutofillProfileSpecifics(
     const sync_pb::AutofillProfileSpecifics& specifics);
 
-// TODO(crbug.com/904390): Remove when the investigation is over.
-bool IsLocalProfileEqualToServerProfile(
-    const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
-    const AutofillProfile& local_profile,
-    const std::string& app_locale);
-
-// TODO(crbug.com/904390): Remove when the investigation is over.
-enum class AutofillProfileSyncChangeOrigin {
-  kTrulyLocal = 0,
-  kConvertedLocal = 1,
-  kIncrementalRemote = 2,
-  kInitial = 3,
-  kMaxValue = kInitial,
-};
-void ReportAutofillProfileAddOrUpdateOrigin(
-    AutofillProfileSyncChangeOrigin origin);
-void ReportAutofillProfileDeleteOrigin(AutofillProfileSyncChangeOrigin origin);
-
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_PROFILE_SYNC_UTIL_H_
diff --git a/components/autofill/core/browser/autofill_profile_unittest.cc b/components/autofill/core/browser/autofill_profile_unittest.cc
index 6320fe08..49ba721 100644
--- a/components/autofill/core/browser/autofill_profile_unittest.cc
+++ b/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -1921,7 +1921,7 @@
                 test_case.use_server_validation));
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     AutofillProfileTest,
     HasGreaterFrescocencyTest,
     testing::Values(
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
index 7acd59b..4ee20ea6 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
@@ -49,20 +49,6 @@
 // Address to this variable used as the user data key.
 static int kAutofillProfileSyncBridgeUserDataKey = 0;
 
-// TODO(crbug.com/904390): Remove when the investigation is over.
-base::Optional<AutofillProfile> FindLocalProfileByStorageKey(
-    const std::string& storage_key,
-    AutofillTable* table) {
-  std::vector<std::unique_ptr<AutofillProfile>> local_profiles;
-  table->GetAutofillProfiles(&local_profiles);
-  for (const auto& local_profile : local_profiles) {
-    if (storage_key == GetStorageKeyFromAutofillProfile(*local_profile)) {
-      return *local_profile;
-    }
-  }
-  return base::nullopt;
-}
-
 }  // namespace
 
 // static
@@ -138,9 +124,8 @@
 
   RETURN_IF_ERROR(
       initial_sync_tracker.MergeSimilarEntriesForInitialSync(app_locale_));
-  RETURN_IF_ERROR(FlushSyncTracker(std::move(metadata_change_list),
-                                   &initial_sync_tracker,
-                                   AutofillProfileSyncChangeOrigin::kInitial));
+  RETURN_IF_ERROR(
+      FlushSyncTracker(std::move(metadata_change_list), &initial_sync_tracker));
 
   web_data_backend_->NotifyThatSyncHasStarted(syncer::AUTOFILL_PROFILE);
   return base::nullopt;
@@ -171,8 +156,7 @@
     }
   }
 
-  return FlushSyncTracker(std::move(metadata_change_list), &tracker,
-                          AutofillProfileSyncChangeOrigin::kIncrementalRemote);
+  return FlushSyncTracker(std::move(metadata_change_list), &tracker);
 }
 
 void AutofillProfileSyncBridge::GetData(StorageKeyList storage_keys,
@@ -231,22 +215,6 @@
       std::make_unique<syncer::SyncMetadataStoreChangeList>(
           GetAutofillTable(), syncer::AUTOFILL_PROFILE);
 
-  // TODO(crbug.com/904390): Remove when the investigation is over.
-  base::Optional<AutofillProfile> local_profile;
-  if (change.type() == AutofillProfileChange::REMOVE) {
-    local_profile =
-        FindLocalProfileByStorageKey(change.key(), GetAutofillTable());
-  } else {
-    local_profile = *change.data_model();
-  }
-  std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
-  GetAutofillTable()->GetServerProfiles(&server_profiles);
-  bool is_converted_from_server = false;
-  if (local_profile != base::nullopt) {
-    is_converted_from_server = IsLocalProfileEqualToServerProfile(
-        server_profiles, *local_profile, app_locale_);
-  }
-
   switch (change.type()) {
     case AutofillProfileChange::ADD:
     case AutofillProfileChange::UPDATE:
@@ -254,12 +222,6 @@
           change.key(),
           CreateEntityDataFromAutofillProfile(*change.data_model()),
           metadata_change_list.get());
-
-      // TODO(crbug.com/904390): Remove when the investigation is over.
-      ReportAutofillProfileAddOrUpdateOrigin(
-          is_converted_from_server
-              ? AutofillProfileSyncChangeOrigin::kConvertedLocal
-              : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       break;
     case AutofillProfileChange::REMOVE:
       // Removals have no data_model() so this change can still be for a
@@ -269,15 +231,6 @@
       // TODO(jkrcal): implement a hash map of known storage_keys and use it
       // here.
       change_processor()->Delete(change.key(), metadata_change_list.get());
-
-      // TODO(crbug.com/904390): Remove when the investigation is over.
-      if (local_profile != base::nullopt) {
-        // Report only if we delete an existing entity.
-        ReportAutofillProfileDeleteOrigin(
-            is_converted_from_server
-                ? AutofillProfileSyncChangeOrigin::kConvertedLocal
-                : AutofillProfileSyncChangeOrigin::kTrulyLocal);
-      }
       break;
     case AutofillProfileChange::EXPIRE:
       // EXPIRE changes are not being issued for profiles.
@@ -292,8 +245,7 @@
 
 base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker(
     std::unique_ptr<MetadataChangeList> metadata_change_list,
-    AutofillProfileSyncDifferenceTracker* tracker,
-    AutofillProfileSyncChangeOrigin origin) {
+    AutofillProfileSyncDifferenceTracker* tracker) {
   DCHECK(tracker);
 
   RETURN_IF_ERROR(tracker->FlushToLocal(
@@ -307,9 +259,6 @@
     change_processor()->Put(GetStorageKeyFromAutofillProfile(*entry),
                             CreateEntityDataFromAutofillProfile(*entry),
                             metadata_change_list.get());
-
-    // TODO(crbug.com/904390): Remove when the investigation is over.
-    ReportAutofillProfileAddOrUpdateOrigin(origin);
   }
 
   return static_cast<syncer::SyncMetadataStoreChangeList*>(
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
index 9b449f4..a6e50098 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
@@ -29,7 +29,6 @@
 class AutofillTable;
 class AutofillWebDataBackend;
 class AutofillWebDataService;
-enum class AutofillProfileSyncChangeOrigin;
 
 // Sync bridge implementation for AUTOFILL_PROFILE model type. Takes care of
 // propagating local autofill profiles to other clients as well as incorporating
@@ -91,9 +90,7 @@
   // Flushes changes accumulated within |tracker| both to local and to sync.
   base::Optional<syncer::ModelError> FlushSyncTracker(
       std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
-      AutofillProfileSyncDifferenceTracker* tracker,
-      // TODO(crbug.com/904390): Remove |origin| when the investigation is over.
-      AutofillProfileSyncChangeOrigin origin);
+      AutofillProfileSyncDifferenceTracker* tracker);
 
   // Synchronously load sync metadata from the autofill table and pass it to the
   // processor so that it can start tracking changes.
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
index f3c90a6d..51d3cb7 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
@@ -17,8 +17,6 @@
 #include "components/autofill/core/browser/autofill_country.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_profile_comparator.h"
-// TODO(crbug.com/904390): Remove when the investigation is over.
-#include "components/autofill/core/browser/autofill_profile_sync_util.h"
 #include "components/autofill/core/browser/country_names.h"
 #include "components/autofill/core/browser/form_group.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
@@ -186,10 +184,6 @@
         syncer::SyncChange(FROM_HERE,
                            syncer::SyncChange::ACTION_ADD,
                            CreateData(*(it.second))));
-
-    // TODO(crbug.com/904390): Remove when the investigation is over.
-    ReportAutofillProfileAddOrUpdateOrigin(
-        AutofillProfileSyncChangeOrigin::kInitial);
     profiles_map_[it.first] = it.second;
   }
 
@@ -198,10 +192,6 @@
         syncer::SyncChange(FROM_HERE,
                            syncer::SyncChange::ACTION_UPDATE,
                            CreateData(*(bundle.profiles_to_sync_back[i]))));
-
-    // TODO(crbug.com/904390): Remove when the investigation is over.
-    ReportAutofillProfileAddOrUpdateOrigin(
-        AutofillProfileSyncChangeOrigin::kInitial);
   }
 
   if (!new_changes.empty()) {
@@ -613,24 +603,6 @@
     return;
   }
 
-  // TODO(crbug.com/904390): Remove when the investigation is over.
-  const AutofillProfile* local_profile = nullptr;
-  if (change.type() == AutofillProfileChange::REMOVE) {
-    if (profiles_map_.find(change.key()) != profiles_map_.end()) {
-      local_profile = profiles_map_[change.key()];
-    }
-  } else {
-    local_profile = change.data_model();
-  }
-  bool is_converted_from_server = false;
-  // |webdata_backend_| may be null in unit-tests.
-  if (local_profile != nullptr && webdata_backend_ != nullptr) {
-    std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
-    GetAutofillTable()->GetServerProfiles(&server_profiles);
-    is_converted_from_server = IsLocalProfileEqualToServerProfile(
-        server_profiles, *local_profile, app_locale_);
-  }
-
   syncer::SyncChangeList new_changes;
   DataBundle bundle;
   switch (change.type()) {
@@ -644,12 +616,6 @@
       profiles_.push_back(
           std::make_unique<AutofillProfile>(*(change.data_model())));
       profiles_map_[change.data_model()->guid()] = profiles_.back().get();
-
-      // TODO(crbug.com/904390): Remove when the investigation is over.
-      ReportAutofillProfileAddOrUpdateOrigin(
-          is_converted_from_server
-              ? AutofillProfileSyncChangeOrigin::kConvertedLocal
-              : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       break;
     case AutofillProfileChange::UPDATE: {
       auto it = profiles_map_.find(change.data_model()->guid());
@@ -659,12 +625,6 @@
           syncer::SyncChange(FROM_HERE,
                              syncer::SyncChange::ACTION_UPDATE,
                              CreateData(*(change.data_model()))));
-
-      // TODO(crbug.com/904390): Remove when the investigation is over.
-      ReportAutofillProfileAddOrUpdateOrigin(
-          is_converted_from_server
-              ? AutofillProfileSyncChangeOrigin::kConvertedLocal
-              : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       break;
     }
     case AutofillProfileChange::REMOVE: {
@@ -676,11 +636,6 @@
             syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE,
                                CreateData(empty_profile)));
         profiles_map_.erase(change.key());
-        // TODO(crbug.com/904390): Remove when the investigation is over.
-        ReportAutofillProfileDeleteOrigin(
-            is_converted_from_server
-                ? AutofillProfileSyncChangeOrigin::kConvertedLocal
-                : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       }
       break;
     }
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc
index 2e214e34..94286ee 100644
--- a/components/autofill_assistant/browser/web_controller.cc
+++ b/components/autofill_assistant/browser/web_controller.cc
@@ -1455,10 +1455,10 @@
   float visual_h = static_cast<float>(list[7].GetDouble());
 
   RectF rect;
-  rect.left = std::max(0.0f, left_layout - visual_left_offset) / visual_w;
-  rect.top = std::max(0.0f, top_layout - visual_top_offset) / visual_h;
-  rect.right = std::max(0.0f, right_layout - visual_left_offset) / visual_w;
-  rect.bottom = std::max(0.0f, bottom_layout - visual_top_offset) / visual_h;
+  rect.left = (left_layout - visual_left_offset) / visual_w;
+  rect.top = (top_layout - visual_top_offset) / visual_h;
+  rect.right = (right_layout - visual_left_offset) / visual_w;
+  rect.bottom = (bottom_layout - visual_top_offset) / visual_h;
 
   std::move(callback).Run(true, rect);
 }
diff --git a/components/browser_sync/profile_sync_service_autofill_unittest.cc b/components/browser_sync/profile_sync_service_autofill_unittest.cc
index 7051642..84f22c1 100644
--- a/components/browser_sync/profile_sync_service_autofill_unittest.cc
+++ b/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -144,11 +144,6 @@
   MOCK_METHOD1(UpdateAutofillProfile, bool(const AutofillProfile&));   // NOLINT
   MOCK_METHOD1(AddAutofillProfile, bool(const AutofillProfile&));      // NOLINT
   MOCK_METHOD1(RemoveAutofillProfile, bool(const std::string&));       // NOLINT
-
-  // TODO(crbug.com/904390): Remove when the investigation is over.
-  MOCK_CONST_METHOD1(
-      GetServerProfiles,
-      bool(std::vector<std::unique_ptr<AutofillProfile>>*));  // NOLINT
 };
 
 MATCHER_P(MatchProfiles, profile, "") {
@@ -955,10 +950,6 @@
       "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
       "Orlando", "FL", "32801", "US", "19482937549");
 
-  // TODO(crbug.com/904390): Remove when the investigation is over. This call is
-  // needed in the AutofillProfileChanged() callback.
-  EXPECT_CALL(autofill_table(), GetServerProfiles(_)).WillOnce(Return(true));
-
   AutofillProfileChange change(AutofillProfileChange::ADD, added_profile.guid(),
                                &added_profile);
   web_data_service()->OnAutofillProfileChanged(change);
@@ -998,10 +989,6 @@
   StartAutofillProfileSyncService(add_autofill.callback());
   ASSERT_TRUE(add_autofill.success());
 
-  // TODO(crbug.com/904390): Remove when the investigation is over. This call is
-  // needed in the AutofillProfileChanged() callback.
-  EXPECT_CALL(autofill_table(), GetServerProfiles(_)).WillOnce(Return(true));
-
   AutofillProfileChange change(AutofillProfileChange::REMOVE,
                                sync_profile.guid(), nullptr);
   web_data_service()->OnAutofillProfileChanged(change);
diff --git a/components/feed/core/feed_logging_metrics.cc b/components/feed/core/feed_logging_metrics.cc
index 3da3377b..9726f2d 100644
--- a/components/feed/core/feed_logging_metrics.cc
+++ b/components/feed/core/feed_logging_metrics.cc
@@ -52,6 +52,7 @@
   std::string histogram_name(
       base::StringPrintf("%s.%s", kHistogramArticlesUsageTimeLocal,
                          kWeekdayNames[now_exploded.day_of_week]));
+  // Since the |histogram_name| is dynamic, we can't use the regular macro.
   base::UmaHistogramExactLinear(histogram_name, bucket, kNumBuckets);
   UMA_HISTOGRAM_EXACT_LINEAR(kHistogramArticlesUsageTimeLocal, bucket,
                              kNumBuckets);
@@ -77,6 +78,26 @@
   base::RecordAction(base::UserMetricsAction("MobileNTP.Snippets.VisitEnd"));
 }
 
+void RecordUndoableActionUMA(const std::string& histogram_base,
+                             int position,
+                             bool committed) {
+  std::string histogram_name =
+      histogram_base + (committed ? ".Commit" : ".Undo");
+
+  // Since the |histogram_name| is dynamic, we can't use the regular macro.
+  base::UmaHistogramExactLinear(histogram_name, position, kMaxSuggestionsTotal);
+}
+
+void CheckURLVisitedDone(int position, bool committed, bool visited) {
+  if (visited) {
+    RecordUndoableActionUMA("NewTabPage.ContentSuggestions.DismissedVisited",
+                            position, committed);
+  } else {
+    RecordUndoableActionUMA("NewTabPage.ContentSuggestions.DismissedUnvisited",
+                            position, committed);
+  }
+}
+
 }  // namespace
 
 FeedLoggingMetrics::FeedLoggingMetrics(
@@ -179,10 +200,11 @@
       ToUMAScore(score), 11);
 }
 
-void FeedLoggingMetrics::OnSuggestionDismissed(int position, const GURL& url) {
+void FeedLoggingMetrics::OnSuggestionDismissed(int position,
+                                               const GURL& url,
+                                               bool committed) {
   history_url_check_callback_.Run(
-      url, base::BindOnce(&FeedLoggingMetrics::CheckURLVisitedDone,
-                          weak_ptr_factory_.GetWeakPtr(), position));
+      url, base::BindOnce(&CheckURLVisitedDone, position, committed));
 
   base::RecordAction(base::UserMetricsAction("Suggestions.Content.Dismissed"));
 }
@@ -222,25 +244,34 @@
       kMaxSuggestionsForArticle + 1);
 }
 
+void FeedLoggingMetrics::OnNotInterestedInSource(int position, bool committed) {
+  RecordUndoableActionUMA(
+      "ContentSuggestions.Feed.InterestHeader.NotInterestedInSource", position,
+      committed);
+}
+
+void FeedLoggingMetrics::OnNotInterestedInTopic(int position, bool committed) {
+  RecordUndoableActionUMA(
+      "ContentSuggestions.Feed.InterestHeader.NotInterestedInTopic", position,
+      committed);
+}
+
 void FeedLoggingMetrics::OnSpinnerShown(base::TimeDelta shown_time) {
   base::UmaHistogramTimes(
       "ContentSuggestions.Feed.FetchPendingSpinner.VisibleDuration",
       shown_time);
 }
 
-void FeedLoggingMetrics::ReportScrolledAfterOpen() {
-  base::RecordAction(base::UserMetricsAction("Suggestions.ScrolledAfterOpen"));
+void FeedLoggingMetrics::OnPietFrameRenderingEvent(
+    std::vector<int> piet_error_codes) {
+  for (auto error_code : piet_error_codes) {
+    base::UmaHistogramSparse(
+        "ContentSuggestions.Feed.Piet.FrameRenderingErrorCode", error_code);
+  }
 }
 
-void FeedLoggingMetrics::CheckURLVisitedDone(int position, bool visited) {
-  if (visited) {
-    UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.ContentSuggestions.DismissedVisited",
-                               position, kMaxSuggestionsTotal);
-  } else {
-    UMA_HISTOGRAM_EXACT_LINEAR(
-        "NewTabPage.ContentSuggestions.DismissedUnvisited", position,
-        kMaxSuggestionsTotal);
-  }
+void FeedLoggingMetrics::ReportScrolledAfterOpen() {
+  base::RecordAction(base::UserMetricsAction("Suggestions.ScrolledAfterOpen"));
 }
 
 }  // namespace feed
diff --git a/components/feed/core/feed_logging_metrics.h b/components/feed/core/feed_logging_metrics.h
index 994d19f..3f9999d 100644
--- a/components/feed/core/feed_logging_metrics.h
+++ b/components/feed/core/feed_logging_metrics.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 #include <utility>
+#include <vector>
 
 #include "base/callback.h"
 #include "base/macros.h"
@@ -60,7 +61,7 @@
                               base::Time publish_date,
                               float score);
 
-  void OnSuggestionDismissed(int position, const GURL& url);
+  void OnSuggestionDismissed(int position, const GURL& url, bool committed);
 
   void OnSuggestionSwiped();
 
@@ -75,13 +76,17 @@
 
   void OnMoreButtonClicked(int position);
 
+  void OnNotInterestedInSource(int position, bool committed);
+
+  void OnNotInterestedInTopic(int position, bool committed);
+
   void OnSpinnerShown(base::TimeDelta shown_time);
 
+  void OnPietFrameRenderingEvent(std::vector<int> piet_error_codes);
+
   void ReportScrolledAfterOpen();
 
  private:
-  void CheckURLVisitedDone(int position, bool visited);
-
   const HistoryURLCheckCallback history_url_check_callback_;
 
   // Used to access current time, injected for testing.
diff --git a/components/feed/core/feed_logging_metrics_unittest.cc b/components/feed/core/feed_logging_metrics_unittest.cc
index 9fc3c55..37303c0 100644
--- a/components/feed/core/feed_logging_metrics_unittest.cc
+++ b/components/feed/core/feed_logging_metrics_unittest.cc
@@ -150,21 +150,55 @@
                   /*count=*/4)));
 }
 
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedIfVisited) {
+TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedCommitIfVisited) {
   base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, kVisitedUrl);
+  feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, kVisitedUrl,
+                                                true);
   EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.DismissedVisited"),
+                  "NewTabPage.ContentSuggestions.DismissedVisited.Commit"),
               ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
 }
 
-TEST_F(FeedLoggingMetricsTest, ShouldLogOnSuggestionDismissedIfNotVisited) {
+TEST_F(FeedLoggingMetricsTest,
+       ShouldLogOnSuggestionDismissedCommitIfNotVisited) {
   base::HistogramTester histogram_tester;
-  feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10,
-                                                GURL("http://non_visited.com"));
+  feed_logging_metrics()->OnSuggestionDismissed(
+      /*position=*/10, GURL("http://non_visited.com"), true);
   EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.ContentSuggestions.DismissedVisited"),
-              IsEmpty());
+                  "NewTabPage.ContentSuggestions.DismissedUnvisited.Commit"),
+              ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
+}
+
+TEST_F(FeedLoggingMetricsTest,
+       ShouldLogOnSuggestionDismissedUndoIfUndoDismissAndVisited) {
+  base::HistogramTester histogram_tester;
+  feed_logging_metrics()->OnSuggestionDismissed(/*position=*/10, kVisitedUrl,
+                                                false);
+  EXPECT_THAT(histogram_tester.GetAllSamples(
+                  "NewTabPage.ContentSuggestions.DismissedVisited.Undo"),
+              ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
+}
+
+TEST_F(FeedLoggingMetricsTest,
+       ShouldLogOnSuggestionDismissedUndoIfUndoDismissAndNotVisited) {
+  base::HistogramTester histogram_tester;
+  feed_logging_metrics()->OnSuggestionDismissed(
+      /*position=*/10, GURL("http://non_visited.com"), false);
+  EXPECT_THAT(histogram_tester.GetAllSamples(
+                  "NewTabPage.ContentSuggestions.DismissedUnvisited.Undo"),
+              ElementsAre(base::Bucket(/*min=*/10, /*count=*/1)));
+}
+
+TEST_F(FeedLoggingMetricsTest, ShouldReportOnPietFrameRenderingEvent) {
+  base::HistogramTester histogram_tester;
+  std::vector<int> error_codes({0, 1, 6, 7});
+  feed_logging_metrics()->OnPietFrameRenderingEvent(error_codes);
+  EXPECT_THAT(histogram_tester.GetAllSamples(
+                  "ContentSuggestions.Feed.Piet.FrameRenderingErrorCode"),
+              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
+                          base::Bucket(/*min=*/1, /*count=*/1),
+                          base::Bucket(/*min=*/6, /*count=*/1),
+                          base::Bucket(/*min=*/7, /*count=*/1)));
 }
 
 }  // namespace feed
diff --git a/components/password_manager/core/browser/new_password_form_manager.cc b/components/password_manager/core/browser/new_password_form_manager.cc
index ff50b4ac..dde59b3d 100644
--- a/components/password_manager/core/browser/new_password_form_manager.cc
+++ b/components/password_manager/core/browser/new_password_form_manager.cc
@@ -316,8 +316,23 @@
   parsed_submitted_form_->username_value = new_username;
   parsed_submitted_form_->username_element.clear();
 
-  // TODO(https://crbug.com/831123): Implement processing username editing votes
-  // after implementation of |other_possible_usernames|.
+  // |has_username_edited_vote_| is true iff |new_username| was typed in another
+  // field. Otherwise, |has_username_edited_vote_| is false and no vote will be
+  // uploaded.
+  votes_uploader_.set_has_username_edited_vote(false);
+  if (!new_username.empty()) {
+    // |other_possible_usernames| has all possible usernames.
+    // TODO(crbug.com/831123): rename to |all_possible_usernames| when the old
+    // parser is gone.
+    for (const auto& possible_username :
+         parsed_submitted_form_->other_possible_usernames) {
+      if (possible_username.first == new_username) {
+        parsed_submitted_form_->username_element = possible_username.second;
+        votes_uploader_.set_has_username_edited_vote(true);
+        break;
+      }
+    }
+  }
 
   CreatePendingCredentials();
 }
@@ -344,15 +359,29 @@
   CreatePendingCredentials();
 }
 
-// TODO(https://crbug.com/831123): Implement all methods from
-// PasswordFormManagerForUI.
-void NewPasswordFormManager::OnNopeUpdateClicked() {}
+void NewPasswordFormManager::OnNopeUpdateClicked() {
+  votes_uploader_.UploadPasswordVote(*parsed_submitted_form_,
+                                     *parsed_submitted_form_,
+                                     autofill::NOT_NEW_PASSWORD, std::string());
+}
 
 void NewPasswordFormManager::OnNeverClicked() {
+  // |UNKNOWN_TYPE| is sent in order to record that a generation popup was
+  // shown and ignored.
+  votes_uploader_.UploadPasswordVote(*parsed_submitted_form_,
+                                     *parsed_submitted_form_,
+                                     autofill::UNKNOWN_TYPE, std::string());
   PermanentlyBlacklist();
 }
 
-void NewPasswordFormManager::OnNoInteraction(bool is_update) {}
+void NewPasswordFormManager::OnNoInteraction(bool is_update) {
+  // |UNKNOWN_TYPE| is sent in order to record that a generation popup was
+  // shown and ignored.
+  votes_uploader_.UploadPasswordVote(
+      *parsed_submitted_form_, *parsed_submitted_form_,
+      is_update ? autofill::PROBABLY_NEW_PASSWORD : autofill::UNKNOWN_TYPE,
+      std::string());
+}
 
 void NewPasswordFormManager::PermanentlyBlacklist() {
   DCHECK(!client_->IsIncognito());
@@ -366,7 +395,9 @@
   form_saver_->PermanentlyBlacklist(new_blacklisted_.get());
 }
 
-void NewPasswordFormManager::OnPasswordsRevealed() {}
+void NewPasswordFormManager::OnPasswordsRevealed() {
+  votes_uploader_.set_has_passwords_revealed_vote(true);
+}
 
 bool NewPasswordFormManager::IsNewLogin() const {
   return is_new_login_;
@@ -583,6 +614,11 @@
 
 void NewPasswordFormManager::ProcessServerPredictions(
     const std::map<FormSignature, FormPredictions>& predictions) {
+  if (parser_.predictions()) {
+    // This method might be called multiple times. No need to process
+    // predictions again.
+    return;
+  }
   FormSignature observed_form_signature =
       CalculateFormSignature(observed_form_);
   auto it = predictions.find(observed_form_signature);
diff --git a/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
index 1b65f68d..b5d488f7 100644
--- a/components/password_manager/core/browser/new_password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -26,6 +26,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using autofill::AutofillUploadContents;
 using autofill::FieldPropertiesFlags;
 using autofill::FormData;
 using autofill::FormFieldData;
@@ -39,6 +40,7 @@
 using base::TestMockTimeTaskRunner;
 using testing::_;
 using testing::AllOf;
+using testing::Contains;
 using testing::Mock;
 using testing::NiceMock;
 using testing::Return;
@@ -560,6 +562,11 @@
   // Expect filling without delay on receiving server predictions.
   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(1);
   form_manager_->ProcessServerPredictions(predictions);
+  Mock::VerifyAndClearExpectations(&driver_);
+
+  // Expect no filling on receving predictions again.
+  EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
+  form_manager_->ProcessServerPredictions(predictions);
 }
 
 // Tests that NewPasswordFormManager fills after some delay even without
@@ -947,6 +954,7 @@
   EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
   EXPECT_FALSE(form_manager_->IsNewLogin());
   EXPECT_FALSE(form_manager_->IsPasswordOverridden());
+  EXPECT_TRUE(form_manager_->IsPasswordUpdate());
 
   MockFormSaver& form_saver = MockFormSaver::Get(form_manager_.get());
   PasswordForm updated_form;
@@ -977,38 +985,43 @@
 
 TEST_F(NewPasswordFormManagerTest, VotesUploadingOnPasswordUpdate) {
   TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
-  CreateFormManager(observed_form_only_password_fields_);
-  fetcher_->SetNonFederated({&saved_match_}, 0u);
 
-  FormData submitted_form = observed_form_only_password_fields_;
-  submitted_form.fields[0].value = saved_match_.password_value;
-  base::string16 new_password = saved_match_.password_value + ASCIIToUTF16("1");
-  submitted_form.fields[1].value = new_password;
+  for (auto expected_vote :
+       {autofill::NEW_PASSWORD, autofill::PROBABLY_NEW_PASSWORD,
+        autofill::NOT_NEW_PASSWORD}) {
+    SCOPED_TRACE(testing::Message("expected_vote=") << expected_vote);
+    CreateFormManager(observed_form_only_password_fields_);
+    fetcher_->SetNonFederated({&saved_match_}, 0u);
 
-  EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
-  EXPECT_TRUE(form_manager_->IsPasswordUpdate());
+    FormData submitted_form = observed_form_only_password_fields_;
+    submitted_form.fields[0].value = saved_match_.password_value;
+    auto new_password = saved_match_.password_value + ASCIIToUTF16("1");
+    submitted_form.fields[1].value = new_password;
 
-  MockFormSaver& form_saver = MockFormSaver::Get(form_manager_.get());
-  PasswordForm updated_form;
-  std::map<base::string16, const PasswordForm*> best_matches;
-  std::vector<PasswordForm> credentials_to_update;
-  EXPECT_CALL(form_saver, Update(_, _, _, nullptr))
-      .WillOnce(DoAll(SaveArg<0>(&updated_form), SaveArg<1>(&best_matches),
-                      SaveArgPointee<2>(&credentials_to_update)));
+    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_));
 
-  std::map<base::string16, autofill::ServerFieldType> expected_types;
-  expected_types[ASCIIToUTF16("password")] = autofill::PASSWORD;
-  expected_types[ASCIIToUTF16("password2")] = autofill::NEW_PASSWORD;
+    std::map<base::string16, autofill::ServerFieldType> expected_types;
+    expected_types[ASCIIToUTF16("password")] = autofill::PASSWORD;
+    expected_types[ASCIIToUTF16("password2")] = expected_vote;
 
-  testing::InSequence in_sequence;
-  EXPECT_CALL(mock_autofill_download_manager_,
-              StartUploadRequest(UploadedAutofillTypesAre(expected_types),
-                                 false, _, _, true, nullptr));
-  // An unrelated |FIRST_USE| vote.
-  EXPECT_CALL(mock_autofill_download_manager_,
-              StartUploadRequest(_, _, _, _, _, _));
+    testing::InSequence in_sequence;
+    EXPECT_CALL(mock_autofill_download_manager_,
+                StartUploadRequest(UploadedAutofillTypesAre(expected_types),
+                                   false, _, _, true, nullptr));
+    if (expected_vote == autofill::NEW_PASSWORD) {
+      // An unrelated |FIRST_USE| vote.
+      EXPECT_CALL(mock_autofill_download_manager_,
+                  StartUploadRequest(_, _, _, _, _, _));
+    }
 
-  form_manager_->Save();
+    if (expected_vote == autofill::NEW_PASSWORD)
+      form_manager_->Save();
+    else if (expected_vote == autofill::PROBABLY_NEW_PASSWORD)
+      form_manager_->OnNoInteraction(true /* is_update */);
+    else
+      form_manager_->OnNopeUpdateClicked();
+    Mock::VerifyAndClearExpectations(&mock_autofill_download_manager_);
+  }
 }
 
 TEST_F(NewPasswordFormManagerTest, UpdateUsernameEmptyStore) {
@@ -1029,6 +1042,40 @@
   EXPECT_TRUE(form_manager_->IsNewLogin());
 }
 
+TEST_F(NewPasswordFormManagerTest, UpdateUsernameToAnotherFieldValue) {
+  TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
+  fetcher_->SetNonFederated({}, 0u);
+
+  base::string16 user_chosen_username = ASCIIToUTF16("user_chosen_username");
+  base::string16 automatically_chosen_username =
+      ASCIIToUTF16("automatically_chosen_username");
+  submitted_form_.fields[0].value = user_chosen_username;
+  submitted_form_.fields[1].value = automatically_chosen_username;
+  form_manager_->ProvisionallySave(submitted_form_, &driver_);
+
+  EXPECT_EQ(automatically_chosen_username,
+            form_manager_->GetPendingCredentials().username_value);
+
+  form_manager_->UpdateUsername(user_chosen_username);
+
+  EXPECT_EQ(user_chosen_username,
+            form_manager_->GetPendingCredentials().username_value);
+
+  FieldTypeMap expected_types = {
+      {ASCIIToUTF16("firstname"), autofill::USERNAME},
+      {ASCIIToUTF16("password"), autofill::PASSWORD}};
+  VoteTypeMap expected_vote_types = {
+      {ASCIIToUTF16("firstname"),
+       AutofillUploadContents::Field::USERNAME_EDITED}};
+  EXPECT_CALL(
+      mock_autofill_download_manager_,
+      StartUploadRequest(
+          AllOf(UploadedAutofillTypesAre(expected_types),
+                HasGenerationVote(false), VoteTypesAre(expected_vote_types)),
+          _, Contains(autofill::USERNAME), _, _, nullptr));
+  form_manager_->Save();
+}
+
 TEST_F(NewPasswordFormManagerTest, UpdateUsernameToAlreadyExisting) {
   TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
   fetcher_->SetNonFederated({&saved_match_}, 0u);
@@ -1703,6 +1750,77 @@
       PasswordFormMetricsRecorder::FillingAssistance::kManual, 1);
 }
 
+TEST_F(NewPasswordFormManagerTest, PasswordRevealedVote) {
+  TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
+
+  for (bool password_revealed : {false, true}) {
+    SCOPED_TRACE(testing::Message("password_revealed=") << password_revealed);
+    CreateFormManager(observed_form_);
+    fetcher_->SetNonFederated({}, 0u);
+
+    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+
+    if (password_revealed)
+      form_manager_->OnPasswordsRevealed();
+
+    EXPECT_CALL(mock_autofill_download_manager_,
+                StartUploadRequest(PasswordsWereRevealed(password_revealed),
+                                   false, _, _, true, nullptr));
+    form_manager_->Save();
+    Mock::VerifyAndClearExpectations(&mock_autofill_download_manager_);
+  }
+}
+
+TEST_F(NewPasswordFormManagerTest, GenerationUploadOnNoInteraction) {
+  TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
+
+  for (bool generation_popup_shown : {false, true}) {
+    SCOPED_TRACE(testing::Message("generation_popup_shown=")
+                 << generation_popup_shown);
+    CreateFormManager(observed_form_);
+    fetcher_->SetNonFederated({}, 0u);
+
+    if (generation_popup_shown) {
+      form_manager_->SetGenerationElement(ASCIIToUTF16("password"));
+      form_manager_->SetGenerationPopupWasShown(
+          true /*generation_popup_was_shown*/, false /*is_manual_generation*/);
+    }
+    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+
+    EXPECT_CALL(
+        mock_autofill_download_manager_,
+        StartUploadRequest(HasGenerationVote(true), false, _, _, true, nullptr))
+        .Times(generation_popup_shown ? 1 : 0);
+    form_manager_->OnNoInteraction(false /*is_update */);
+    Mock::VerifyAndClearExpectations(&mock_autofill_download_manager_);
+  }
+}
+
+TEST_F(NewPasswordFormManagerTest, GenerationUploadOnNeverClicked) {
+  TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner_.get());
+
+  for (bool generation_popup_shown : {false, true}) {
+    SCOPED_TRACE(testing::Message("generation_popup_shown=")
+                 << generation_popup_shown);
+    CreateFormManager(observed_form_);
+    fetcher_->SetNonFederated({}, 0u);
+
+    if (generation_popup_shown) {
+      form_manager_->SetGenerationElement(ASCIIToUTF16("password"));
+      form_manager_->SetGenerationPopupWasShown(
+          true /*generation_popup_was_shown*/, false /*is_manual_generation*/);
+    }
+    EXPECT_TRUE(form_manager_->ProvisionallySave(submitted_form_, &driver_));
+
+    EXPECT_CALL(
+        mock_autofill_download_manager_,
+        StartUploadRequest(HasGenerationVote(true), false, _, _, true, nullptr))
+        .Times(generation_popup_shown ? 1 : 0);
+    form_manager_->OnNeverClicked();
+    Mock::VerifyAndClearExpectations(&mock_autofill_download_manager_);
+  }
+}
+
 }  // namespace
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/vote_uploads_test_matchers.h b/components/password_manager/core/browser/vote_uploads_test_matchers.h
index 4072642..7ee81d7 100644
--- a/components/password_manager/core/browser/vote_uploads_test_matchers.h
+++ b/components/password_manager/core/browser/vote_uploads_test_matchers.h
@@ -158,4 +158,8 @@
   return true;
 }
 
+MATCHER_P(PasswordsWereRevealed, passwords_were_revealed, "") {
+  return passwords_were_revealed == arg.passwords_were_revealed();
+}
+
 #endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_VOTE_UPLOADS_TEST_MATCHERS_H_
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc
index 47b8fbc..3d20236 100644
--- a/components/policy/core/common/cloud/cloud_policy_client.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -72,9 +72,9 @@
 
 void ExtractLicenseMap(const em::CheckDeviceLicenseResponse& license_response,
                        CloudPolicyClient::LicenseMap& licenses) {
-  for (int i = 0; i < license_response.license_availability_size(); i++) {
+  for (int i = 0; i < license_response.license_availabilities_size(); i++) {
     const em::LicenseAvailability& license =
-        license_response.license_availability(i);
+        license_response.license_availabilities(i);
     if (!license.has_license_type() || !license.has_available_licenses())
       continue;
     auto license_type = TranslateLicenseType(license.license_type());
@@ -383,7 +383,7 @@
   // Build policy fetch requests.
   em::DevicePolicyRequest* policy_request = request->mutable_policy_request();
   for (const auto& type_to_fetch : types_to_fetch_) {
-    em::PolicyFetchRequest* fetch_request = policy_request->add_request();
+    em::PolicyFetchRequest* fetch_request = policy_request->add_requests();
     fetch_request->set_policy_type(type_to_fetch.first);
     if (!type_to_fetch.second.empty())
       fetch_request->set_settings_entity_id(type_to_fetch.second);
@@ -416,7 +416,7 @@
              state_keys_to_upload_.begin());
          key != state_keys_to_upload_.end();
          ++key) {
-      key_update_request->add_server_backed_state_key(*key);
+      key_update_request->add_server_backed_state_keys(*key);
     }
   }
 
@@ -487,7 +487,7 @@
       mutable_service_api_access_request();
   request->set_oauth2_client_id(
       GaiaUrls::GetInstance()->oauth2_chrome_client_id());
-  request->add_auth_scope(GaiaConstants::kAnyApiOAuth2Scope);
+  request->add_auth_scopes(GaiaConstants::kAnyApiOAuth2Scope);
   request->set_device_type(em::DeviceServiceApiAccessRequest::CHROME_OS);
 
   policy_fetch_request_job_->Start(base::AdaptCallbackForRepeating(
@@ -924,7 +924,7 @@
     const em::DeviceManagementResponse& response) {
   if (status == DM_STATUS_SUCCESS) {
     if (!response.has_policy_response() ||
-        response.policy_response().response_size() == 0) {
+        response.policy_response().responses_size() == 0) {
       LOG(WARNING) << "Empty policy response.";
       status = DM_STATUS_RESPONSE_DECODING_ERROR;
     }
@@ -935,8 +935,8 @@
     const em::DevicePolicyResponse& policy_response =
         response.policy_response();
     responses_.clear();
-    for (int i = 0; i < policy_response.response_size(); ++i) {
-      const em::PolicyFetchResponse& response = policy_response.response(i);
+    for (int i = 0; i < policy_response.responses_size(); ++i) {
+      const em::PolicyFetchResponse& response = policy_response.responses(i);
       em::PolicyData policy_data;
       if (!policy_data.ParseFromString(response.policy_data()) ||
           !policy_data.IsInitialized() ||
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
index 3636fc2..9402d28 100644
--- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -164,13 +164,14 @@
         cert_based_register_request->mutable_signed_request());
 
     em::PolicyFetchRequest* policy_fetch_request =
-        policy_request_.mutable_policy_request()->add_request();
+        policy_request_.mutable_policy_request()->add_requests();
     policy_fetch_request->set_policy_type(dm_protocol::kChromeUserPolicyType);
     policy_fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA);
     policy_fetch_request->set_verification_key_hash(kPolicyVerificationKeyHash);
     policy_fetch_request->set_device_dm_token(kDeviceDMToken);
-    policy_response_.mutable_policy_response()->add_response()->set_policy_data(
-        CreatePolicyData("fake-policy-data"));
+    policy_response_.mutable_policy_response()
+        ->add_responses()
+        ->set_policy_data(CreatePolicyData("fake-policy-data"));
 
     registration_response_.mutable_register_response()->
         set_device_management_token(kDMToken);
@@ -251,12 +252,12 @@
     device_license_response->set_license_selection_mode(
         em::CheckDeviceLicenseResponse_LicenseSelectionMode_USER_SELECTION);
     em::LicenseAvailability* license_one =
-        device_license_response->add_license_availability();
+        device_license_response->add_license_availabilities();
     license_one->mutable_license_type()->set_license_type(
         em::LicenseType_LicenseTypeEnum_CDM_PERPETUAL);
     license_one->set_available_licenses(10);
     em::LicenseAvailability* license_two =
-        device_license_response->add_license_availability();
+        device_license_response->add_license_availabilities();
     license_two->mutable_license_type()->set_license_type(
         em::LicenseType_LicenseTypeEnum_KIOSK);
     license_two->set_available_licenses(0);
@@ -553,7 +554,7 @@
   void CheckPolicyResponse() {
     ASSERT_TRUE(client_->GetPolicyFor(policy_type_, std::string()));
     EXPECT_THAT(*client_->GetPolicyFor(policy_type_, std::string()),
-                MatchProto(policy_response_.policy_response().response(0)));
+                MatchProto(policy_response_.policy_response().responses(0)));
   }
 
   std::string CreatePolicyData(const std::string& policy_value) {
@@ -848,8 +849,8 @@
   client_->FetchPolicy();
   CheckPolicyResponse();
 
-  policy_response_.mutable_policy_response()->clear_response();
-  policy_response_.mutable_policy_response()->add_response()->set_policy_data(
+  policy_response_.mutable_policy_response()->clear_responses();
+  policy_response_.mutable_policy_response()->add_responses()->set_policy_data(
       CreatePolicyData("updated-fake-policy-data"));
   ExpectPolicyFetch(kDMToken);
   EXPECT_CALL(observer_, OnPolicyFetched(_));
@@ -866,7 +867,7 @@
   client_->set_last_policy_timestamp(timestamp);
   client_->set_public_key_version(42);
   em::PolicyFetchRequest* policy_fetch_request =
-      policy_request_.mutable_policy_request()->mutable_request(0);
+      policy_request_.mutable_policy_request()->mutable_requests(0);
   policy_fetch_request->set_timestamp(timestamp.ToJavaTime());
   policy_fetch_request->set_public_key_version(42);
 
@@ -883,7 +884,7 @@
   client_->SetInvalidationInfo(12345, "12345");
   EXPECT_EQ(previous_version, client_->fetched_invalidation_version());
   em::PolicyFetchRequest* policy_fetch_request =
-      policy_request_.mutable_policy_request()->mutable_request(0);
+      policy_request_.mutable_policy_request()->mutable_requests(0);
   policy_fetch_request->set_invalidation_version(12345);
   policy_fetch_request->set_invalidation_payload("12345");
 
@@ -936,9 +937,9 @@
   EXPECT_FALSE(client_->GetPolicyFor(policy_type_, std::string()));
   EXPECT_EQ(DM_STATUS_RESPONSE_DECODING_ERROR, client_->status());
 
-  policy_response_.mutable_policy_response()->add_response()->set_policy_data(
+  policy_response_.mutable_policy_response()->add_responses()->set_policy_data(
       CreatePolicyData("fake-policy-data"));
-  policy_response_.mutable_policy_response()->add_response()->set_policy_data(
+  policy_response_.mutable_policy_response()->add_responses()->set_policy_data(
       CreatePolicyData("excess-fake-policy-data"));
   ExpectPolicyFetch(kDMToken);
   EXPECT_CALL(observer_, OnPolicyFetched(_));
@@ -1016,7 +1017,7 @@
                                           std::string());
   // Copy the user policy fetch request.
   expected_responses[key].CopyFrom(
-      policy_response_.policy_response().response(0));
+      policy_response_.policy_response().responses(0));
   expected_namespaces.insert(key);
   key.first = dm_protocol::kChromeExtensionPolicyType;
   expected_namespaces.insert(key);
@@ -1026,7 +1027,7 @@
     policy_data.set_policy_type(key.first);
     policy_data.set_settings_entity_id(key.second);
     expected_responses[key].set_policy_data(policy_data.SerializeAsString());
-    policy_response_.mutable_policy_response()->add_response()->CopyFrom(
+    policy_response_.mutable_policy_response()->add_responses()->CopyFrom(
         expected_responses[key]);
   }
 
@@ -1047,9 +1048,9 @@
   ASSERT_TRUE(policy_request_.has_policy_request());
   const em::DevicePolicyRequest& policy_request =
       policy_request_.policy_request();
-  ASSERT_EQ(2, policy_request.request_size());
-  for (int i = 0; i < policy_request.request_size(); ++i) {
-    const em::PolicyFetchRequest& fetch_request = policy_request.request(i);
+  ASSERT_EQ(2, policy_request.requests_size());
+  for (int i = 0; i < policy_request.requests_size(); ++i) {
+    const em::PolicyFetchRequest& fetch_request = policy_request.requests(i);
     ASSERT_TRUE(fetch_request.has_policy_type());
     EXPECT_FALSE(fetch_request.has_settings_entity_id());
     std::pair<std::string, std::string> key(fetch_request.policy_type(),
@@ -1481,7 +1482,7 @@
   // Starting another app push-install report upload should cancel the pending
   // one.
   request.mutable_app_install_report_request()
-      ->add_app_install_report()
+      ->add_app_install_reports()
       ->set_package(kPackageName);
   ExpectUploadAppInstallReport(request, &async_job);
   EXPECT_CALL(callback_observer_, OnCallbackComplete(true)).Times(1);
diff --git a/components/policy/core/common/cloud/device_management_service_unittest.cc b/components/policy/core/common/cloud/device_management_service_unittest.cc
index 68d0a53..3517d306 100644
--- a/components/policy/core/common/cloud/device_management_service_unittest.cc
+++ b/components/policy/core/common/cloud/device_management_service_unittest.cc
@@ -167,7 +167,7 @@
     job->SetOAuthTokenParameter(kOAuthToken);
     job->SetClientID(kClientID);
     em::PolicyFetchRequest* fetch_request =
-        job->GetRequest()->mutable_policy_request()->add_request();
+        job->GetRequest()->mutable_policy_request()->add_requests();
     fetch_request->set_policy_type(dm_protocol::kChromeUserPolicyType);
     job->SetRetryCallback(base::Bind(
         &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this)));
@@ -184,7 +184,7 @@
     job->SetClientID(kClientID);
     job->SetCritical(true);
     em::PolicyFetchRequest* fetch_request =
-        job->GetRequest()->mutable_policy_request()->add_request();
+        job->GetRequest()->mutable_policy_request()->add_requests();
     fetch_request->set_policy_type(dm_protocol::kChromeUserPolicyType);
     job->SetRetryCallback(base::Bind(
         &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this)));
diff --git a/components/policy/core/common/config_dir_policy_loader_unittest.cc b/components/policy/core/common/config_dir_policy_loader_unittest.cc
index 632880a7..4c64d97 100644
--- a/components/policy/core/common/config_dir_policy_loader_unittest.cc
+++ b/components/policy/core/common/config_dir_policy_loader_unittest.cc
@@ -240,6 +240,16 @@
       .LoadFrom(&test_dict_foo, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                 POLICY_SOURCE_PLATFORM);
   for (unsigned int i = 1; i <= 8; ++i) {
+    auto conflict_policy =
+        expected_bundle
+            .Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+            .Get(kHomepageLocation)
+            ->DeepCopy();
+    conflict_policy.conflicts.clear();
+    conflict_policy.value = std::make_unique<base::Value>("http://bar.com");
+    expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+        .GetMutable(kHomepageLocation)
+        ->AddConflictingPolicy(conflict_policy);
     expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
         .GetMutable(kHomepageLocation)
         ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
diff --git a/components/policy/core/common/policy_bundle_unittest.cc b/components/policy/core/common/policy_bundle_unittest.cc
index ce44509..daa5383 100644
--- a/components/policy/core/common/policy_bundle_unittest.cc
+++ b/components/policy/core/common/policy_bundle_unittest.cc
@@ -194,13 +194,21 @@
   expected.Set(kPolicyClashing0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(0), nullptr);
   expected.GetMutable(kPolicyClashing0)
+      ->AddConflictingPolicy(*policy1.Get(kPolicyClashing0));
+  expected.GetMutable(kPolicyClashing0)
+      ->AddConflictingPolicy(*policy2.Get(kPolicyClashing0));
+  expected.GetMutable(kPolicyClashing0)
       ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
   expected.GetMutable(kPolicyClashing0)
       ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
   expected.Set(kPolicyClashing1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
                POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(1), nullptr);
   expected.GetMutable(kPolicyClashing1)
-      ->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
+      ->AddConflictingPolicy(*policy0.Get(kPolicyClashing1));
+  expected.GetMutable(kPolicyClashing1)
+      ->AddConflictingPolicy(*policy2.Get(kPolicyClashing1));
+  expected.GetMutable(kPolicyClashing1)
+      ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
   expected.GetMutable(kPolicyClashing1)
       ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
   expected.Set(kPolicy0, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
diff --git a/components/policy/core/common/policy_loader_win_unittest.cc b/components/policy/core/common/policy_loader_win_unittest.cc
index d564ee86..311e7fb 100644
--- a/components/policy/core/common/policy_loader_win_unittest.cc
+++ b/components/policy/core/common/policy_loader_win_unittest.cc
@@ -452,6 +452,13 @@
   expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .GetMutable(test_keys::kKeyString)
       ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+
+  PolicyMap::Entry conflict(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                            POLICY_SOURCE_PLATFORM,
+                            std::make_unique<base::Value>("hkcu"), nullptr);
+  expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+      .GetMutable(test_keys::kKeyString)
+      ->AddConflictingPolicy(conflict);
   EXPECT_TRUE(Matches(expected));
 }
 
@@ -507,16 +514,46 @@
   expected_policy.GetMutable("a")->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
   expected_policy.GetMutable("a")->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
   expected_policy.GetMutable("a")->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+
+  PolicyMap::Entry a_conflict_1(
+      POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM,
+      std::make_unique<base::Value>(kMachineRecommended), nullptr);
+  PolicyMap::Entry a_conflict_2(
+      POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM,
+      std::make_unique<base::Value>(kUserMandatory), nullptr);
+  PolicyMap::Entry a_conflict_3(
+      POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM,
+      std::make_unique<base::Value>(kUserRecommended), nullptr);
+  expected_policy.GetMutable("a")->AddConflictingPolicy(a_conflict_1);
+  expected_policy.GetMutable("a")->AddConflictingPolicy(a_conflict_2);
+  expected_policy.GetMutable("a")->AddConflictingPolicy(a_conflict_3);
+
   expected_policy.Set("b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                       POLICY_SOURCE_PLATFORM,
                       std::make_unique<base::Value>(kUserMandatory), nullptr);
-  expected_policy.GetMutable("b")->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
   expected_policy.GetMutable("b")->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  expected_policy.GetMutable("b")->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+
+  PolicyMap::Entry b_conflict_1(
+      POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM,
+      std::make_unique<base::Value>(kMachineRecommended), nullptr);
+  PolicyMap::Entry b_conflict_2(
+      POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM,
+      std::make_unique<base::Value>(kUserRecommended), nullptr);
+  expected_policy.GetMutable("b")->AddConflictingPolicy(b_conflict_1);
+  expected_policy.GetMutable("b")->AddConflictingPolicy(b_conflict_2);
+
   expected_policy.Set("c", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
                       POLICY_SOURCE_PLATFORM,
                       std::make_unique<base::Value>(kMachineRecommended),
                       nullptr);
   expected_policy.GetMutable("c")->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+
+  PolicyMap::Entry c_conflict_1(
+      POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM,
+      std::make_unique<base::Value>(kUserRecommended), nullptr);
+  expected_policy.GetMutable("c")->AddConflictingPolicy(c_conflict_1);
+
   expected_policy.Set("d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
                       POLICY_SOURCE_PLATFORM,
                       std::make_unique<base::Value>(kUserRecommended), nullptr);
diff --git a/components/policy/core/common/policy_map.cc b/components/policy/core/common/policy_map.cc
index 8e4b97739..2d8a2d6 100644
--- a/components/policy/core/common/policy_map.cc
+++ b/components/policy/core/common/policy_map.cc
@@ -5,6 +5,7 @@
 #include "components/policy/core/common/policy_map.h"
 
 #include <algorithm>
+#include <utility>
 
 #include "base/callback.h"
 #include "base/stl_util.h"
@@ -14,6 +15,17 @@
 
 namespace policy {
 PolicyMap::Entry::Entry() = default;
+PolicyMap::Entry::Entry(
+    PolicyLevel level,
+    PolicyScope scope,
+    PolicySource source,
+    std::unique_ptr<base::Value> value,
+    std::unique_ptr<ExternalDataFetcher> external_data_fetcher)
+    : level(level),
+      scope(scope),
+      source(source),
+      value(std::move(value)),
+      external_data_fetcher(std::move(external_data_fetcher)) {}
 
 PolicyMap::Entry::~Entry() = default;
 
@@ -33,6 +45,9 @@
     copy.external_data_fetcher.reset(
         new ExternalDataFetcher(*external_data_fetcher));
   }
+  for (const auto& conflict : conflicts) {
+    copy.AddConflictingPolicy(conflict);
+  }
   return copy;
 }
 
@@ -48,7 +63,11 @@
 }
 
 bool PolicyMap::Entry::Equals(const PolicyMap::Entry& other) const {
-  return level == other.level && scope == other.scope &&
+  bool conflicts_are_equal = conflicts.size() == other.conflicts.size();
+  for (size_t i = 0; conflicts_are_equal && i < conflicts.size(); ++i)
+    conflicts_are_equal &= conflicts[i].Equals(other.conflicts[i]);
+
+  return conflicts_are_equal && level == other.level && scope == other.scope &&
          source == other.source &&  // Necessary for PolicyUIHandler observers.
                                     // They have to update when sources change.
          error_strings_ == other.error_strings_ &&
@@ -67,6 +86,20 @@
   error_message_ids_.push_back(message_id);
 }
 
+void PolicyMap::Entry::AddConflictingPolicy(const Entry& conflict) {
+  Entry conflicted_policy_copy = conflict.DeepCopy();
+
+  for (const auto& conflict : conflicted_policy_copy.conflicts) {
+    AddConflictingPolicy(conflict);
+  }
+
+  // Avoid conflict nesting
+  conflicted_policy_copy.conflicts.clear();
+  conflicted_policy_copy.error_message_ids_.clear();
+  conflicted_policy_copy.error_strings_.clear();
+  conflicts.push_back(std::move(conflicted_policy_copy));
+}
+
 base::string16 PolicyMap::Entry::GetLocalizedErrors(
     L10nLookupFunction lookup) const {
   base::string16 error_string = base::UTF8ToUTF16(error_strings_);
@@ -114,12 +147,8 @@
     PolicySource source,
     std::unique_ptr<base::Value> value,
     std::unique_ptr<ExternalDataFetcher> external_data_fetcher) {
-  Entry entry;
-  entry.level = level;
-  entry.scope = scope;
-  entry.source = source;
-  entry.value = std::move(value);
-  entry.external_data_fetcher = std::move(external_data_fetcher);
+  Entry entry(level, scope, source, std::move(value),
+              std::move(external_data_fetcher));
   Set(policy, std::move(entry));
 }
 
@@ -173,14 +202,25 @@
 
 void PolicyMap::MergeFrom(const PolicyMap& other) {
   for (const auto& it : other) {
-    Entry* entry = GetMutable(it.first);
-    if (!entry || it.second.has_higher_priority_than(*entry))
+    const Entry* entry = Get(it.first);
+    bool same_value = false;
+    if (!entry) {
       Set(it.first, it.second.DeepCopy());
+    } else {
+      same_value = entry->value && it.second.value->Equals(entry->value.get());
+      if (it.second.has_higher_priority_than(*entry)) {
+        auto new_policy = it.second.DeepCopy();
+        new_policy.AddConflictingPolicy(*entry);
+        Set(it.first, std::move(new_policy));
+      } else {
+        GetMutable(it.first)->AddConflictingPolicy(it.second);
+      }
+    }
+
     if (entry) {
-      if (entry->value && it.second.value->Equals(entry->value.get()))
-        GetMutable(it.first)->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
-      else
-        GetMutable(it.first)->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+      GetMutable(it.first)->AddError(same_value
+                                         ? IDS_POLICY_CONFLICT_SAME_VALUE
+                                         : IDS_POLICY_CONFLICT_DIFF_VALUE);
     }
   }
 }
diff --git a/components/policy/core/common/policy_map.h b/components/policy/core/common/policy_map.h
index f693073a..faff353 100644
--- a/components/policy/core/common/policy_map.h
+++ b/components/policy/core/common/policy_map.h
@@ -30,13 +30,18 @@
    public:
     PolicyLevel level = POLICY_LEVEL_RECOMMENDED;
     PolicyScope scope = POLICY_SCOPE_USER;
-    std::unique_ptr<base::Value> value;
-    std::unique_ptr<ExternalDataFetcher> external_data_fetcher;
-
     // For debugging and displaying only. Set by provider delivering the policy.
     PolicySource source = POLICY_SOURCE_ENTERPRISE_DEFAULT;
+    std::unique_ptr<base::Value> value;
+    std::unique_ptr<ExternalDataFetcher> external_data_fetcher;
+    std::vector<Entry> conflicts;
 
     Entry();
+    Entry(PolicyLevel level,
+          PolicyScope scope,
+          PolicySource source,
+          std::unique_ptr<base::Value> value,
+          std::unique_ptr<ExternalDataFetcher> external_data_fetcher);
     ~Entry();
 
     Entry(Entry&&) noexcept;
@@ -57,6 +62,9 @@
     // Add a localized error given its l10n message ID.
     void AddError(int message_id);
 
+    // Adds a conflicting policy.
+    void AddConflictingPolicy(const Entry& conflict);
+
     // Callback used to look up a localized string given its l10n message ID. It
     // should return a UTF-16 string.
     typedef base::RepeatingCallback<base::string16(int message_id)>
diff --git a/components/policy/core/common/policy_map_unittest.cc b/components/policy/core/common/policy_map_unittest.cc
index 1d7857b6..873f2578 100644
--- a/components/policy/core/common/policy_map_unittest.cc
+++ b/components/policy/core/common/policy_map_unittest.cc
@@ -232,6 +232,11 @@
         POLICY_SOURCE_ACTIVE_DIRECTORY, std::make_unique<base::Value>(true),
         nullptr);
 
+  auto conflicted_policy_1 = a.Get(kTestPolicyName1)->DeepCopy();
+  auto conflicted_policy_4 = a.Get(kTestPolicyName4)->DeepCopy();
+  auto conflicted_policy_5 = a.Get(kTestPolicyName5)->DeepCopy();
+  auto conflicted_policy_7 = a.Get(kTestPolicyName7)->DeepCopy();
+
   a.MergeFrom(b);
 
   PolicyMap c;
@@ -239,25 +244,32 @@
   c.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("chromium.org"),
         nullptr);
-  c.GetMutable(kTestPolicyName1)->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
+  c.GetMutable(kTestPolicyName1)->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  c.GetMutable(kTestPolicyName1)->AddConflictingPolicy(conflicted_policy_1);
   // |a| has precedence over |b|.
   c.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(true), nullptr);
   c.GetMutable(kTestPolicyName2)->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  c.GetMutable(kTestPolicyName2)
+      ->AddConflictingPolicy(*b.Get(kTestPolicyName2));
   c.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_ENTERPRISE_DEFAULT, nullptr,
         CreateExternalDataFetcher("a"));
   c.GetMutable(kTestPolicyName3)->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  c.GetMutable(kTestPolicyName3)
+      ->AddConflictingPolicy(*b.Get(kTestPolicyName3));
   // POLICY_SCOPE_MACHINE over POLICY_SCOPE_USER for POLICY_LEVEL_RECOMMENDED.
   c.Set(kTestPolicyName4, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_PUBLIC_SESSION_OVERRIDE,
         std::make_unique<base::Value>(true), nullptr);
-  c.GetMutable(kTestPolicyName4)->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
+  c.GetMutable(kTestPolicyName4)->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  c.GetMutable(kTestPolicyName4)->AddConflictingPolicy(conflicted_policy_4);
   // POLICY_LEVEL_MANDATORY over POLICY_LEVEL_RECOMMENDED.
   c.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_PLATFORM, std::make_unique<base::Value>(std::string()),
         nullptr);
-  c.GetMutable(kTestPolicyName5)->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
+  c.GetMutable(kTestPolicyName5)->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  c.GetMutable(kTestPolicyName5)->AddConflictingPolicy(conflicted_policy_5);
   // Merge new ones.
   c.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
         POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(true), nullptr);
@@ -265,7 +277,8 @@
   c.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
         POLICY_SOURCE_ACTIVE_DIRECTORY, std::make_unique<base::Value>(true),
         nullptr);
-  c.GetMutable(kTestPolicyName7)->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
+  c.GetMutable(kTestPolicyName7)->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  c.GetMutable(kTestPolicyName7)->AddConflictingPolicy(conflicted_policy_7);
 
   EXPECT_TRUE(a.Equals(c));
 }
@@ -378,4 +391,28 @@
   EXPECT_TRUE(a.Equals(b));
 }
 
+TEST_F(PolicyMapTest, EntryAddConflict) {
+  PolicyMap::Entry entry_a;
+  entry_a.level = POLICY_LEVEL_MANDATORY;
+  entry_a.source = POLICY_SOURCE_CLOUD;
+  entry_a.value = std::make_unique<base::Value>(true);
+  entry_a.scope = POLICY_SCOPE_USER;
+  PolicyMap::Entry entry_b = entry_a.DeepCopy();
+  entry_b.value = std::make_unique<base::Value>(false);
+  PolicyMap::Entry entry_b_no_conflicts = entry_b.DeepCopy();
+  PolicyMap::Entry entry_c = entry_a.DeepCopy();
+  entry_c.source = POLICY_SOURCE_PLATFORM;
+
+  entry_b.AddConflictingPolicy(entry_c);
+  entry_a.AddConflictingPolicy(entry_b);
+
+  EXPECT_TRUE(entry_a.conflicts.size() == 2);
+  EXPECT_TRUE(entry_b.conflicts.size() == 1);
+  EXPECT_TRUE(entry_c.conflicts.empty());
+
+  EXPECT_TRUE(entry_a.conflicts[0].Equals(entry_c));
+  EXPECT_TRUE(entry_a.conflicts[1].Equals(entry_b_no_conflicts));
+  EXPECT_TRUE(entry_b.conflicts[0].Equals(entry_c));
+}
+
 }  // namespace policy
diff --git a/components/policy/core/common/policy_service_impl_unittest.cc b/components/policy/core/common/policy_service_impl_unittest.cc
index 0aec35e9..62b59b1 100644
--- a/components/policy/core/common/policy_service_impl_unittest.cc
+++ b/components/policy/core/common/policy_service_impl_unittest.cc
@@ -374,6 +374,9 @@
   provider0_.UpdateChromePolicy(policy0_);
   provider1_.UpdateChromePolicy(policy1_);
   provider2_.UpdateChromePolicy(policy2_);
+  expected.GetMutable("aaa")->AddConflictingPolicy(*policy1_.Get("aaa"));
+  expected.GetMutable("aaa")->AddConflictingPolicy(*policy2_.Get("aaa"));
+
   EXPECT_TRUE(VerifyPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()), expected));
 
@@ -382,6 +385,7 @@
   expected.GetMutable("aaa")->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
   policy0_.Erase("aaa");
   provider0_.UpdateChromePolicy(policy0_);
+  expected.GetMutable("aaa")->AddConflictingPolicy(*policy2_.Get("aaa"));
   EXPECT_TRUE(VerifyPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()), expected));
 
@@ -390,7 +394,8 @@
   expected.GetMutable("aaa")->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
   policy1_.Set("aaa", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
                POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(1), nullptr);
-  provider1_.UpdateChromePolicy(policy1_);
+  expected.GetMutable("aaa")->AddConflictingPolicy(*policy2_.Get("aaa"));
+  provider1_.UpdateChromePolicy(policy2_);
   EXPECT_TRUE(VerifyPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()), expected));
 }
@@ -531,11 +536,6 @@
   AddTestPolicies(bundle2.get(), "bundle2",
                   POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
 
-  provider0_.UpdatePolicy(std::move(bundle0));
-  provider1_.UpdatePolicy(std::move(bundle1));
-  provider2_.UpdatePolicy(std::move(bundle2));
-  RunUntilIdle();
-
   PolicyMap expected;
   // For policies of the same level and scope, the first provider takes
   // precedence, on every namespace.
@@ -546,13 +546,35 @@
       ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
   expected.GetMutable(kSameLevelPolicy)
       ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  expected.GetMutable(kSameLevelPolicy)
+      ->AddConflictingPolicy(
+          *bundle1->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+               .Get(kSameLevelPolicy));
+  expected.GetMutable(kSameLevelPolicy)
+      ->AddConflictingPolicy(
+          *bundle2->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+               .Get(kSameLevelPolicy));
   // For policies with different levels and scopes, the highest priority
   // level/scope combination takes precedence, on every namespace.
   expected.Set(kDiffLevelPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
                POLICY_SOURCE_PLATFORM, std::make_unique<base::Value>("bundle2"),
                nullptr);
   expected.GetMutable(kDiffLevelPolicy)
-      ->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
+      ->AddError(IDS_POLICY_CONFLICT_DIFF_VALUE);
+  expected.GetMutable(kDiffLevelPolicy)
+      ->AddConflictingPolicy(
+          *bundle0->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+               .Get(kDiffLevelPolicy));
+  expected.GetMutable(kDiffLevelPolicy)
+      ->AddConflictingPolicy(
+          *bundle1->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+               .Get(kDiffLevelPolicy));
+
+  provider0_.UpdatePolicy(std::move(bundle0));
+  provider1_.UpdatePolicy(std::move(bundle1));
+  provider2_.UpdatePolicy(std::move(bundle2));
+  RunUntilIdle();
+
   EXPECT_TRUE(policy_service_->GetPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())).Equals(expected));
   EXPECT_TRUE(policy_service_->GetPolicies(
diff --git a/components/policy/core/common/schema_map_unittest.cc b/components/policy/core/common/schema_map_unittest.cc
index 0bee8f3..cc8a211 100644
--- a/components/policy/core/common/schema_map_unittest.cc
+++ b/components/policy/core/common/schema_map_unittest.cc
@@ -185,6 +185,10 @@
   // Merged twice so this causes a conflict.
   expected_bundle.Get(chrome_ns)
       .GetMutable("ChromePolicy")
+      ->AddConflictingPolicy(
+          *expected_bundle.Get(chrome_ns).Get("ChromePolicy"));
+  expected_bundle.Get(chrome_ns)
+      .GetMutable("ChromePolicy")
       ->AddError(IDS_POLICY_CONFLICT_SAME_VALUE);
   EXPECT_TRUE(bundle.Equals(expected_bundle));
 
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index 347009fc..a8b9f46 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -240,7 +240,7 @@
 // Request to access a Google service with the given scope.
 message DeviceServiceApiAccessRequest {
   // The list of auth scopes the device requests from DMServer.
-  repeated string auth_scope = 1;
+  repeated string auth_scopes = 1;
 
   // OAuth2 client ID to which the returned authorization code is bound.
   optional string oauth2_client_id = 2;
@@ -648,16 +648,16 @@
 
 // Request from device to server for reading policies.
 message DevicePolicyRequest {
-  // The policy fetch request.  If this field exists, the request must
-  // comes from a non-TT client.  The repeated field allows client to
-  // request multiple policies for better performance.
-  repeated PolicyFetchRequest request = 3;
+  // The policy fetch requests.  If this field exists, the requests must come
+  // from a non-TT client.  The repeated field allows clients to request
+  // multiple policies for better performance.
+  repeated PolicyFetchRequest requests = 3;
 }
 
 // Response from server to device for reading policies.
 message DevicePolicyResponse {
-  // The policy fetch response.
-  repeated PolicyFetchResponse response = 3;
+  // The policy fetch responses.
+  repeated PolicyFetchResponse responses = 3;
 }
 
 message TimePeriod {
@@ -817,7 +817,7 @@
   optional int64 full_charge_capacity = 5;
   optional int32 cycle_count = 6;
   // Last sampling data.
-  repeated BatterySample sample = 7;
+  repeated BatterySample samples = 7;
   // Designed minimum output voltage (mV)
   optional int32 design_min_voltage = 9;
 }
@@ -862,12 +862,12 @@
 message ThermalInfo {
   reserved 2;
   optional string label = 1;
-  repeated ThermalSample sample = 3;
+  repeated ThermalSample samples = 3;
 }
 
 // Status for various on-board components
 message BoardStatus {
-  repeated ThermalInfo thermal = 1;
+  repeated ThermalInfo thermal_infos = 1;
 }
 
 // Report device level status.
@@ -888,32 +888,32 @@
   optional string browser_version = 5;
 
   // A list of periods when the device was active, aggregated by day by user.
-  repeated ActiveTimePeriod active_period = 6;
+  repeated ActiveTimePeriod active_periods = 6;
 
   // List of network interfaces.
-  repeated NetworkInterface network_interface = 8;
+  repeated NetworkInterface network_interfaces = 8;
 
   // List of recent device users, in descending order by last login time.
-  repeated DeviceUser user = 9;
+  repeated DeviceUser users = 9;
 
   // Disk space + other info about mounted/connected volumes.
-  repeated VolumeInfo volume_info = 10;
+  repeated VolumeInfo volume_infos = 10;
 
   // List of visible/configured networks
-  repeated NetworkState network_state = 11;
+  repeated NetworkState network_states = 11;
 
   // Samples of CPU utilization (0-100), sampled once every 120 seconds.
-  repeated int32 cpu_utilization_pct = 12;
+  repeated int32 cpu_utilization_pct_samples = 12;
 
   // Total RAM on the device.
   optional int64 system_ram_total = 14;
 
   // Samples of free RAM [in bytes] (unreliable due to GC).
-  repeated int64 system_ram_free = 15;
+  repeated int64 system_ram_free_samples = 15;
 
   // Samples of CPU temperatures in Celsius, plus associated labels
   // identifying which CPU produced the temperature measurement.
-  repeated CPUTempInfo cpu_temp_info = 16;
+  repeated CPUTempInfo cpu_temp_infos = 16;
 
   // This field is set only when an OS update is needed because of the required
   // platform version of an updated kiosk app is different from the current
@@ -1303,7 +1303,7 @@
   // enrollment should be optional.
   // The format of each entry depends on the |enrollment_check_type| that was
   // set in the DeviceAutoEnrollmentRequest.
-  repeated bytes hash = 2;
+  repeated bytes hashes = 2;
 }
 
 // Sent by the client to the server. The device management server keeps a
@@ -1327,7 +1327,7 @@
   // algorithm that takes stable device identifiers as an input and produces a
   // key as the output, possibly by running the identifiers through a
   // cryptographic hash function such as SHA-256.
-  repeated bytes server_backed_state_key = 1;
+  repeated bytes server_backed_state_keys = 1;
 }
 
 // Server to client message carrying the device state response. Because the
@@ -1759,7 +1759,7 @@
   // contains more than one entry then device should display a screen asking
   // user to choose license type and send selected license type value in the
   // DeviceRegisterRequest.license_type field.
-  repeated LicenseAvailability license_availability = 2;
+  repeated LicenseAvailability license_availabilities = 2;
 }
 
 // Sign in an Active Directory user using SAML SSO. The device management server
@@ -1808,7 +1808,7 @@
 // System state included with some log events.
 message SystemState {
   // VolumeInfo is reused from existing Chrome reporting.
-  repeated VolumeInfo volume_info = 1;
+  repeated VolumeInfo volume_infos = 1;
 }
 
 // A single entry in the push-install log for an app.
@@ -1894,13 +1894,13 @@
   optional bool incomplete = 2;
 
   // Log events for the app.
-  repeated AppInstallReportLogEvent log = 3;
+  repeated AppInstallReportLogEvent logs = 3;
 }
 
 // Push-install logs for all apps.
 message AppInstallReportRequest {
   // Log buckets for each app.
-  repeated AppInstallReport app_install_report = 1;
+  repeated AppInstallReport app_install_reports = 1;
 }
 
 // Response from server after receiving a report on the status of app
diff --git a/components/resources/autofill_scaled_resources.grdp b/components/resources/autofill_scaled_resources.grdp
index 40cb93f..968175c 100644
--- a/components/resources/autofill_scaled_resources.grdp
+++ b/components/resources/autofill_scaled_resources.grdp
@@ -27,6 +27,7 @@
 
   <if expr="not is_android and not is_ios">
     <structure type="chrome_scaled_image" name="IDR_AUTOFILL_MIGRATION_DIALOG_HEADER" file="autofill/migration_header.png" />
+    <structure type="chrome_scaled_image" name="IDR_AUTOFILL_MIGRATION_DIALOG_HEADER_DARK" file="autofill/migration_header_dark.png" />
   </if>
 
   <structure type="chrome_scaled_image" name="IDR_CREDIT_CARD_CVC_HINT" file="autofill/credit_card_cvc_hint.png" />
diff --git a/components/resources/default_100_percent/autofill/migration_header_dark.png b/components/resources/default_100_percent/autofill/migration_header_dark.png
new file mode 100644
index 0000000..5893ea3
--- /dev/null
+++ b/components/resources/default_100_percent/autofill/migration_header_dark.png
Binary files differ
diff --git a/components/resources/default_200_percent/autofill/migration_header_dark.png b/components/resources/default_200_percent/autofill/migration_header_dark.png
new file mode 100644
index 0000000..b39066c
--- /dev/null
+++ b/components/resources/default_200_percent/autofill/migration_header_dark.png
Binary files differ
diff --git a/components/resources/default_300_percent/autofill/migration_header_dark.png b/components/resources/default_300_percent/autofill/migration_header_dark.png
new file mode 100644
index 0000000..37992e47b
--- /dev/null
+++ b/components/resources/default_300_percent/autofill/migration_header_dark.png
Binary files differ
diff --git a/components/send_tab_to_self/send_tab_to_self_entry.cc b/components/send_tab_to_self/send_tab_to_self_entry.cc
index 6fc811f..433c782 100644
--- a/components/send_tab_to_self/send_tab_to_self_entry.cc
+++ b/components/send_tab_to_self/send_tab_to_self_entry.cc
@@ -11,6 +11,22 @@
 
 namespace send_tab_to_self {
 
+namespace {
+
+// Converts a time object to the format used in sync protobufs (ms since the
+// Windows epoch).
+int64_t TimeToProtoTime(const base::Time t) {
+  return t.ToDeltaSinceWindowsEpoch().InMicroseconds();
+}
+
+// Converts a time field from sync protobufs to a time object.
+base::Time ProtoTimeToTime(int64_t proto_t) {
+  return base::Time::FromDeltaSinceWindowsEpoch(
+      base::TimeDelta::FromMicroseconds(proto_t));
+}
+
+}  // namespace
+
 SendTabToSelfEntry::SendTabToSelfEntry(const std::string& guid,
                                        const GURL& url,
                                        const std::string& title,
@@ -60,10 +76,9 @@
   pb_entry->set_guid(GetGUID());
   pb_entry->set_title(GetTitle());
   pb_entry->set_url(GetURL().spec());
-  pb_entry->set_shared_time_usec(
-      GetSharedTime().ToDeltaSinceWindowsEpoch().InMicroseconds());
+  pb_entry->set_shared_time_usec(TimeToProtoTime(GetSharedTime()));
   pb_entry->set_navigation_time_usec(
-      GetOriginalNavigationTime().ToDeltaSinceWindowsEpoch().InMicroseconds());
+      TimeToProtoTime(GetOriginalNavigationTime()));
   pb_entry->set_device_name(GetDeviceName());
 
   return pb_entry;
@@ -78,16 +93,14 @@
   GURL url(pb_entry.url());
   DCHECK(url.is_valid());
 
-  base::Time shared_time = base::Time::FromDeltaSinceWindowsEpoch(
-      base::TimeDelta::FromMicroseconds(pb_entry.shared_time_usec()));
+  base::Time shared_time = ProtoTimeToTime(pb_entry.shared_time_usec());
   if (shared_time > now) {
     shared_time = now;
   }
 
   base::Time navigation_time;
   if (pb_entry.has_navigation_time_usec()) {
-    navigation_time = base::Time::FromDeltaSinceWindowsEpoch(
-        base::TimeDelta::FromMicroseconds(pb_entry.navigation_time_usec()));
+    navigation_time = ProtoTimeToTime(pb_entry.navigation_time_usec());
   }
 
   return std::make_unique<SendTabToSelfEntry>(guid, url, pb_entry.title(),
diff --git a/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc b/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc
index ba55592..c276a9d 100644
--- a/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc
+++ b/components/send_tab_to_self/send_tab_to_self_entry_unittest.cc
@@ -23,6 +23,20 @@
          a.GetOriginalNavigationTime() == b.GetOriginalNavigationTime();
 }
 
+bool IsEqualForTesting(const SendTabToSelfEntry& entry,
+                       const sync_pb::SendTabToSelfSpecifics& specifics) {
+  return (
+      entry.GetGUID() == specifics.guid() &&
+      entry.GetURL() == specifics.url() &&
+      entry.GetTitle() == specifics.title() &&
+      entry.GetDeviceName() == specifics.device_name() &&
+      specifics.shared_time_usec() ==
+          entry.GetSharedTime().ToDeltaSinceWindowsEpoch().InMicroseconds() &&
+      specifics.navigation_time_usec() == entry.GetOriginalNavigationTime()
+                                              .ToDeltaSinceWindowsEpoch()
+                                              .InMicroseconds());
+}
+
 TEST(SendTabToSelfEntry, CompareEntries) {
   const SendTabToSelfEntry e1("1", GURL("http://example.com"), "bar",
                               base::Time::FromTimeT(10),
@@ -54,18 +68,8 @@
   SendTabToSelfEntry entry("1", GURL("http://example.com"), "bar",
                            base::Time::FromTimeT(10), base::Time::FromTimeT(10),
                            "device");
-  base::Time shared_time = entry.GetSharedTime();
-  base::Time navigation_time = entry.GetSharedTime();
-
   std::unique_ptr<sync_pb::SendTabToSelfSpecifics> pb_entry(entry.AsProto());
-  EXPECT_EQ(pb_entry->url(), "http://example.com/");
-  EXPECT_EQ(pb_entry->title(), "bar");
-  EXPECT_EQ(pb_entry->shared_time_usec(),
-            shared_time.ToDeltaSinceWindowsEpoch().InMicroseconds());
-
-  EXPECT_EQ(pb_entry->navigation_time_usec(),
-            navigation_time.ToDeltaSinceWindowsEpoch().InMicroseconds());
-  EXPECT_EQ(pb_entry->device_name(), "device");
+  EXPECT_TRUE(IsEqualForTesting(entry, *pb_entry));
 }
 
 // Tests that the send tab to self entry is correctly parsed from
@@ -83,16 +87,7 @@
   std::unique_ptr<SendTabToSelfEntry> entry(
       SendTabToSelfEntry::FromProto(*pb_entry, base::Time::FromTimeT(10)));
 
-  EXPECT_EQ(entry->GetGUID(), "1");
-  EXPECT_EQ(entry->GetURL().spec(), "http://example.com/");
-  EXPECT_EQ(entry->GetTitle(), "title");
-  EXPECT_EQ(entry->GetDeviceName(), "device");
-  EXPECT_EQ(entry->GetSharedTime().ToDeltaSinceWindowsEpoch().InMicroseconds(),
-            1);
-  EXPECT_EQ(entry->GetOriginalNavigationTime()
-                .ToDeltaSinceWindowsEpoch()
-                .InMicroseconds(),
-            1);
+  EXPECT_TRUE(IsEqualForTesting(*entry, *pb_entry));
 }
 
 }  // namespace
diff --git a/components/sync/engine_impl/cycle/data_type_tracker.cc b/components/sync/engine_impl/cycle/data_type_tracker.cc
index 4fc64bf..27c23a9 100644
--- a/components/sync/engine_impl/cycle/data_type_tracker.cc
+++ b/components/sync/engine_impl/cycle/data_type_tracker.cc
@@ -125,10 +125,11 @@
 }
 
 void DataTypeTracker::RecordSuccessfulSyncCycle() {
-  // If we were bloacked, then we would have been excluded from this cycle's
+  // If we were blocked, then we would have been excluded from this cycle's
   // GetUpdates and Commit actions.  Our state remains unchanged.
-  if (IsBlocked())
+  if (IsBlocked()) {
     return;
+  }
 
   // Reset throttling and backoff state.
   unblock_time_ = base::TimeTicks();
@@ -152,10 +153,26 @@
     last_dropped_invalidation_.reset();
   }
 
+  // The initial sync should generally have happened as part of a "configure"
+  // sync cycle, before this method gets called (i.e. after a successful
+  // "normal" sync cycle). However, in some cases the initial sync might not
+  // have happened, e.g. if this one data type got blocked or throttled during
+  // the configure cycle. For those cases, also clear |initial_sync_required_|
+  // here.
   initial_sync_required_ = false;
+
   sync_required_to_resolve_conflict_ = false;
 }
 
+void DataTypeTracker::RecordInitialSyncDone() {
+  // If we were blocked during the initial sync cycle, then the initial sync is
+  // not actually done. Our state remains unchanged.
+  if (IsBlocked()) {
+    return;
+  }
+  initial_sync_required_ = false;
+}
+
 // This limit will take effect on all future invalidations received.
 void DataTypeTracker::UpdatePayloadBufferSize(size_t new_size) {
   payload_buffer_size_ = new_size;
@@ -166,6 +183,9 @@
 }
 
 bool DataTypeTracker::IsGetUpdatesRequired() const {
+  // TODO(crbug.com/926184): Maybe this shouldn't check IsInitialSyncRequired():
+  // The initial sync is done in a configuration cycle, while this method
+  // refers to normal cycles.
   return !IsBlocked() &&
          (HasRefreshRequestPending() || HasPendingInvalidation() ||
           IsInitialSyncRequired() || IsSyncRequiredToResolveConflict());
diff --git a/components/sync/engine_impl/cycle/data_type_tracker.h b/components/sync/engine_impl/cycle/data_type_tracker.h
index 06715dc..89771eb 100644
--- a/components/sync/engine_impl/cycle/data_type_tracker.h
+++ b/components/sync/engine_impl/cycle/data_type_tracker.h
@@ -81,6 +81,10 @@
   // function.
   void RecordSuccessfulSyncCycle();
 
+  // Records that the initial sync has completed successfully. This gets called
+  // when the initial configuration/download cycle has finished for this type.
+  void RecordInitialSyncDone();
+
   // Updates the size of the invalidations payload buffer.
   void UpdatePayloadBufferSize(size_t new_size);
 
diff --git a/components/sync/engine_impl/cycle/nudge_tracker.cc b/components/sync/engine_impl/cycle/nudge_tracker.cc
index 9cab8ec1..6f28bf3 100644
--- a/components/sync/engine_impl/cycle/nudge_tracker.cc
+++ b/components/sync/engine_impl/cycle/nudge_tracker.cc
@@ -122,6 +122,14 @@
   }
 }
 
+void NudgeTracker::RecordInitialSyncDone(ModelTypeSet types) {
+  for (ModelType type : types) {
+    TypeTrackerMap::const_iterator tracker_it = type_trackers_.find(type);
+    DCHECK(tracker_it != type_trackers_.end()) << ModelTypeToString(type);
+    tracker_it->second->RecordInitialSyncDone();
+  }
+}
+
 base::TimeDelta NudgeTracker::RecordLocalChange(ModelTypeSet types) {
   // Start with the longest delay.
   base::TimeDelta delay =
diff --git a/components/sync/engine_impl/cycle/nudge_tracker.h b/components/sync/engine_impl/cycle/nudge_tracker.h
index f3f1716a..496bfa8d 100644
--- a/components/sync/engine_impl/cycle/nudge_tracker.h
+++ b/components/sync/engine_impl/cycle/nudge_tracker.h
@@ -51,6 +51,10 @@
   // completed successfully, as the result of a "normal" sync cycle.
   void RecordSuccessfulSyncCycle(ModelTypeSet types);
 
+  // Tells this class that the initial sync has happened for the given |types|,
+  // generally due to a "configuration" cycle.
+  void RecordInitialSyncDone(ModelTypeSet types);
+
   // Takes note of a local change.
   // Returns the shortest nudge delay from the tracker of each type in |types|.
   base::TimeDelta RecordLocalChange(ModelTypeSet types);
diff --git a/components/sync/engine_impl/cycle/nudge_tracker_unittest.cc b/components/sync/engine_impl/cycle/nudge_tracker_unittest.cc
index a38be36..140861b 100644
--- a/components/sync/engine_impl/cycle/nudge_tracker_unittest.cc
+++ b/components/sync/engine_impl/cycle/nudge_tracker_unittest.cc
@@ -350,7 +350,13 @@
   // Initial sync request.
   nudge_tracker_.RecordInitialSyncRequired(BOOKMARKS);
   EXPECT_TRUE(nudge_tracker_.IsSyncRequired(ProtocolTypes()));
-  nudge_tracker_.RecordSuccessfulSyncCycle({BOOKMARKS});
+  // Note: The initial sync happens as part of a configuration cycle, not a
+  // normal cycle, so here we need to use RecordInitialSyncDone() rather than
+  // RecordSuccessfulSyncCycle().
+  // A finished initial sync for a different data type doesn't affect us.
+  nudge_tracker_.RecordInitialSyncDone({EXTENSIONS});
+  EXPECT_TRUE(nudge_tracker_.IsSyncRequired(ProtocolTypes()));
+  nudge_tracker_.RecordInitialSyncDone({BOOKMARKS});
   EXPECT_FALSE(nudge_tracker_.IsSyncRequired(ProtocolTypes()));
 
   // Sync request for resolve conflict.
@@ -392,9 +398,12 @@
   EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired(ProtocolTypes()));
 
   // Initial sync request.
+  // TODO(crbug.com/926184): This is probably wrong; a missing initial sync
+  // should not cause IsGetUpdatesRequired(): The former happens during config
+  // cycles, but the latter refers to normal cycles.
   nudge_tracker_.RecordInitialSyncRequired(BOOKMARKS);
   EXPECT_TRUE(nudge_tracker_.IsGetUpdatesRequired(ProtocolTypes()));
-  nudge_tracker_.RecordSuccessfulSyncCycle(ProtocolTypes());
+  nudge_tracker_.RecordInitialSyncDone(ProtocolTypes());
   EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired(ProtocolTypes()));
 
   // Local changes.
diff --git a/components/sync/engine_impl/sync_scheduler_impl.cc b/components/sync/engine_impl/sync_scheduler_impl.cc
index c12e1862..ceba6a96 100644
--- a/components/sync/engine_impl/sync_scheduler_impl.cc
+++ b/components/sync/engine_impl/sync_scheduler_impl.cc
@@ -514,6 +514,11 @@
 
   if (success) {
     SDVLOG(2) << "Configure succeeded.";
+    // At this point, the initial sync for the affected types has been
+    // completed. Let the nudge tracker know to avoid any spurious extra
+    // requests; see also crbug.com/926184.
+    nudge_tracker_.RecordInitialSyncDone(
+        pending_configure_params_->types_to_download);
     pending_configure_params_->ready_task.Run();
     pending_configure_params_.reset();
     HandleSuccess();
diff --git a/components/sync/protocol/proto_value_conversions_unittest.cc b/components/sync/protocol/proto_value_conversions_unittest.cc
index 02859294..ea2176fd 100644
--- a/components/sync/protocol/proto_value_conversions_unittest.cc
+++ b/components/sync/protocol/proto_value_conversions_unittest.cc
@@ -58,54 +58,54 @@
 // default_instance().ByteSize() won't change for most changes, since most of
 // our fields are optional. So we just settle for comments in the proto files.
 
-DEFINE_SPECIFICS_TO_VALUE_TEST(encrypted);
+DEFINE_SPECIFICS_TO_VALUE_TEST(encrypted)
 
 static_assert(44 == syncer::MODEL_TYPE_COUNT,
               "When adding a new field, add a DEFINE_SPECIFICS_TO_VALUE_TEST "
               "for your field below, and optionally a test for the specific "
               "conversions.");
 
-DEFINE_SPECIFICS_TO_VALUE_TEST(app);
-DEFINE_SPECIFICS_TO_VALUE_TEST(app_list);
-DEFINE_SPECIFICS_TO_VALUE_TEST(app_notification);
-DEFINE_SPECIFICS_TO_VALUE_TEST(app_setting);
-DEFINE_SPECIFICS_TO_VALUE_TEST(arc_package);
-DEFINE_SPECIFICS_TO_VALUE_TEST(article);
-DEFINE_SPECIFICS_TO_VALUE_TEST(autofill);
-DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_profile);
-DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_wallet);
-DEFINE_SPECIFICS_TO_VALUE_TEST(bookmark);
-DEFINE_SPECIFICS_TO_VALUE_TEST(device_info);
-DEFINE_SPECIFICS_TO_VALUE_TEST(dictionary);
-DEFINE_SPECIFICS_TO_VALUE_TEST(experiments);
-DEFINE_SPECIFICS_TO_VALUE_TEST(extension);
-DEFINE_SPECIFICS_TO_VALUE_TEST(extension_setting);
-DEFINE_SPECIFICS_TO_VALUE_TEST(favicon_image);
-DEFINE_SPECIFICS_TO_VALUE_TEST(favicon_tracking);
-DEFINE_SPECIFICS_TO_VALUE_TEST(history_delete_directive);
-DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user);
-DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_setting);
-DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_shared_setting);
-DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_whitelist);
-DEFINE_SPECIFICS_TO_VALUE_TEST(mountain_share);
-DEFINE_SPECIFICS_TO_VALUE_TEST(nigori);
-DEFINE_SPECIFICS_TO_VALUE_TEST(password);
-DEFINE_SPECIFICS_TO_VALUE_TEST(preference);
-DEFINE_SPECIFICS_TO_VALUE_TEST(printer);
-DEFINE_SPECIFICS_TO_VALUE_TEST(priority_preference);
-DEFINE_SPECIFICS_TO_VALUE_TEST(reading_list);
-DEFINE_SPECIFICS_TO_VALUE_TEST(search_engine);
-DEFINE_SPECIFICS_TO_VALUE_TEST(security_event);
-DEFINE_SPECIFICS_TO_VALUE_TEST(send_tab_to_self);
-DEFINE_SPECIFICS_TO_VALUE_TEST(session);
-DEFINE_SPECIFICS_TO_VALUE_TEST(synced_notification);
-DEFINE_SPECIFICS_TO_VALUE_TEST(synced_notification_app_info);
-DEFINE_SPECIFICS_TO_VALUE_TEST(theme);
-DEFINE_SPECIFICS_TO_VALUE_TEST(typed_url);
-DEFINE_SPECIFICS_TO_VALUE_TEST(user_consent);
-DEFINE_SPECIFICS_TO_VALUE_TEST(user_event);
-DEFINE_SPECIFICS_TO_VALUE_TEST(wallet_metadata);
-DEFINE_SPECIFICS_TO_VALUE_TEST(wifi_credential);
+DEFINE_SPECIFICS_TO_VALUE_TEST(app)
+DEFINE_SPECIFICS_TO_VALUE_TEST(app_list)
+DEFINE_SPECIFICS_TO_VALUE_TEST(app_notification)
+DEFINE_SPECIFICS_TO_VALUE_TEST(app_setting)
+DEFINE_SPECIFICS_TO_VALUE_TEST(arc_package)
+DEFINE_SPECIFICS_TO_VALUE_TEST(article)
+DEFINE_SPECIFICS_TO_VALUE_TEST(autofill)
+DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_profile)
+DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_wallet)
+DEFINE_SPECIFICS_TO_VALUE_TEST(bookmark)
+DEFINE_SPECIFICS_TO_VALUE_TEST(device_info)
+DEFINE_SPECIFICS_TO_VALUE_TEST(dictionary)
+DEFINE_SPECIFICS_TO_VALUE_TEST(experiments)
+DEFINE_SPECIFICS_TO_VALUE_TEST(extension)
+DEFINE_SPECIFICS_TO_VALUE_TEST(extension_setting)
+DEFINE_SPECIFICS_TO_VALUE_TEST(favicon_image)
+DEFINE_SPECIFICS_TO_VALUE_TEST(favicon_tracking)
+DEFINE_SPECIFICS_TO_VALUE_TEST(history_delete_directive)
+DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user)
+DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_setting)
+DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_shared_setting)
+DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_whitelist)
+DEFINE_SPECIFICS_TO_VALUE_TEST(mountain_share)
+DEFINE_SPECIFICS_TO_VALUE_TEST(nigori)
+DEFINE_SPECIFICS_TO_VALUE_TEST(password)
+DEFINE_SPECIFICS_TO_VALUE_TEST(preference)
+DEFINE_SPECIFICS_TO_VALUE_TEST(printer)
+DEFINE_SPECIFICS_TO_VALUE_TEST(priority_preference)
+DEFINE_SPECIFICS_TO_VALUE_TEST(reading_list)
+DEFINE_SPECIFICS_TO_VALUE_TEST(search_engine)
+DEFINE_SPECIFICS_TO_VALUE_TEST(security_event)
+DEFINE_SPECIFICS_TO_VALUE_TEST(send_tab_to_self)
+DEFINE_SPECIFICS_TO_VALUE_TEST(session)
+DEFINE_SPECIFICS_TO_VALUE_TEST(synced_notification)
+DEFINE_SPECIFICS_TO_VALUE_TEST(synced_notification_app_info)
+DEFINE_SPECIFICS_TO_VALUE_TEST(theme)
+DEFINE_SPECIFICS_TO_VALUE_TEST(typed_url)
+DEFINE_SPECIFICS_TO_VALUE_TEST(user_consent)
+DEFINE_SPECIFICS_TO_VALUE_TEST(user_event)
+DEFINE_SPECIFICS_TO_VALUE_TEST(wallet_metadata)
+DEFINE_SPECIFICS_TO_VALUE_TEST(wifi_credential)
 
 TEST(ProtoValueConversionsTest, PasswordSpecifics) {
   sync_pb::PasswordSpecifics specifics;
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc
index d32da8b..45dd014 100644
--- a/components/user_manager/fake_user_manager.cc
+++ b/components/user_manager/fake_user_manager.cc
@@ -56,10 +56,6 @@
   return user;
 }
 
-void FakeUserManager::OnProfileInitialized(User* user) {
-  user->set_profile_ever_initialized(true);
-}
-
 void FakeUserManager::RemoveUserFromList(const AccountId& account_id) {
   const user_manager::UserList::iterator it =
       std::find_if(users_.begin(), users_.end(),
diff --git a/components/user_manager/fake_user_manager.h b/components/user_manager/fake_user_manager.h
index 48b4e49..4f87775 100644
--- a/components/user_manager/fake_user_manager.h
+++ b/components/user_manager/fake_user_manager.h
@@ -61,7 +61,6 @@
   user_manager::UserList GetUnlockUsers() const override;
   const AccountId& GetOwnerAccountId() const override;
   void OnSessionStarted() override {}
-  void OnProfileInitialized(User* user) override;
   void RemoveUser(const AccountId& account_id,
                   user_manager::RemoveUserDelegate* delegate) override {}
   void RemoveUserFromList(const AccountId& account_id) override;
diff --git a/components/user_manager/known_user.cc b/components/user_manager/known_user.cc
index 44a5bdd..8501c20 100644
--- a/components/user_manager/known_user.cc
+++ b/components/user_manager/known_user.cc
@@ -54,9 +54,6 @@
 // Key for the GaiaId migration status.
 const char kGaiaIdMigration[] = "gaia_id_migration";
 
-// Key of the boolean flag telling if user session has finished init yet.
-const char kProfileEverInitialized[] = "profile_ever_initialized";
-
 // Key of the boolean flag telling if a minimal user home migration has been
 // attempted.
 const char kMinimalMigrationAttempted[] = "minimal_migration_attempted";
@@ -488,19 +485,6 @@
   return false;
 }
 
-bool WasProfileEverInitialized(const AccountId& account_id) {
-  bool profile_ever_initialized;
-  if (GetBooleanPref(account_id, kProfileEverInitialized,
-                     &profile_ever_initialized)) {
-    return profile_ever_initialized;
-  }
-  return false;
-}
-
-void SetProfileEverInitialized(const AccountId& account_id, bool initialized) {
-  SetBooleanPref(account_id, kProfileEverInitialized, initialized);
-}
-
 void SetProfileRequiresPolicy(const AccountId& account_id,
                               ProfileRequiresPolicy required) {
   DCHECK_NE(required, ProfileRequiresPolicy::kUnknown);
diff --git a/components/user_manager/known_user.h b/components/user_manager/known_user.h
index 52a92fb5..a76f7faa 100644
--- a/components/user_manager/known_user.h
+++ b/components/user_manager/known_user.h
@@ -136,17 +136,6 @@
 // returns false.
 bool USER_MANAGER_EXPORT IsUsingSAML(const AccountId& account_id);
 
-// Returns true if the user's session has already completed initialization
-// (set to false when session is created, and then is set to true once
-// the profile is intiaiized - this allows us to detect crashes/restarts during
-// initial session creation so we can recover gracefully).
-bool USER_MANAGER_EXPORT WasProfileEverInitialized(const AccountId& account_id);
-
-// Sets the flag that denotes whether the session associated with a user has
-// completed initialization at least once.
-void USER_MANAGER_EXPORT SetProfileEverInitialized(const AccountId& account_id,
-                                                   bool initialized);
-
 // Enum describing whether a user's profile requires policy. If kPolicyRequired,
 // the profile initialization code will ensure that valid policy is loaded
 // before session initialization completes.
diff --git a/components/user_manager/user.h b/components/user_manager/user.h
index a271236267..9dc31a0 100644
--- a/components/user_manager/user.h
+++ b/components/user_manager/user.h
@@ -161,14 +161,6 @@
   // user's next sign-in.
   bool force_online_signin() const { return force_online_signin_; }
 
-  // Whether the user's session has completed initialization yet.
-  bool profile_ever_initialized() const { return profile_ever_initialized_; }
-
-  // Public so it can be called via tests.
-  void set_profile_ever_initialized(bool profile_ever_initialized) {
-    profile_ever_initialized_ = profile_ever_initialized;
-  }
-
   // True if the user's session can be locked (i.e. the user has a password with
   // which to unlock the session).
   bool can_lock() const;
@@ -289,7 +281,6 @@
   std::unique_ptr<UserImage> user_image_;
   OAuthTokenStatus oauth_token_status_ = OAUTH_TOKEN_STATUS_UNKNOWN;
   bool force_online_signin_ = false;
-  bool profile_ever_initialized_ = false;
 
   // This is set to chromeos locale if account data has been downloaded.
   // (Or failed to download, but at least one download attempt finished).
diff --git a/components/user_manager/user_manager.h b/components/user_manager/user_manager.h
index cf398fad..d13ef14 100644
--- a/components/user_manager/user_manager.h
+++ b/components/user_manager/user_manager.h
@@ -174,14 +174,6 @@
   // Invoked by session manager to inform session start.
   virtual void OnSessionStarted() = 0;
 
-  // Invoked once profile initialization has been completed. This allows various
-  // subsystems (for example, policy framework) to skip an expensive online
-  // initialization process, and also allows the signin screen to force an
-  // online signin if it knows that profile initialization has not yet
-  // completed. |user| is the User associated with the profile that has
-  // completed initialization.
-  virtual void OnProfileInitialized(User* user) = 0;
-
   // Removes the user from the device. Note, it will verify that the given user
   // isn't the owner, so calling this method for the owner will take no effect.
   // Note, |delegate| can be NULL.
@@ -324,10 +316,6 @@
       const gfx::ImageSkia& profile_image) = 0;
   virtual void NotifyUsersSignInConstraintsChanged() = 0;
 
-  // Resets this profile to be regarded as if it has never been initialized
-  // before. Used on profile wipe.
-  virtual void ResetProfileEverInitialized(const AccountId& account_id) = 0;
-
   // Returns true if supervised users allowed.
   virtual bool AreSupervisedUsersAllowed() const = 0;
 
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index 422a036..5dbb470 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -306,16 +306,6 @@
   GetLocalState()->CommitPendingWrite();
 }
 
-void UserManagerBase::OnProfileInitialized(User* user) {
-  DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence());
-
-  // Mark the user as having an initialized session and persist this in
-  // the known_user DB.
-  user->set_profile_ever_initialized(true);
-  known_user::SetProfileEverInitialized(user->GetAccountId(), true);
-  GetLocalState()->CommitPendingWrite();
-}
-
 void UserManagerBase::RemoveUser(const AccountId& account_id,
                                  RemoveUserDelegate* delegate) {
   DCHECK(!task_runner_ || task_runner_->RunsTasksInCurrentSequence());
@@ -848,8 +838,6 @@
     }
     user->set_oauth_token_status(LoadUserOAuthStatus(*it));
     user->set_force_online_signin(LoadForceOnlineSignin(*it));
-    user->set_profile_ever_initialized(
-        known_user::WasProfileEverInitialized(*it));
     user->set_using_saml(known_user::IsUsingSAML(*it));
     users_.push_back(user);
 
@@ -940,8 +928,6 @@
     active_user_->set_oauth_token_status(LoadUserOAuthStatus(account_id));
     SaveUserDisplayName(active_user_->GetAccountId(),
                         base::UTF8ToUTF16(active_user_->GetAccountName(true)));
-    known_user::SetProfileEverInitialized(
-        active_user_->GetAccountId(), active_user_->profile_ever_initialized());
   } else {
     SaveUserType(active_user_);
   }
@@ -1076,18 +1062,6 @@
     observer.ActiveUserHashChanged(hash);
 }
 
-void UserManagerBase::ResetProfileEverInitialized(const AccountId& account_id) {
-  User* user = FindUserAndModify(account_id);
-  if (!user) {
-    LOG(ERROR) << "User not found: " << account_id.GetUserEmail();
-    return;  // Ignore if there is no such user.
-  }
-
-  user->set_profile_ever_initialized(false);
-  known_user::SetProfileEverInitialized(user->GetAccountId(), false);
-  GetLocalState()->CommitPendingWrite();
-}
-
 void UserManagerBase::Initialize() {
   UserManager::Initialize();
   if (!HasBrowserRestarted())
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h
index cfa5e7f..886191c 100644
--- a/components/user_manager/user_manager_base.h
+++ b/components/user_manager/user_manager_base.h
@@ -61,7 +61,6 @@
   void SwitchActiveUser(const AccountId& account_id) override;
   void SwitchToLastActiveUser() override;
   void OnSessionStarted() override;
-  void OnProfileInitialized(User* user) override;
   void RemoveUser(const AccountId& account_id,
                   RemoveUserDelegate* delegate) override;
   void RemoveUserFromList(const AccountId& account_id) override;
@@ -115,7 +114,6 @@
       const User& user,
       const gfx::ImageSkia& profile_image) override;
   void NotifyUsersSignInConstraintsChanged() override;
-  void ResetProfileEverInitialized(const AccountId& account_id) override;
   void Initialize() override;
 
   // This method updates "User was added to the device in this session nad is
diff --git a/components/user_manager/user_unittest.cc b/components/user_manager/user_unittest.cc
index f5ff2037..96265ab 100644
--- a/components/user_manager/user_unittest.cc
+++ b/components/user_manager/user_unittest.cc
@@ -44,13 +44,4 @@
   EXPECT_TRUE(arc_kiosk_user.IsAffiliated());
 }
 
-TEST(UserTest, UserSessionInitialized) {
-  const AccountId account_id = AccountId::FromUserEmailGaiaId(kEmail, kGaiaId);
-  std::unique_ptr<User> user(
-      User::CreateRegularUser(account_id, user_manager::USER_TYPE_REGULAR));
-  EXPECT_FALSE(user->profile_ever_initialized());
-  user->set_profile_ever_initialized(true);
-  EXPECT_TRUE(user->profile_ever_initialized());
-}
-
 }  // namespace user_manager
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc
index abb030f..63d8a0d 100644
--- a/components/viz/host/host_frame_sink_manager.cc
+++ b/components/viz/host/host_frame_sink_manager.cc
@@ -223,7 +223,6 @@
                                                   child_frame_sink_id);
 
   FrameSinkData& child_data = frame_sink_data_map_[child_frame_sink_id];
-  DCHECK(child_data.IsFrameSinkRegistered());
   DCHECK(!base::ContainsValue(child_data.parents, parent_frame_sink_id));
   child_data.parents.push_back(parent_frame_sink_id);
 
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h
index 2b331a9..54e16d6a 100644
--- a/components/viz/host/host_frame_sink_manager.h
+++ b/components/viz/host/host_frame_sink_manager.h
@@ -137,10 +137,7 @@
   // the child. If |parent_frame_sink_id| is registered then it will be added as
   // a parent of |child_frame_sink_id| and the function will return true. If
   // |parent_frame_sink_id| is not registered then the function will return
-  // false.
-  //
-  // |child_frame_sink_id| must be registered before calling. A frame sink
-  // can have multiple parents.
+  // false. A frame sink can have multiple parents.
   bool RegisterFrameSinkHierarchy(const FrameSinkId& parent_frame_sink_id,
                                   const FrameSinkId& child_frame_sink_id);
 
diff --git a/components/viz/service/display_embedder/direct_context_provider.cc b/components/viz/service/display_embedder/direct_context_provider.cc
index b7517fc7..4be6dba 100644
--- a/components/viz/service/display_embedder/direct_context_provider.cc
+++ b/components/viz/service/display_embedder/direct_context_provider.cc
@@ -136,6 +136,7 @@
   gles2_implementation_->Disable(GL_SCISSOR_TEST);
   gles2_implementation_->Disable(GL_STENCIL_TEST);
   gles2_implementation_->Disable(GL_BLEND);
+  gles2_implementation_->ActiveTexture(GL_TEXTURE0);
 
   if (texture_client_id) {
     if (!framebuffer_id_)
@@ -319,4 +320,12 @@
   gles2_implementation_->DeleteTextures(1, &client_id);
 }
 
+void DirectContextProvider::MarkContextLost() {
+  if (!decoder_->WasContextLost()) {
+    decoder_->MarkContextLost(gpu::error::kUnknown);
+    command_buffer_->service()->SetParseError(gpu::error::kLostContext);
+    OnContextLost();
+  }
+}
+
 }  // namespace viz
diff --git a/components/viz/service/display_embedder/direct_context_provider.h b/components/viz/service/display_embedder/direct_context_provider.h
index 9078b87..d87c3d4 100644
--- a/components/viz/service/display_embedder/direct_context_provider.h
+++ b/components/viz/service/display_embedder/direct_context_provider.h
@@ -69,6 +69,7 @@
   gpu::gles2::TextureManager* texture_manager();
   GLuint GenClientTextureId();
   void DeleteClientTextureId(GLuint client_id);
+  void MarkContextLost();
 
   // ContextProvider implementation.
   void AddRef() const override;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
index 258f4e7..0a62fc9 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -81,6 +81,7 @@
     api->glDisableFn(GL_SCISSOR_TEST);
     api->glDisableFn(GL_STENCIL_TEST);
     api->glDisableFn(GL_BLEND);
+    api->glActiveTextureFn(GL_TEXTURE0);
     impl_on_gpu_->context_provider_->SetGLRendererCopierRequiredState(
         texture_client_id);
   }
@@ -554,9 +555,12 @@
 SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
-  // ~DirectContextProvider wants either the context to be lost or made current.
+  // |context_provider_| and clients want either the context to be lost or made
+  // current on destruction.
   MakeCurrent();
-  context_provider_.reset();
+  copier_ = nullptr;
+  texture_deleter_ = nullptr;
+  context_provider_ = nullptr;
 
   sync_point_client_state_->Destroy();
 }
@@ -1155,8 +1159,7 @@
       LOG(ERROR) << "Failed to make current.";
       context_lost_callback_.Run();
       if (context_provider_)
-        context_provider_->decoder()->MarkContextLost(
-            gpu::error::kMakeCurrentFailed);
+        context_provider_->MarkContextLost();
       return false;
     }
     context_state_->set_need_context_state_reset(true);
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index b7887520..d5278b6 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -169,8 +169,7 @@
   AXTextMarkerRef text_marker = AXTextMarkerCreate(
       kCFAllocatorDefault, reinterpret_cast<const UInt8*>(position.get()),
       sizeof(BrowserAccessibilityPosition));
-  return static_cast<id>(
-      base::mac::CFTypeRefToNSObjectAutorelease(text_marker));
+  return [static_cast<id>(text_marker) autorelease];
 }
 
 // |range| is destructed at the end of this method. |anchor| and |focus| are
@@ -184,8 +183,7 @@
       sizeof(BrowserAccessibilityPosition)));
   AXTextMarkerRangeRef marker_range =
       AXTextMarkerRangeCreate(kCFAllocatorDefault, start_marker, end_marker);
-  return static_cast<id>(
-      base::mac::CFTypeRefToNSObjectAutorelease(marker_range));
+  return [static_cast<id>(marker_range) autorelease];
 }
 
 BrowserAccessibilityPositionInstance CreatePositionFromTextMarker(
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.cc b/content/browser/browsing_data/browsing_data_remover_impl.cc
index bbbf6c6..087240e 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl.cc
+++ b/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -18,6 +18,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/stl_util.h"
 #include "base/task/post_task.h"
+#include "base/trace_event/trace_event.h"
 #include "content/browser/browsing_data/storage_partition_http_cache_data_remover.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -254,7 +255,9 @@
   //    |filter_builder.IsEmptyBlacklist()|. Add a comment explaining why this
   //    is acceptable.
   base::ScopedClosureRunner synchronous_clear_operations(
-      CreatePendingTaskCompletionClosure());
+      CreateTaskCompletionClosure(TracingDataType::kSynchronous));
+
+  TRACE_EVENT0("browsing_data", "BrowsingDataRemoverImpl::RemoveImpl");
 
   // crbug.com/140910: Many places were calling this with base::Time() as
   // delete_end, even though they should've used base::Time::Max().
@@ -318,8 +321,9 @@
 
     BrowserContext::GetDefaultStoragePartition(browser_context_)
         ->GetNetworkContext()
-        ->ClearChannelIds(delete_begin, delete_end, std::move(service_filter),
-                          CreatePendingTaskCompletionClosureForMojo());
+        ->ClearChannelIds(
+            delete_begin, delete_end, std::move(service_filter),
+            CreateTaskCompletionClosureForMojo(TracingDataType::kChannelIds));
   }
 
   //////////////////////////////////////////////////////////////////////////////
@@ -418,7 +422,8 @@
         base::BindRepeating(&DoesOriginMatchMaskAndURLs, origin_type_mask_,
                             filter, std::move(embedder_matcher)),
         std::move(deletion_filter), perform_storage_cleanup, delete_begin_,
-        delete_end_, CreatePendingTaskCompletionClosure());
+        delete_end_,
+        CreateTaskCompletionClosure(TracingDataType::kStoragePartition));
   }
 
   //////////////////////////////////////////////////////////////////////////////
@@ -438,20 +443,22 @@
       // and are now using a single cache for both purposes.
       network_context->ClearHttpCache(
           delete_begin, delete_end, filter_builder.BuildNetworkServiceFilter(),
-          CreatePendingTaskCompletionClosureForMojo());
+          CreateTaskCompletionClosureForMojo(TracingDataType::kHttpCache));
     } else {
       storage_partition->ClearHttpAndMediaCaches(
           delete_begin, delete_end, nullable_filter,
-          CreatePendingTaskCompletionClosureForMojo());
+          CreateTaskCompletionClosureForMojo(
+              TracingDataType::kHttpAndMediaCaches));
     }
     storage_partition->ClearCodeCaches(
         delete_begin, delete_end, nullable_filter,
-        CreatePendingTaskCompletionClosureForMojo());
+        CreateTaskCompletionClosureForMojo(TracingDataType::kCodeCaches));
 
     // When clearing cache, wipe accumulated network related data
     // (TransportSecurityState and HttpServerPropertiesManager data).
     network_context->ClearNetworkingHistorySince(
-        delete_begin, CreatePendingTaskCompletionClosureForMojo());
+        delete_begin,
+        CreateTaskCompletionClosureForMojo(TracingDataType::kNetworkHistory));
 
     // Tell the shader disk cache to clear.
     base::RecordAction(UserMetricsAction("ClearBrowsingData_ShaderCache"));
@@ -468,10 +475,11 @@
             ->GetNetworkContext();
     network_context->ClearReportingCacheClients(
         filter_builder.BuildNetworkServiceFilter(),
-        CreatePendingTaskCompletionClosureForMojo());
+        CreateTaskCompletionClosureForMojo(TracingDataType::kReportingCache));
     network_context->ClearNetworkErrorLogging(
         filter_builder.BuildNetworkServiceFilter(),
-        CreatePendingTaskCompletionClosureForMojo());
+        CreateTaskCompletionClosureForMojo(
+            TracingDataType::kNetworkErrorLogging));
   }
 #endif  // BUILDFLAG(ENABLE_REPORTING)
 
@@ -481,8 +489,8 @@
       !(remove_mask & DATA_TYPE_AVOID_CLOSING_CONNECTIONS)) {
     BrowserContext::GetDefaultStoragePartition(browser_context_)
         ->GetNetworkContext()
-        ->ClearHttpAuthCache(delete_begin,
-                             CreatePendingTaskCompletionClosureForMojo());
+        ->ClearHttpAuthCache(delete_begin, CreateTaskCompletionClosureForMojo(
+                                               TracingDataType::kAuthCache));
   }
 
   //////////////////////////////////////////////////////////////////////////////
@@ -490,7 +498,8 @@
   if (embedder_delegate_) {
     embedder_delegate_->RemoveEmbedderData(
         delete_begin_, delete_end_, remove_mask, filter_builder,
-        origin_type_mask, CreatePendingTaskCompletionClosure());
+        origin_type_mask,
+        CreateTaskCompletionClosure(TracingDataType::kEmbedderData));
   }
 }
 
@@ -597,14 +606,16 @@
       base::BindOnce(&BrowsingDataRemoverImpl::RunNextTask, GetWeakPtr()));
 }
 
-void BrowsingDataRemoverImpl::OnTaskComplete() {
+void BrowsingDataRemoverImpl::OnTaskComplete(TracingDataType data_type) {
   // TODO(brettw) http://crbug.com/305259: This should also observe session
   // clearing (what about other things such as passwords, etc.?) and wait for
   // them to complete before continuing.
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK_GT(num_pending_tasks_, 0);
   num_pending_tasks_--;
-
+  TRACE_EVENT_ASYNC_END1("browsing_data", "BrowsingDataRemoverImpl",
+                         static_cast<int>(data_type), "data_type",
+                         static_cast<int>(data_type));
   if (num_pending_tasks_ > 0)
     return;
 
@@ -617,19 +628,24 @@
   Notify();
 }
 
-base::OnceClosure
-BrowsingDataRemoverImpl::CreatePendingTaskCompletionClosure() {
+base::OnceClosure BrowsingDataRemoverImpl::CreateTaskCompletionClosure(
+    TracingDataType data_type) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   num_pending_tasks_++;
-  return base::BindOnce(&BrowsingDataRemoverImpl::OnTaskComplete, GetWeakPtr());
+  TRACE_EVENT_ASYNC_BEGIN1("browsing_data", "BrowsingDataRemoverImpl",
+                           static_cast<int>(data_type), "data_type",
+                           static_cast<int>(data_type));
+  return base::BindOnce(&BrowsingDataRemoverImpl::OnTaskComplete, GetWeakPtr(),
+                        data_type);
 }
 
-base::OnceClosure
-BrowsingDataRemoverImpl::CreatePendingTaskCompletionClosureForMojo() {
+base::OnceClosure BrowsingDataRemoverImpl::CreateTaskCompletionClosureForMojo(
+    TracingDataType data_type) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return RunsOrPostOnCurrentTaskRunner(mojo::WrapCallbackWithDropHandler(
-      CreatePendingTaskCompletionClosure(),
-      base::BindOnce(&BrowsingDataRemoverImpl::OnTaskComplete, GetWeakPtr())));
+      CreateTaskCompletionClosure(data_type),
+      base::BindOnce(&BrowsingDataRemoverImpl::OnTaskComplete, GetWeakPtr(),
+                     data_type)));
 }
 
 base::WeakPtr<BrowsingDataRemoverImpl> BrowsingDataRemoverImpl::GetWeakPtr() {
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.h b/content/browser/browsing_data/browsing_data_remover_impl.h
index 4d4f3c9..ef4ffdf 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl.h
+++ b/content/browser/browsing_data/browsing_data_remover_impl.h
@@ -97,6 +97,21 @@
   // Testing the private RemovalTask.
   FRIEND_TEST_ALL_PREFIXES(BrowsingDataRemoverImplTest, MultipleTasks);
 
+  // For debugging purposes. Please add new deletion tasks at the end.
+  enum class TracingDataType {
+    kSynchronous = 1,
+    kEmbedderData = 2,
+    kStoragePartition = 3,
+    kHttpCache = 4,
+    kHttpAndMediaCaches = 5,
+    kReportingCache = 6,
+    kChannelIds = 7,
+    kNetworkHistory = 8,
+    kAuthCache = 9,
+    kCodeCaches = 10,
+    kNetworkErrorLogging = 11,
+  };
+
   // Represents a single removal task. Contains all parameters needed to execute
   // it and a pointer to the observer that added it. CONTENT_EXPORTed to be
   // visible in tests.
@@ -144,19 +159,20 @@
   // Notifies observers and transitions to the idle state.
   void Notify();
 
-  // Called by the closures returned by CreatePendingTaskCompletionClosure().
+  // Called by the closures returned by CreateTaskCompletionClosure().
   // Checks if all tasks have completed, and if so, calls Notify().
-  void OnTaskComplete();
+  void OnTaskComplete(TracingDataType data_type);
 
   // Increments the number of pending tasks by one, and returns a OnceClosure
   // that calls OnTaskComplete(). The Remover is complete once all the closures
   // created by this method have been invoked.
-  base::OnceClosure CreatePendingTaskCompletionClosure();
+  base::OnceClosure CreateTaskCompletionClosure(TracingDataType data_type);
 
-  // Same as CreatePendingTaskCompletionClosure() but guarantees that
+  // Same as CreateTaskCompletionClosure() but guarantees that
   // OnTaskComplete() is called if the task is dropped. That can typically
   // happen when the connection is closed while an interface call is made.
-  base::OnceClosure CreatePendingTaskCompletionClosureForMojo();
+  base::OnceClosure CreateTaskCompletionClosureForMojo(
+      TracingDataType data_type);
 
   // Like GetWeakPtr(), but returns a weak pointer to BrowsingDataRemoverImpl
   // for internal purposes.
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 97e526d..5da8761 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -514,9 +514,19 @@
       info.request_handle->CancelRequest(false);
     return true;
   }
+
+  std::string user_agent = "";
+  for (const auto& header : info.request_headers) {
+    if (header.first == net::HttpRequestHeaders::kUserAgent) {
+      user_agent = header.second;
+      break;
+    }
+  }
+
   if (!delegate_ ||
       !delegate_->InterceptDownloadIfApplicable(
-          info.url(), info.mime_type, info.request_origin, web_contents)) {
+          info.url(), user_agent, info.content_disposition, info.mime_type,
+          info.request_origin, info.total_bytes, web_contents)) {
     return false;
   }
   if (info.request_handle)
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc
index 4371c70a..18270d21 100644
--- a/content/browser/media/session/media_session_impl.cc
+++ b/content/browser/media/session/media_session_impl.cc
@@ -185,6 +185,14 @@
   RebuildAndNotifyMetadataChanged();
 }
 
+void MediaSessionImpl::OnWebContentsFocused(RenderWidgetHost*) {
+  focused_ = true;
+}
+
+void MediaSessionImpl::OnWebContentsLostFocus(RenderWidgetHost*) {
+  focused_ = false;
+}
+
 bool MediaSessionImpl::AddPlayer(MediaSessionPlayerObserver* observer,
                                  int player_id,
                                  media::MediaContentType media_content_type) {
@@ -350,7 +358,7 @@
     }
 
     MediaSessionUmaHelper::RecordMediaSessionUserAction(
-        MediaSessionUmaHelper::MediaSessionUserAction::PlayDefault);
+        MediaSessionUmaHelper::MediaSessionUserAction::PlayDefault, focused_);
   }
 
   // When the resume requests comes from another source than system, audio focus
@@ -386,7 +394,7 @@
     }
 
     MediaSessionUmaHelper::RecordMediaSessionUserAction(
-        MediaSessionUserAction::PauseDefault);
+        MediaSessionUserAction::PauseDefault, focused_);
   }
 
   OnSuspendInternal(suspend_type, State::SUSPENDED);
@@ -399,7 +407,7 @@
 
   if (suspend_type == SuspendType::kUI) {
     MediaSessionUmaHelper::RecordMediaSessionUserAction(
-        MediaSessionUmaHelper::MediaSessionUserAction::StopDefault);
+        MediaSessionUmaHelper::MediaSessionUserAction::StopDefault, focused_);
   }
 
   // TODO(mlamouri): merge the logic between UI and SYSTEM.
@@ -616,6 +624,9 @@
   session_android_.reset(new MediaSessionAndroid(this));
 #endif  // defined(OS_ANDROID)
 
+  if (web_contents->GetMainFrame() && web_contents->GetMainFrame()->GetView())
+    focused_ = web_contents->GetMainFrame()->GetView()->HasFocus();
+
   RebuildAndNotifyMetadataChanged();
 }
 
@@ -902,7 +913,7 @@
 void MediaSessionImpl::DidReceiveAction(
     media_session::mojom::MediaSessionAction action) {
   MediaSessionUmaHelper::RecordMediaSessionUserAction(
-      MediaSessionActionToUserAction(action));
+      MediaSessionActionToUserAction(action), focused_);
 
   // Pause all players in non-routed frames if the action is PAUSE.
   //
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h
index 7e6921a..66686b6 100644
--- a/content/browser/media/session/media_session_impl.h
+++ b/content/browser/media/session/media_session_impl.h
@@ -132,6 +132,8 @@
   void WebContentsDestroyed() override;
   void RenderFrameDeleted(RenderFrameHost* rfh) override;
   void DidFinishNavigation(NavigationHandle* navigation_handle) override;
+  void OnWebContentsFocused(RenderWidgetHost*) override;
+  void OnWebContentsLostFocus(RenderWidgetHost*) override;
 
   // MediaSessionService-related methods
 
@@ -370,6 +372,9 @@
 
   double ducking_volume_multiplier_;
 
+  // True if the WebContents associated with this MediaSessionImpl is focused.
+  bool focused_ = false;
+
 #if defined(OS_ANDROID)
   std::unique_ptr<MediaSessionAndroid> session_android_;
 #endif  // defined(OS_ANDROID)
diff --git a/content/browser/media/session/media_session_uma_helper.cc b/content/browser/media/session/media_session_uma_helper.cc
index d961917..2b53595 100644
--- a/content/browser/media/session/media_session_uma_helper.cc
+++ b/content/browser/media/session/media_session_uma_helper.cc
@@ -22,8 +22,10 @@
 
 // static
 void MediaSessionUmaHelper::RecordMediaSessionUserAction(
-    MediaSessionUserAction action) {
+    MediaSessionUserAction action,
+    bool focused) {
   UMA_HISTOGRAM_ENUMERATION("Media.Session.UserAction", action);
+  UMA_HISTOGRAM_BOOLEAN("Media.Session.UserAction.Focus", focused);
 }
 
 void MediaSessionUmaHelper::RecordSessionSuspended(
diff --git a/content/browser/media/session/media_session_uma_helper.h b/content/browser/media/session/media_session_uma_helper.h
index 4745e78..1b8511e 100644
--- a/content/browser/media/session/media_session_uma_helper.h
+++ b/content/browser/media/session/media_session_uma_helper.h
@@ -48,7 +48,8 @@
   MediaSessionUmaHelper();
   ~MediaSessionUmaHelper();
 
-  static void RecordMediaSessionUserAction(MediaSessionUserAction action);
+  static void RecordMediaSessionUserAction(MediaSessionUserAction action,
+                                           bool focused);
 
   void RecordSessionSuspended(MediaSessionSuspendedSource source) const;
 
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
index 17ec939..ae11346a 100644
--- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
+++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -19,6 +19,7 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/content_client.h"
 #include "media/base/media_switches.h"
+#include "ui/compositor/layer.h"
 
 namespace content {
 
@@ -126,6 +127,17 @@
   DCHECK(window_);
 
   DCHECK(surface_id.is_valid());
+
+  // TODO(https://crbug.com/925346): We also want to unregister the page that
+  // used to embed the video as its parent.
+  ui::Compositor* compositor = window_->GetLayer()->GetCompositor();
+  if (!surface_id_.is_valid()) {
+    compositor->AddChildFrameSink(surface_id.frame_sink_id());
+  } else if (surface_id_.frame_sink_id() != surface_id.frame_sink_id()) {
+    compositor->RemoveChildFrameSink(surface_id_.frame_sink_id());
+    compositor->AddChildFrameSink(surface_id.frame_sink_id());
+  }
+
   surface_id_ = surface_id;
 
   // Update the media player id in step with the video surface id. If the
@@ -305,6 +317,11 @@
 void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture(
     bool should_pause_video,
     bool should_reset_pip_player) {
+  if (window_ && surface_id_.is_valid()) {
+    window_->GetLayer()->GetCompositor()->RemoveChildFrameSink(
+        surface_id_.frame_sink_id());
+  }
+
   if (IsPlayerActive() && should_pause_video) {
     // Pause the current video so there is only one video playing at a time.
     media_player_id_->render_frame_host->Send(new MediaPlayerDelegateMsg_Pause(
@@ -332,10 +349,9 @@
   if (initiator_->IsBeingDestroyed())
     return;
 
-  surface_id_ = viz::SurfaceId();
-
   initiator_->SetHasPictureInPictureVideo(false);
   OnLeavingPictureInPicture(should_pause_video, should_reset_pip_player);
+  surface_id_ = viz::SurfaceId();
 }
 
 void PictureInPictureWindowControllerImpl::EnsureWindow() {
diff --git a/content/browser/renderer_host/input/mouse_latency_browsertest.cc b/content/browser/renderer_host/input/mouse_latency_browsertest.cc
index 33af683..a7fef82a 100644
--- a/content/browser/renderer_host/input/mouse_latency_browsertest.cc
+++ b/content/browser/renderer_host/input/mouse_latency_browsertest.cc
@@ -274,6 +274,24 @@
     return trace_data_;
   }
 
+  std::string ShowTraceEventsWithId(const std::string& id_to_show,
+                                    const base::ListValue* traceEvents) {
+    std::stringstream stream;
+    for (size_t i = 0; i < traceEvents->GetSize(); ++i) {
+      const base::DictionaryValue* traceEvent;
+      if (!traceEvents->GetDictionary(i, &traceEvent))
+        continue;
+
+      std::string id;
+      if (!traceEvent->GetString("id", &id))
+        continue;
+
+      if (id == id_to_show)
+        stream << *traceEvent;
+    }
+    return stream.str();
+  }
+
   void AssertTraceIdsBeginAndEnd(const base::Value& trace_data,
                                  const std::string& trace_event_name) {
     const base::DictionaryValue* trace_data_dict;
@@ -301,7 +319,7 @@
 
     for (auto i : trace_ids) {
       // Each trace id should show up once for the begin, and once for the end.
-      EXPECT_EQ(2, i.second);
+      EXPECT_EQ(2, i.second) << ShowTraceEventsWithId(i.first, traceEvents);
     }
   }
 
@@ -387,16 +405,8 @@
   AssertTraceIdsBeginAndEnd(trace_data, "InputLatency::MouseMove");
 }
 
-// TODO(crbug.com/923627): This test is flaky on Windows and Android.
-#if defined(OS_WIN) || defined(OS_ANDROID)
-#define MAYBE_CoalescedMouseWheelsCorrectlyTerminated \
-  DISABLED_CoalescedMouseWheelsCorrectlyTerminated
-#else
-#define MAYBE_CoalescedMouseWheelsCorrectlyTerminated \
-  CoalescedMouseWheelsCorrectlyTerminated
-#endif
 IN_PROC_BROWSER_TEST_F(MouseLatencyBrowserTest,
-                       MAYBE_CoalescedMouseWheelsCorrectlyTerminated) {
+                       CoalescedMouseWheelsCorrectlyTerminated) {
   LoadURL();
 
   StartTracing();
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 7a90824..e2c5dc9 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -928,6 +928,20 @@
       key_prefix, std::move(callback));
 }
 
+void ServiceWorkerContextWrapper::ClearUserDataForAllRegistrationsByKeyPrefix(
+    const std::string& key_prefix,
+    StatusCallback callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!context_core_) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(std::move(callback),
+                                  blink::ServiceWorkerStatusCode::kErrorAbort));
+    return;
+  }
+  context_core_->storage()->ClearUserDataForAllRegistrationsByKeyPrefix(
+      key_prefix, std::move(callback));
+}
+
 void ServiceWorkerContextWrapper::StartServiceWorker(const GURL& scope,
                                                      StatusCallback callback) {
   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h
index d2b8ad8c..ef08660 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -265,6 +265,9 @@
   void GetUserDataForAllRegistrationsByKeyPrefix(
       const std::string& key_prefix,
       GetUserDataForAllRegistrationsCallback callback);
+  void ClearUserDataForAllRegistrationsByKeyPrefix(
+      const std::string& key_prefix,
+      StatusCallback callback);
 
   // This function can be called from any thread, but the callback will always
   // be called on the UI thread.
diff --git a/content/browser/service_worker/service_worker_database.cc b/content/browser/service_worker/service_worker_database.cc
index 0137f9a8..c4a75cf5 100644
--- a/content/browser/service_worker/service_worker_database.cc
+++ b/content/browser/service_worker/service_worker_database.cc
@@ -1136,7 +1136,7 @@
 
       std::vector<std::string> parts = base::SplitString(
           user_data_name_with_id,
-          base::StringPrintf("%c", service_worker_internals::kKeySeparator),
+          std::string(1, service_worker_internals::kKeySeparator),
           base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
       if (parts.size() != 2) {
         status = STATUS_ERROR_CORRUPTED;
@@ -1167,6 +1167,59 @@
   return status;
 }
 
+ServiceWorkerDatabase::Status
+ServiceWorkerDatabase::DeleteUserDataForAllRegistrationsByKeyPrefix(
+    const std::string& user_data_name_prefix) {
+  DCHECK(sequence_checker_.CalledOnValidSequence());
+
+  Status status = LazyOpen(false);
+  if (IsNewOrNonexistentDatabase(status))
+    return STATUS_OK;
+  if (status != STATUS_OK)
+    return status;
+
+  leveldb::WriteBatch batch;
+  std::string key_prefix = service_worker_internals::kRegHasUserDataKeyPrefix +
+                           user_data_name_prefix;
+
+  std::unique_ptr<leveldb::Iterator> itr(
+      db_->NewIterator(leveldb::ReadOptions()));
+  for (itr->Seek(key_prefix); itr->Valid(); itr->Next()) {
+    status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
+    if (status != STATUS_OK)
+      return status;
+
+    if (!itr->key().starts_with(key_prefix)) {
+      // |itr| reached the end of the range of keys prefixed by |key_prefix|.
+      break;
+    }
+
+    std::string user_data_name_with_id;
+    bool did_remove_prefix =
+        RemovePrefix(itr->key().ToString(),
+                     service_worker_internals::kRegHasUserDataKeyPrefix,
+                     &user_data_name_with_id);
+    DCHECK(did_remove_prefix);
+
+    std::vector<std::string> parts = base::SplitString(
+        user_data_name_with_id,
+        std::string(1, service_worker_internals::kKeySeparator),
+        base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+    if (parts.size() != 2)
+      return STATUS_ERROR_CORRUPTED;
+
+    int64_t registration_id;
+    status = ParseId(parts[1], &registration_id);
+    if (status != STATUS_OK)
+      return status;
+
+    batch.Delete(itr->key());
+    batch.Delete(CreateUserDataKey(registration_id, parts[0]));
+  }
+
+  return WriteBatch(&batch);
+}
+
 ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetUncommittedResourceIds(
     std::set<int64_t>* ids) {
   return ReadResourceIds(service_worker_internals::kUncommittedResIdKeyPrefix,
diff --git a/content/browser/service_worker/service_worker_database.h b/content/browser/service_worker/service_worker_database.h
index 99cbb01..d2a5ae0 100644
--- a/content/browser/service_worker/service_worker_database.h
+++ b/content/browser/service_worker/service_worker_database.h
@@ -240,12 +240,19 @@
       const std::string& user_data_name,
       std::vector<std::pair<int64_t, std::string>>* user_data);
 
-  // Reads user data for all registrations that have data with |user_data_name|
-  // from the database. Returns OK if they are successfully read or not found.
+  // Reads user data for all registrations that have data with
+  // |user_data_name_prefix| from the database. Returns OK if they are
+  // successfully read or not found.
   Status ReadUserDataForAllRegistrationsByKeyPrefix(
       const std::string& user_data_name_prefix,
       std::vector<std::pair<int64_t, std::string>>* user_data);
 
+  // Deletes user data for all registrations that have data with
+  // |user_data_name_prefix| from the database. Returns OK if all are
+  // successfully deleted or not found in the database.
+  Status DeleteUserDataForAllRegistrationsByKeyPrefix(
+      const std::string& user_data_name_prefix);
+
   // Resources should belong to one of following resource lists: uncommitted,
   // committed and purgeable.
   // As new resources are put into the diskcache, they go into the uncommitted
diff --git a/content/browser/service_worker/service_worker_database_unittest.cc b/content/browser/service_worker/service_worker_database_unittest.cc
index 2ba6e26..5a6044d5 100644
--- a/content/browser/service_worker/service_worker_database_unittest.cc
+++ b/content/browser/service_worker/service_worker_database_unittest.cc
@@ -1462,6 +1462,90 @@
   EXPECT_EQ("value_e2", user_data_list[2].second);
 }
 
+TEST(ServiceWorkerDatabaseTest,
+     UserData_DeleteUserDataForAllRegistrationsByKeyPrefix) {
+  std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+  const GURL kOrigin("https://example.com");
+
+  // Add registration 1.
+  RegistrationData data1;
+  data1.registration_id = 100;
+  data1.scope = URL(kOrigin, "/foo");
+  data1.script = URL(kOrigin, "/script1.js");
+  data1.version_id = 200;
+  data1.resources_total_size_bytes = 100;
+  std::vector<Resource> resources1;
+  resources1.push_back(CreateResource(1, data1.script, 100));
+
+  // Add registration 2.
+  RegistrationData data2;
+  data2.registration_id = 101;
+  data2.scope = URL(kOrigin, "/bar");
+  data2.script = URL(kOrigin, "/script2.js");
+  data2.version_id = 201;
+  data2.resources_total_size_bytes = 200;
+  std::vector<Resource> resources2;
+  resources2.push_back(CreateResource(2, data2.script, 200));
+
+  ServiceWorkerDatabase::RegistrationData deleted_version;
+  std::vector<int64_t> newly_purgeable_resources;
+  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+            database->WriteRegistration(data1, resources1, &deleted_version,
+                                        &newly_purgeable_resources));
+  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+            database->WriteRegistration(data2, resources2, &deleted_version,
+                                        &newly_purgeable_resources));
+
+  // Write user data associated with registration 1.
+  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+            database->WriteUserData(data1.registration_id, kOrigin,
+                                    {{"key_prefix:key1", "value_a1"},
+                                     {"key_prefix:key2", "value_a2"},
+                                     {"key_prefix:key3", "value_a3"},
+                                     {"kept_key_prefix:key1", "value_b1"}}));
+
+  // Write user data associated with registration 2.
+  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+            database->WriteUserData(data2.registration_id, kOrigin,
+                                    {{"key_prefix:key1", "value_c1"},
+                                     {"key_prefix:key2", "value_c2"},
+                                     {"kept_key_prefix:key1", "value_d1"},
+                                     {"kept_key_prefix:key2", "value_d2"}}));
+
+  // Deleting user data by key prefixes should return STATUS_OK (rather than
+  // STATUS_ERROR_NOT_FOUND) even if no keys match the prefixes and so nothing
+  // is deleted.
+  EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+            database->DeleteUserDataForAllRegistrationsByKeyPrefix(
+                "not_found_key_prefix:"));
+
+  // Actually delete user data by key prefixes.
+  ASSERT_EQ(
+      ServiceWorkerDatabase::STATUS_OK,
+      database->DeleteUserDataForAllRegistrationsByKeyPrefix("key_prefix:"));
+
+  // User data with deleted "key_prefix:" should be deleted.
+  std::vector<std::pair<int64_t, std::string>> user_data_list;
+  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+            database->ReadUserDataForAllRegistrationsByKeyPrefix(
+                "key_prefix:", &user_data_list));
+  EXPECT_TRUE(user_data_list.empty());
+
+  // User data with "kept_key_prefix:" should remain on both registrations.
+  user_data_list.clear();
+  ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
+            database->ReadUserDataForAllRegistrationsByKeyPrefix(
+                "kept_key_prefix:", &user_data_list));
+  ASSERT_EQ(3u, user_data_list.size());
+
+  EXPECT_EQ(data1.registration_id, user_data_list[0].first);
+  EXPECT_EQ("value_b1", user_data_list[0].second);
+  EXPECT_EQ(data2.registration_id, user_data_list[1].first);
+  EXPECT_EQ("value_d1", user_data_list[1].second);
+  EXPECT_EQ(data2.registration_id, user_data_list[2].first);
+  EXPECT_EQ("value_d2", user_data_list[2].second);
+}
+
 TEST(ServiceWorkerDatabaseTest, UserData_DataIsolation) {
   std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
   const GURL kOrigin("https://example.com");
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc
index 69de20e..db7587f 100644
--- a/content/browser/service_worker/service_worker_storage.cc
+++ b/content/browser/service_worker/service_worker_storage.cc
@@ -1016,6 +1016,41 @@
               weak_factory_.GetWeakPtr(), std::move(callback))));
 }
 
+void ServiceWorkerStorage::ClearUserDataForAllRegistrationsByKeyPrefix(
+    const std::string& key_prefix,
+    StatusCallback callback) {
+  switch (state_) {
+    case STORAGE_STATE_DISABLED:
+      RunSoon(FROM_HERE,
+              base::BindOnce(std::move(callback),
+                             blink::ServiceWorkerStatusCode::kErrorAbort));
+      return;
+    case STORAGE_STATE_INITIALIZING:  // Fall-through.
+    case STORAGE_STATE_UNINITIALIZED:
+      LazyInitialize(base::BindOnce(
+          &ServiceWorkerStorage::ClearUserDataForAllRegistrationsByKeyPrefix,
+          weak_factory_.GetWeakPtr(), key_prefix, std::move(callback)));
+      return;
+    case STORAGE_STATE_INITIALIZED:
+      break;
+  }
+
+  if (key_prefix.empty()) {
+    RunSoon(FROM_HERE,
+            base::BindOnce(std::move(callback),
+                           blink::ServiceWorkerStatusCode::kErrorFailed));
+    return;
+  }
+
+  base::PostTaskAndReplyWithResult(
+      database_task_runner_.get(), FROM_HERE,
+      base::BindOnce(
+          &ServiceWorkerDatabase::DeleteUserDataForAllRegistrationsByKeyPrefix,
+          base::Unretained(database_.get()), key_prefix),
+      base::BindOnce(&ServiceWorkerStorage::DidDeleteUserData,
+                     weak_factory_.GetWeakPtr(), std::move(callback)));
+}
+
 void ServiceWorkerStorage::DeleteAndStartOver(StatusCallback callback) {
   Disable();
 
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h
index cb05e33c..72abeea 100644
--- a/content/browser/service_worker/service_worker_storage.h
+++ b/content/browser/service_worker/service_worker_storage.h
@@ -242,6 +242,11 @@
   void GetUserDataForAllRegistrationsByKeyPrefix(
       const std::string& key_prefix,
       GetUserDataForAllRegistrationsCallback callback);
+  // Responds OK if all are successfully deleted or not found in the database.
+  // |key_prefix| cannot be empty.
+  void ClearUserDataForAllRegistrationsByKeyPrefix(
+      const std::string& key_prefix,
+      StatusCallback callback);
 
   // Deletes the storage and starts over.
   void DeleteAndStartOver(StatusCallback callback);
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc
index a0dc1b7f..e5624a51 100644
--- a/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -522,6 +522,18 @@
     return result.value();
   }
 
+  blink::ServiceWorkerStatusCode ClearUserDataForAllRegistrationsByKeyPrefix(
+      const std::string& key_prefix) {
+    bool was_called = false;
+    base::Optional<blink::ServiceWorkerStatusCode> result;
+    storage()->ClearUserDataForAllRegistrationsByKeyPrefix(
+        key_prefix, MakeStatusCallback(&was_called, &result));
+    EXPECT_FALSE(was_called);  // always async
+    base::RunLoop().RunUntilIdle();
+    EXPECT_TRUE(was_called);
+    return result.value();
+  }
+
   blink::ServiceWorkerStatusCode UpdateToActiveState(
       scoped_refptr<ServiceWorkerRegistration> registration) {
     bool was_called = false;
@@ -688,6 +700,8 @@
   std::vector<std::pair<int64_t, std::string>> data_list_out;
   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
             GetUserDataForAllRegistrations(kUserDataKey, &data_list_out));
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
+            ClearUserDataForAllRegistrationsByKeyPrefix("prefix"));
 
   // Next available ids should be invalid.
   EXPECT_EQ(blink::mojom::kInvalidServiceWorkerRegistrationId,
@@ -1124,6 +1138,12 @@
   ASSERT_EQ(1u, data_out.size());
   EXPECT_EQ("data3", data_out[0]);
 
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            ClearUserDataForAllRegistrationsByKeyPrefix("prefixB"));
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            GetUserDataByKeyPrefix(kRegistrationId, "prefix", &data_out));
+  EXPECT_TRUE(data_out.empty());
+
   // User data should be deleted when the associated registration is deleted.
   ASSERT_EQ(
       blink::ServiceWorkerStatusCode::kOk,
@@ -1189,6 +1209,8 @@
             ClearUserDataByKeyPrefixes(kRegistrationId, {}));
   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
             ClearUserDataByKeyPrefixes(kRegistrationId, {std::string()}));
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
+            ClearUserDataForAllRegistrationsByKeyPrefix(std::string()));
   data_list_out.clear();
   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
             GetUserDataForAllRegistrations(std::string(), &data_list_out));
@@ -1218,6 +1240,8 @@
             ClearUserData(kRegistrationId, {"key"}));
   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
             ClearUserDataByKeyPrefixes(kRegistrationId, {"prefix"}));
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            ClearUserDataForAllRegistrationsByKeyPrefix("key"));
 }
 
 TEST_F(ServiceWorkerStorageTest,
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index faeef74..8b61441 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -454,6 +454,9 @@
   WebRuntimeFeatures::EnableImplicitRootScroller(
       base::FeatureList::IsEnabled(blink::features::kImplicitRootScroller));
 
+  WebRuntimeFeatures::EnableTextFragmentAnchor(
+      base::FeatureList::IsEnabled(blink::features::kTextFragmentAnchor));
+
   if (!base::FeatureList::IsEnabled(features::kBackgroundFetch))
     WebRuntimeFeatures::EnableBackgroundFetch(false);
 
@@ -477,6 +480,10 @@
 
   WebRuntimeFeatures::EnableGetDisplayMedia(
       base::FeatureList::IsEnabled(blink::features::kRTCGetDisplayMedia));
+
+  WebRuntimeFeatures::EnableMimeHandlerViewInCrossProcessFrame(
+      base::FeatureList::IsEnabled(
+          features::kMimeHandlerViewInCrossProcessFrame));
 }
 
 }  // namespace
diff --git a/content/public/browser/download_manager_delegate.cc b/content/public/browser/download_manager_delegate.cc
index 1bc1b25..6aca5afa 100644
--- a/content/public/browser/download_manager_delegate.cc
+++ b/content/public/browser/download_manager_delegate.cc
@@ -39,8 +39,11 @@
 
 bool DownloadManagerDelegate::InterceptDownloadIfApplicable(
     const GURL& url,
+    const std::string& user_agent,
+    const std::string& content_disposition,
     const std::string& mime_type,
     const std::string& request_origin,
+    int64_t content_length,
     WebContents* web_contents) {
   return false;
 }
diff --git a/content/public/browser/download_manager_delegate.h b/content/public/browser/download_manager_delegate.h
index a413d86..faeeb685 100644
--- a/content/public/browser/download_manager_delegate.h
+++ b/content/public/browser/download_manager_delegate.h
@@ -123,10 +123,14 @@
 
   // Checks and hands off the downloading to be handled by another system based
   // on mime type. Returns true if the download was intercepted.
-  virtual bool InterceptDownloadIfApplicable(const GURL& url,
-                                             const std::string& mime_type,
-                                             const std::string& request_origin,
-                                             WebContents* web_contents);
+  virtual bool InterceptDownloadIfApplicable(
+      const GURL& url,
+      const std::string& user_agent,
+      const std::string& content_disposition,
+      const std::string& mime_type,
+      const std::string& request_origin,
+      int64_t content_length,
+      WebContents* web_contents);
 
   // Returns true if we need to generate a binary hash for downloads.
   virtual bool GenerateFileHash();
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 5207742..4f716c1 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -718,8 +718,12 @@
     "//third_party/webrtc/pc:peerconnection",
     "//third_party/webrtc/pc:rtc_pc",
     "//third_party/webrtc/pc:rtc_pc_base",
+    "//third_party/webrtc/rtc_base:async_resolver_interface",
+    "//third_party/webrtc/rtc_base:ip_address",
     "//third_party/webrtc/rtc_base:rtc_base",
     "//third_party/webrtc/rtc_base:rtc_task_queue",
+    "//third_party/webrtc/rtc_base:socket_address",
+    "//third_party/webrtc/rtc_base:threading",
     "//third_party/webrtc/rtc_base:timeutils",
 
     # TODO(titovartem) remove dependency on WebRTC internals.
diff --git a/content/renderer/compositor/layer_tree_view.cc b/content/renderer/compositor/layer_tree_view.cc
index 3a4da40b..947c4174a 100644
--- a/content/renderer/compositor/layer_tree_view.cc
+++ b/content/renderer/compositor/layer_tree_view.cc
@@ -502,6 +502,14 @@
   return layer_tree_host_->DeferMainFrameUpdate();
 }
 
+void LayerTreeView::StartDeferringCommits() {
+  layer_tree_host_->StartDeferringCommits();
+}
+
+void LayerTreeView::StopDeferringCommits() {
+  layer_tree_host_->StopDeferringCommits();
+}
+
 int LayerTreeView::LayerTreeId() const {
   return layer_tree_host_->GetId();
 }
diff --git a/content/renderer/compositor/layer_tree_view.h b/content/renderer/compositor/layer_tree_view.h
index 095e35a..2d7cfe39 100644
--- a/content/renderer/compositor/layer_tree_view.h
+++ b/content/renderer/compositor/layer_tree_view.h
@@ -152,6 +152,8 @@
   void UpdateAllLifecyclePhasesAndCompositeForTesting(bool do_raster) override;
   std::unique_ptr<cc::ScopedDeferMainFrameUpdate> DeferMainFrameUpdate()
       override;
+  void StartDeferringCommits() override;
+  void StopDeferringCommits() override;
   void RegisterViewportLayers(const ViewportLayers& viewport_layers) override;
   void ClearViewportLayers() override;
   void RegisterSelection(const cc::LayerSelection& selection) override;
diff --git a/content/renderer/media/stream/mock_media_stream_video_sink.h b/content/renderer/media/stream/mock_media_stream_video_sink.h
index 8d9c585..a4c398a 100644
--- a/content/renderer/media/stream/mock_media_stream_video_sink.h
+++ b/content/renderer/media/stream/mock_media_stream_video_sink.h
@@ -46,7 +46,7 @@
   int number_of_frames() const { return number_of_frames_; }
   media::VideoPixelFormat format() const { return format_; }
   gfx::Size frame_size() const { return frame_size_; }
-  scoped_refptr<media::VideoFrame> last_frame() const { return last_frame_; };
+  scoped_refptr<media::VideoFrame> last_frame() const { return last_frame_; }
 
   bool enabled() const { return enabled_; }
   blink::WebMediaStreamSource::ReadyState state() const { return state_; }
diff --git a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
index c649211..534b792 100644
--- a/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
+++ b/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
@@ -1396,9 +1396,9 @@
 }
 #endif
 
-INSTANTIATE_TEST_CASE_P(,
-                        WebMediaPlayerMSTest,
-                        ::testing::Combine(::testing::Bool(),
-                                           ::testing::Bool(),
-                                           ::testing::Bool()));
+INSTANTIATE_TEST_SUITE_P(,
+                         WebMediaPlayerMSTest,
+                         ::testing::Combine(::testing::Bool(),
+                                            ::testing::Bool(),
+                                            ::testing::Bool()));
 }  // namespace content
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 4cf6abb..104e48a 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -75,6 +75,7 @@
 #include "content/public/common/context_menu_params.h"
 #include "content/public/common/favicon_url.h"
 #include "content/public/common/isolated_world_ids.h"
+#include "content/public/common/mime_handler_view_mode.h"
 #include "content/public/common/navigation_policy.h"
 #include "content/public/common/page_state.h"
 #include "content/public/common/service_manager_connection.h"
@@ -3848,6 +3849,7 @@
     const blink::WebElement& plugin_element,
     const blink::WebURL& url,
     const blink::WebString& suggested_mime_type) {
+  DCHECK(content::MimeHandlerViewMode::UsesCrossProcessFrame());
 #if BUILDFLAG(ENABLE_PLUGINS)
   if (!BrowserPluginManager::Get()) {
     // BrowserPluginManager needs a RenderThreadImpl, but some renderer tests
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 1c6d2aad..da73415 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1991,7 +1991,9 @@
     "//third_party/webrtc/modules/video_capture",
     "//third_party/webrtc/modules/video_coding:video_codec_interface",
     "//third_party/webrtc/pc:libjingle_peerconnection",
+    "//third_party/webrtc/rtc_base:ip_address",
     "//third_party/webrtc/rtc_base:rtc_base",
+    "//third_party/webrtc/rtc_base:socket_address",
     "//third_party/webrtc/rtc_base:timeutils",
     "//third_party/webrtc/stats:rtc_stats_test_utils",
     "//third_party/webrtc_overrides",
diff --git a/content/test/OWNERS b/content/test/OWNERS
index ae6c523b..96e95d7 100644
--- a/content/test/OWNERS
+++ b/content/test/OWNERS
@@ -3,6 +3,9 @@
 # For WebRTC files.
 tommi@chromium.org
 
+# For Background Sync related files.
+per-file *background_sync*=file://content/browser/background_sync/OWNERS
+
 # This integration test uses both renderer and renderer_host code.
 per-file renderer_audio_output_stream_factory_context_impl_unittest.cc=file://content/renderer/media/OWNERS
 
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos.cc b/extensions/browser/api/networking_private/networking_private_chromeos.cc
index 00d7289e..e904c73f 100644
--- a/extensions/browser/api/networking_private/networking_private_chromeos.cc
+++ b/extensions/browser/api/networking_private/networking_private_chromeos.cc
@@ -739,7 +739,9 @@
 
   std::vector<private_api::Certificate> user_cert_list;
   const std::vector<NetworkCertificateHandler::Certificate>& user_certs =
-      NetworkHandler::Get()->network_certificate_handler()->user_certificates();
+      NetworkHandler::Get()
+          ->network_certificate_handler()
+          ->client_certificates();
   for (const auto& cert : user_certs)
     result.user_certificates.push_back(GetCertDictionary(cert));
 
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn
index 3f3db22..b46a0f23 100644
--- a/google_apis/BUILD.gn
+++ b/google_apis/BUILD.gn
@@ -141,6 +141,10 @@
       "//services/network/public/cpp",
     ]
 
+    if (use_official_google_api_keys) {
+      deps += [ "internal:generate_metrics_key_header" ]
+    }
+
     if (defined(invoker.deps)) {
       deps += invoker.deps
     }
diff --git a/google_apis/gcm/BUILD.gn b/google_apis/gcm/BUILD.gn
index f41b2b2e..fc9fe07 100644
--- a/google_apis/gcm/BUILD.gn
+++ b/google_apis/gcm/BUILD.gn
@@ -174,4 +174,7 @@
     "//testing/gtest",
     "//third_party/protobuf:protobuf_lite",
   ]
+  if (is_android) {
+    deps += [ "//net/android:net_java" ]
+  }
 }
diff --git a/google_apis/google_api_keys.cc b/google_apis/google_api_keys.cc
index 8f0ea9e8..48aa4820 100644
--- a/google_apis/google_api_keys.cc
+++ b/google_apis/google_api_keys.cc
@@ -24,6 +24,7 @@
 
 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
 #include "google_apis/internal/google_chrome_api_keys.h"
+#include "google_apis/internal/metrics_signing_key.h"
 #endif
 
 // Used to indicate an unset key/id/secret.  This works better with
@@ -34,6 +35,10 @@
 #define GOOGLE_API_KEY DUMMY_API_TOKEN
 #endif
 
+#if !defined(GOOGLE_METRICS_SIGNING_KEY)
+#define GOOGLE_METRICS_SIGNING_KEY DUMMY_API_TOKEN
+#endif
+
 #if !defined(GOOGLE_CLIENT_ID_MAIN)
 #define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN
 #endif
@@ -120,6 +125,11 @@
                           STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_REMOTING_FTL),
                           NULL, std::string(), environment.get(), command_line);
 
+    metrics_key_ =
+        CalculateKeyValue(GOOGLE_METRICS_SIGNING_KEY,
+                          STRINGIZE_NO_EXPANSION(GOOGLE_METRICS_SIGNING_KEY),
+                          NULL, std::string(), environment.get(), command_line);
+
     std::string default_client_id =
         CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_ID,
                           STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID),
@@ -209,6 +219,8 @@
   std::string api_key_non_stable() const { return api_key_non_stable_; }
   std::string api_key_remoting_ftl() const { return api_key_remoting_ftl_; }
 
+  std::string metrics_key() const { return metrics_key_; }
+
   std::string GetClientID(OAuth2Client client) const {
     DCHECK_LT(client, CLIENT_NUM_ITEMS);
     return client_ids_[client];
@@ -304,6 +316,7 @@
   std::string api_key_;
   std::string api_key_non_stable_;
   std::string api_key_remoting_ftl_;
+  std::string metrics_key_;
   std::string client_ids_[CLIENT_NUM_ITEMS];
   std::string client_secrets_[CLIENT_NUM_ITEMS];
 };
@@ -333,6 +346,10 @@
 }
 #endif
 
+std::string GetMetricsKey() {
+  return g_api_key_cache.Get().metrics_key();
+}
+
 bool HasOAuthClientConfigured() {
   for (size_t client_id = 0; client_id < CLIENT_NUM_ITEMS; ++client_id) {
     OAuth2Client client = static_cast<OAuth2Client>(client_id);
diff --git a/google_apis/google_api_keys.h b/google_apis/google_api_keys.h
index 6f13643d..01fc4e10 100644
--- a/google_apis/google_api_keys.h
+++ b/google_apis/google_api_keys.h
@@ -83,6 +83,9 @@
 void SetAPIKey(const std::string& api_key);
 #endif
 
+// Retrieves the key used to sign metrics (UMA/UKM) uploads.
+std::string GetMetricsKey();
+
 // Represents the different sets of client IDs and secrets in use.
 enum OAuth2Client {
   CLIENT_MAIN,         // Several different features use this.
diff --git a/gpu/command_buffer/service/command_buffer_direct.cc b/gpu/command_buffer/service/command_buffer_direct.cc
index 6e407cf..f82b529 100644
--- a/gpu/command_buffer/service/command_buffer_direct.cc
+++ b/gpu/command_buffer/service/command_buffer_direct.cc
@@ -48,6 +48,8 @@
 
 void CommandBufferDirect::Flush(int32_t put_offset) {
   DCHECK(handler_);
+  if (GetLastState().error != gpu::error::kNoError)
+    return;
   service_.Flush(put_offset, handler_);
 }
 
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
index 24660c6..7c1aa704 100644
--- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
+++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittest.cc
@@ -439,15 +439,15 @@
 }
 #endif  // defined(OS_LINUX)
 
-INSTANTIATE_TEST_CASE_P(GpuMemoryBufferTests,
-                        GpuMemoryBufferTest,
-                        ::testing::Values(gfx::BufferFormat::R_8,
-                                          gfx::BufferFormat::BGR_565,
-                                          gfx::BufferFormat::RGBA_4444,
-                                          gfx::BufferFormat::RGBA_8888,
-                                          gfx::BufferFormat::RGBX_1010102,
-                                          gfx::BufferFormat::BGRA_8888,
-                                          gfx::BufferFormat::RGBA_F16));
+INSTANTIATE_TEST_SUITE_P(GpuMemoryBufferTests,
+                         GpuMemoryBufferTest,
+                         ::testing::Values(gfx::BufferFormat::R_8,
+                                           gfx::BufferFormat::BGR_565,
+                                           gfx::BufferFormat::RGBA_4444,
+                                           gfx::BufferFormat::RGBA_8888,
+                                           gfx::BufferFormat::RGBX_1010102,
+                                           gfx::BufferFormat::BGRA_8888,
+                                           gfx::BufferFormat::RGBA_F16));
 
 }  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/config/gpu_info_collector_unittest.cc b/gpu/config/gpu_info_collector_unittest.cc
index c73e99e..77aa910 100644
--- a/gpu/config/gpu_info_collector_unittest.cc
+++ b/gpu/config/gpu_info_collector_unittest.cc
@@ -196,9 +196,9 @@
   std::vector<std::string> split_extensions_;
 };
 
-INSTANTIATE_TEST_CASE_P(GPUConfig,
-                        GPUInfoCollectorTest,
-                        ::testing::ValuesIn(kMockedOperatingSystemKinds));
+INSTANTIATE_TEST_SUITE_P(GPUConfig,
+                         GPUInfoCollectorTest,
+                         ::testing::ValuesIn(kMockedOperatingSystemKinds));
 
 // TODO(rlp): Test the vendor and device id collection if deemed necessary as
 //            it involves several complicated mocks for each platform.
diff --git a/gpu/config/gpu_test_expectations_parser_unittest.cc b/gpu/config/gpu_test_expectations_parser_unittest.cc
index 72acc7c9..d1000f6 100644
--- a/gpu/config/gpu_test_expectations_parser_unittest.cc
+++ b/gpu/config/gpu_test_expectations_parser_unittest.cc
@@ -345,9 +345,9 @@
   EXPECT_NE(0u, parser.GetErrorMessages().size());
 }
 
-INSTANTIATE_TEST_CASE_P(GPUTestExpectationsParser,
-                        GPUTestExpectationsParserParamTest,
-                        ::testing::ValuesIn(kOSVersionsWithFamily));
+INSTANTIATE_TEST_SUITE_P(GPUTestExpectationsParser,
+                         GPUTestExpectationsParserParamTest,
+                         ::testing::ValuesIn(kOSVersionsWithFamily));
 
 }  // namespace gpu
 
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_android_hardware_buffer_unittest.cc b/gpu/ipc/common/gpu_memory_buffer_impl_android_hardware_buffer_unittest.cc
index a7f3a62..01e419b 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_android_hardware_buffer_unittest.cc
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_android_hardware_buffer_unittest.cc
@@ -8,13 +8,13 @@
 namespace gpu {
 namespace {
 
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplAndroidHardwareBuffer,
-                              GpuMemoryBufferImplTest,
-                              GpuMemoryBufferImplAndroidHardwareBuffer);
+INSTANTIATE_TYPED_TEST_SUITE_P(GpuMemoryBufferImplAndroidHardwareBuffer,
+                               GpuMemoryBufferImplTest,
+                               GpuMemoryBufferImplAndroidHardwareBuffer);
 
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplAndroidHardwareBuffer,
-                              GpuMemoryBufferImplCreateTest,
-                              GpuMemoryBufferImplAndroidHardwareBuffer);
+INSTANTIATE_TYPED_TEST_SUITE_P(GpuMemoryBufferImplAndroidHardwareBuffer,
+                               GpuMemoryBufferImplCreateTest,
+                               GpuMemoryBufferImplAndroidHardwareBuffer);
 
 }  // namespace
 }  // namespace gpu
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_dxgi_unittest.cc b/gpu/ipc/common/gpu_memory_buffer_impl_dxgi_unittest.cc
index f1a24dc1..586dbdb 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_dxgi_unittest.cc
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_dxgi_unittest.cc
@@ -9,8 +9,8 @@
 namespace {
 
 // Disabled by default as it requires DX11.
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GpuMemoryBufferImplDXGI,
-                              GpuMemoryBufferImplTest,
-                              GpuMemoryBufferImplDXGI);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GpuMemoryBufferImplDXGI,
+                               GpuMemoryBufferImplTest,
+                               GpuMemoryBufferImplDXGI);
 }  // namespace
 }  // namespace gpu
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap_unittest.cc b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap_unittest.cc
index 2b0dc470..bf77a6d 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap_unittest.cc
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap_unittest.cc
@@ -8,9 +8,9 @@
 namespace gpu {
 namespace {
 
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplNativePixmap,
-                              GpuMemoryBufferImplTest,
-                              GpuMemoryBufferImplNativePixmap);
+INSTANTIATE_TYPED_TEST_SUITE_P(GpuMemoryBufferImplNativePixmap,
+                               GpuMemoryBufferImplTest,
+                               GpuMemoryBufferImplNativePixmap);
 
 }  // namespace
 }  // namespace gpu
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory_unittest.cc b/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory_unittest.cc
index af95651..80b32ba 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory_unittest.cc
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory_unittest.cc
@@ -10,13 +10,13 @@
 namespace gpu {
 namespace {
 
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplSharedMemory,
-                              GpuMemoryBufferImplTest,
-                              GpuMemoryBufferImplSharedMemory);
+INSTANTIATE_TYPED_TEST_SUITE_P(GpuMemoryBufferImplSharedMemory,
+                               GpuMemoryBufferImplTest,
+                               GpuMemoryBufferImplSharedMemory);
 
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferImplSharedMemory,
-                              GpuMemoryBufferImplCreateTest,
-                              GpuMemoryBufferImplSharedMemory);
+INSTANTIATE_TYPED_TEST_SUITE_P(GpuMemoryBufferImplSharedMemory,
+                               GpuMemoryBufferImplCreateTest,
+                               GpuMemoryBufferImplSharedMemory);
 
 }  // namespace
 }  // namespace gpu
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_test_template.h b/gpu/ipc/common/gpu_memory_buffer_impl_test_template.h
index 5b3a9a0c3..1f1658db 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_test_template.h
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_test_template.h
@@ -81,7 +81,7 @@
   GpuMemoryBufferSupport gpu_memory_buffer_support_;
 };
 
-TYPED_TEST_CASE_P(GpuMemoryBufferImplTest);
+TYPED_TEST_SUITE_P(GpuMemoryBufferImplTest);
 
 TYPED_TEST_P(GpuMemoryBufferImplTest, CreateFromHandle) {
   const gfx::Size kBufferSize(8, 8);
@@ -298,13 +298,13 @@
 
 // The GpuMemoryBufferImplTest test case verifies behavior that is expected
 // from a GpuMemoryBuffer implementation in order to be conformant.
-REGISTER_TYPED_TEST_CASE_P(GpuMemoryBufferImplTest,
-                           CreateFromHandle,
-                           Map,
-                           PersistentMap,
-                           SerializeAndDeserialize);
+REGISTER_TYPED_TEST_SUITE_P(GpuMemoryBufferImplTest,
+                            CreateFromHandle,
+                            Map,
+                            PersistentMap,
+                            SerializeAndDeserialize);
 
-TYPED_TEST_CASE_P(GpuMemoryBufferImplCreateTest);
+TYPED_TEST_SUITE_P(GpuMemoryBufferImplCreateTest);
 
 TYPED_TEST_P(GpuMemoryBufferImplCreateTest, Create) {
   const gfx::GpuMemoryBufferId kBufferId(1);
@@ -332,7 +332,7 @@
 // The GpuMemoryBufferImplCreateTest test case verifies behavior that is
 // expected from a GpuMemoryBuffer Create() implementation in order to be
 // conformant.
-REGISTER_TYPED_TEST_CASE_P(GpuMemoryBufferImplCreateTest, Create);
+REGISTER_TYPED_TEST_SUITE_P(GpuMemoryBufferImplCreateTest, Create);
 
 }  // namespace gpu
 
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc
index 7ac4bed..dafd9dc 100644
--- a/gpu/ipc/service/command_buffer_stub.cc
+++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -20,14 +20,9 @@
 #include "build/build_config.h"
 #include "gpu/command_buffer/common/constants.h"
 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
-#include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "gpu/command_buffer/service/decoder_context.h"
-#include "gpu/command_buffer/service/gl_context_virtual.h"
-#include "gpu/command_buffer/service/gl_state_restorer_impl.h"
 #include "gpu/command_buffer/service/gpu_command_buffer_memory_tracker.h"
-#include "gpu/command_buffer/service/gpu_fence_manager.h"
-#include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/logger.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/memory_tracking.h"
@@ -35,17 +30,13 @@
 #include "gpu/command_buffer/service/scheduler.h"
 #include "gpu/command_buffer/service/service_utils.h"
 #include "gpu/command_buffer/service/sync_point_manager.h"
-#include "gpu/command_buffer/service/transfer_buffer_manager.h"
 #include "gpu/config/gpu_crash_keys.h"
 #include "gpu/ipc/common/gpu_messages.h"
 #include "gpu/ipc/service/gpu_channel.h"
 #include "gpu/ipc/service/gpu_channel_manager.h"
 #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
-#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
 #include "gpu/ipc/service/gpu_watchdog_thread.h"
 #include "gpu/ipc/service/image_transport_surface.h"
-#include "ui/gfx/gpu_fence.h"
-#include "ui/gfx/gpu_fence_handle.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_image.h"
@@ -185,35 +176,30 @@
     have_context = true;
   }
 
-  // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
-  // here. This is so the reply can be delayed if the scheduler is unscheduled.
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(CommandBufferStub, message)
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetGetBuffer, OnSetGetBuffer);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_TakeFrontBuffer, OnTakeFrontBuffer);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ReturnFrontBuffer,
-                        OnReturnFrontBuffer);
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForTokenInRange,
-                                    OnWaitForTokenInRange);
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForGetOffsetInRange,
-                                    OnWaitForGetOffsetInRange);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer,
-                        OnRegisterTransferBuffer);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
-                        OnDestroyTransferBuffer);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncToken, OnSignalSyncToken)
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery, OnSignalQuery)
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture,
-                        OnCreateStreamTexture)
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateGpuFenceFromHandle,
-                        OnCreateGpuFenceFromHandle)
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetGpuFenceHandle,
-                        OnGetGpuFenceHandle)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
+  bool handled = HandleMessage(message);
+  if (!handled) {
+    handled = true;
+    // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message
+    // handlers here. This is so the reply can be delayed if the scheduler is
+    // unscheduled.
+    IPC_BEGIN_MESSAGE_MAP(CommandBufferStub, message)
+      IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetGetBuffer, OnSetGetBuffer);
+      IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForTokenInRange,
+                                      OnWaitForTokenInRange);
+      IPC_MESSAGE_HANDLER_DELAY_REPLY(
+          GpuCommandBufferMsg_WaitForGetOffsetInRange,
+          OnWaitForGetOffsetInRange);
+      IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
+      IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer,
+                          OnRegisterTransferBuffer);
+      IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
+                          OnDestroyTransferBuffer);
+      IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncToken,
+                          OnSignalSyncToken)
+      IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery, OnSignalQuery)
+      IPC_MESSAGE_UNHANDLED(handled = false)
+    IPC_END_MESSAGE_MAP()
+  }
 
   CheckCompleteWaits();
 
@@ -418,16 +404,6 @@
   command_buffer_.reset();
 }
 
-void CommandBufferStub::OnCreateStreamTexture(uint32_t texture_id,
-                                              int32_t stream_id,
-                                              bool* succeeded) {
-#if defined(OS_ANDROID)
-  *succeeded = StreamTexture::Create(this, texture_id, stream_id);
-#else
-  *succeeded = false;
-#endif
-}
-
 void CommandBufferStub::OnSetGetBuffer(int32_t shm_id) {
   TRACE_EVENT0("gpu", "CommandBufferStub::OnSetGetBuffer");
   if (command_buffer_)
@@ -634,50 +610,6 @@
     OnSignalAck(id);
   }
 }
-
-void CommandBufferStub::OnCreateGpuFenceFromHandle(
-    uint32_t gpu_fence_id,
-    const gfx::GpuFenceHandle& handle) {
-  if (!context_group_->feature_info()->feature_flags().chromium_gpu_fence) {
-    DLOG(ERROR) << "CHROMIUM_gpu_fence unavailable";
-    command_buffer_->SetParseError(error::kLostContext);
-    return;
-  }
-
-  if (decoder_context_->GetGpuFenceManager()->CreateGpuFenceFromHandle(
-          gpu_fence_id, handle))
-    return;
-
-  // The insertion failed. This shouldn't happen, force context loss to avoid
-  // inconsistent state.
-  command_buffer_->SetParseError(error::kLostContext);
-  CheckContextLost();
-}
-
-void CommandBufferStub::OnGetGpuFenceHandle(uint32_t gpu_fence_id) {
-  if (!context_group_->feature_info()->feature_flags().chromium_gpu_fence) {
-    DLOG(ERROR) << "CHROMIUM_gpu_fence unavailable";
-    command_buffer_->SetParseError(error::kLostContext);
-    return;
-  }
-
-  auto* manager = decoder_context_->GetGpuFenceManager();
-  gfx::GpuFenceHandle handle;
-  if (manager->IsValidGpuFence(gpu_fence_id)) {
-    std::unique_ptr<gfx::GpuFence> gpu_fence =
-        manager->GetGpuFence(gpu_fence_id);
-    handle = gfx::CloneHandleForIPC(gpu_fence->GetGpuFenceHandle());
-  } else {
-    // Retrieval failed. This shouldn't happen, force context loss to avoid
-    // inconsistent state.
-    DLOG(ERROR) << "GpuFence not found";
-    command_buffer_->SetParseError(error::kLostContext);
-    CheckContextLost();
-  }
-  Send(new GpuCommandBufferMsg_GetGpuFenceHandleComplete(route_id_,
-                                                         gpu_fence_id, handle));
-}
-
 void CommandBufferStub::OnFenceSyncRelease(uint64_t release) {
   SyncToken sync_token(CommandBufferNamespace::GPU_IO, command_buffer_id_,
                        release);
@@ -708,55 +640,6 @@
   channel_->gpu_channel_manager()->ScheduleGrContextCleanup();
 }
 
-void CommandBufferStub::OnCreateImage(
-    GpuCommandBufferMsg_CreateImage_Params params) {
-  TRACE_EVENT0("gpu", "CommandBufferStub::OnCreateImage");
-  const int32_t id = params.id;
-  const gfx::Size& size = params.size;
-  const gfx::BufferFormat& format = params.format;
-  const uint64_t image_release_count = params.image_release_count;
-
-  gles2::ImageManager* image_manager = channel_->image_manager();
-  DCHECK(image_manager);
-  if (image_manager->LookupImage(id)) {
-    LOG(ERROR) << "Image already exists with same ID.";
-    return;
-  }
-
-  if (!gpu::IsImageFromGpuMemoryBufferFormatSupported(
-          format, decoder_context_->GetCapabilities())) {
-    LOG(ERROR) << "Format is not supported.";
-    return;
-  }
-
-  if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size, format)) {
-    LOG(ERROR) << "Invalid image size for format.";
-    return;
-  }
-
-  scoped_refptr<gl::GLImage> image = channel()->CreateImageForGpuMemoryBuffer(
-      std::move(params.gpu_memory_buffer), size, format, surface_handle_);
-  if (!image.get())
-    return;
-
-  image_manager->AddImage(image.get(), id);
-  if (image_release_count)
-    sync_point_client_state_->ReleaseFenceSync(image_release_count);
-}
-
-void CommandBufferStub::OnDestroyImage(int32_t id) {
-  TRACE_EVENT0("gpu", "CommandBufferStub::OnDestroyImage");
-
-  gles2::ImageManager* image_manager = channel_->image_manager();
-  DCHECK(image_manager);
-  if (!image_manager->LookupImage(id)) {
-    LOG(ERROR) << "Image with ID doesn't exist.";
-    return;
-  }
-
-  image_manager->RemoveImage(id);
-}
-
 void CommandBufferStub::OnConsoleMessage(int32_t id,
                                          const std::string& message) {
   GPUCommandBufferConsoleMessage console_message;
diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h
index 2b2b8e8d..8c08963 100644
--- a/gpu/ipc/service/command_buffer_stub.h
+++ b/gpu/ipc/service/command_buffer_stub.h
@@ -31,7 +31,6 @@
 #include "ipc/ipc_listener.h"
 #include "ipc/ipc_sender.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_fence_handle.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/swap_result.h"
 #include "ui/gl/gl_share_group.h"
@@ -40,11 +39,9 @@
 #include "url/gurl.h"
 
 struct GPUCreateCommandBufferConfig;
-struct GpuCommandBufferMsg_CreateImage_Params;
 
 namespace gpu {
 class DecoderContext;
-struct Mailbox;
 class MemoryTracker;
 struct SyncToken;
 struct WaitForCommandState;
@@ -143,6 +140,7 @@
   scoped_refptr<gl::GLShareGroup> share_group() { return share_group_; }
 
  protected:
+  virtual bool HandleMessage(const IPC::Message& message) = 0;
   // FastSetActiveURL will shortcut the expensive call to SetActiveURL when the
   // url_hash matches.
   static void FastSetActiveURL(const GURL& url,
@@ -157,6 +155,7 @@
   void set_decoder_context(std::unique_ptr<DecoderContext> decoder_context) {
     decoder_context_ = std::move(decoder_context);
   }
+  bool CheckContextLost();
 
   // The lifetime of objects of this class is managed by a GpuChannel. The
   // GpuChannels destroy all the CommandBufferStubs that they own when
@@ -193,8 +192,6 @@
 
   // Message handlers:
   void OnSetGetBuffer(int32_t shm_id);
-  virtual void OnTakeFrontBuffer(const Mailbox& mailbox) = 0;
-  virtual void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) = 0;
   void OnGetState(IPC::Message* reply_message);
   void OnWaitForTokenInRange(int32_t start,
                              int32_t end,
@@ -211,20 +208,9 @@
   void OnDestroyTransferBuffer(int32_t id);
   void OnGetTransferBuffer(int32_t id, IPC::Message* reply_message);
 
-  void OnEnsureBackbuffer();
-
   void OnSignalSyncToken(const SyncToken& sync_token, uint32_t id);
   void OnSignalAck(uint32_t id);
   void OnSignalQuery(uint32_t query, uint32_t id);
-  void OnCreateGpuFenceFromHandle(uint32_t gpu_fence_id,
-                                  const gfx::GpuFenceHandle& handle);
-  void OnGetGpuFenceHandle(uint32_t gpu_fence_id);
-
-  void OnCreateImage(GpuCommandBufferMsg_CreateImage_Params params);
-  void OnDestroyImage(int32_t id);
-  void OnCreateStreamTexture(uint32_t texture_id,
-                             int32_t stream_id,
-                             bool* succeeded);
 
   void ReportState();
 
@@ -238,7 +224,6 @@
   // of delayed work.
   void ScheduleDelayedWork(base::TimeDelta delay);
 
-  bool CheckContextLost();
   void CheckCompleteWaits();
 
   // Set driver bug workarounds and disabled GL extensions to the context.
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc
index fccec34..199b4476 100644
--- a/gpu/ipc/service/gles2_command_buffer_stub.cc
+++ b/gpu/ipc/service/gles2_command_buffer_stub.cc
@@ -26,6 +26,7 @@
 #include "gpu/command_buffer/common/swap_buffers_flags.h"
 #include "gpu/command_buffer/service/gl_context_virtual.h"
 #include "gpu/command_buffer/service/gl_state_restorer_impl.h"
+#include "gpu/command_buffer/service/gpu_fence_manager.h"
 #include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/logger.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
@@ -41,6 +42,8 @@
 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
 #include "gpu/ipc/service/gpu_watchdog_thread.h"
 #include "gpu/ipc/service/image_transport_surface.h"
+#include "ui/gfx/gpu_fence.h"
+#include "ui/gfx/gpu_fence_handle.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_image.h"
@@ -415,13 +418,28 @@
   return route_id_;
 }
 
+bool GLES2CommandBufferStub::HandleMessage(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(GLES2CommandBufferStub, message)
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_TakeFrontBuffer, OnTakeFrontBuffer);
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ReturnFrontBuffer,
+                        OnReturnFrontBuffer);
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage);
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage);
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture,
+                        OnCreateStreamTexture)
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateGpuFenceFromHandle,
+                        OnCreateGpuFenceFromHandle)
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetGpuFenceHandle,
+                        OnGetGpuFenceHandle)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
 void GLES2CommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) {
   TRACE_EVENT0("gpu", "CommandBufferStub::OnTakeFrontBuffer");
-  if (!gles2_decoder_) {
-    LOG(ERROR) << "Can't take front buffer before initialization.";
-    return;
-  }
-
+  DCHECK(gles2_decoder_);
   gles2_decoder_->TakeFrontBuffer(mailbox);
 }
 
@@ -432,6 +450,108 @@
   gles2_decoder_->ReturnFrontBuffer(mailbox, is_lost);
 }
 
+void GLES2CommandBufferStub::OnCreateGpuFenceFromHandle(
+    uint32_t gpu_fence_id,
+    const gfx::GpuFenceHandle& handle) {
+  if (!context_group_->feature_info()->feature_flags().chromium_gpu_fence) {
+    DLOG(ERROR) << "CHROMIUM_gpu_fence unavailable";
+    command_buffer_->SetParseError(error::kLostContext);
+    return;
+  }
+
+  if (gles2_decoder_->GetGpuFenceManager()->CreateGpuFenceFromHandle(
+          gpu_fence_id, handle))
+    return;
+
+  // The insertion failed. This shouldn't happen, force context loss to avoid
+  // inconsistent state.
+  command_buffer_->SetParseError(error::kLostContext);
+  CheckContextLost();
+}
+
+void GLES2CommandBufferStub::OnGetGpuFenceHandle(uint32_t gpu_fence_id) {
+  if (!context_group_->feature_info()->feature_flags().chromium_gpu_fence) {
+    DLOG(ERROR) << "CHROMIUM_gpu_fence unavailable";
+    command_buffer_->SetParseError(error::kLostContext);
+    return;
+  }
+
+  auto* manager = gles2_decoder_->GetGpuFenceManager();
+  gfx::GpuFenceHandle handle;
+  if (manager->IsValidGpuFence(gpu_fence_id)) {
+    std::unique_ptr<gfx::GpuFence> gpu_fence =
+        manager->GetGpuFence(gpu_fence_id);
+    handle = gfx::CloneHandleForIPC(gpu_fence->GetGpuFenceHandle());
+  } else {
+    // Retrieval failed. This shouldn't happen, force context loss to avoid
+    // inconsistent state.
+    DLOG(ERROR) << "GpuFence not found";
+    command_buffer_->SetParseError(error::kLostContext);
+    CheckContextLost();
+  }
+  Send(new GpuCommandBufferMsg_GetGpuFenceHandleComplete(route_id_,
+                                                         gpu_fence_id, handle));
+}
+
+void GLES2CommandBufferStub::OnCreateImage(
+    GpuCommandBufferMsg_CreateImage_Params params) {
+  TRACE_EVENT0("gpu", "GLES2CommandBufferStub::OnCreateImage");
+  const int32_t id = params.id;
+  const gfx::Size& size = params.size;
+  const gfx::BufferFormat& format = params.format;
+  const uint64_t image_release_count = params.image_release_count;
+
+  gles2::ImageManager* image_manager = channel_->image_manager();
+  DCHECK(image_manager);
+  if (image_manager->LookupImage(id)) {
+    LOG(ERROR) << "Image already exists with same ID.";
+    return;
+  }
+
+  if (!gpu::IsImageFromGpuMemoryBufferFormatSupported(
+          format, gles2_decoder_->GetCapabilities())) {
+    LOG(ERROR) << "Format is not supported.";
+    return;
+  }
+
+  if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size, format)) {
+    LOG(ERROR) << "Invalid image size for format.";
+    return;
+  }
+
+  scoped_refptr<gl::GLImage> image = channel()->CreateImageForGpuMemoryBuffer(
+      std::move(params.gpu_memory_buffer), size, format, surface_handle_);
+  if (!image.get())
+    return;
+
+  image_manager->AddImage(image.get(), id);
+  if (image_release_count)
+    sync_point_client_state_->ReleaseFenceSync(image_release_count);
+}
+
+void GLES2CommandBufferStub::OnDestroyImage(int32_t id) {
+  TRACE_EVENT0("gpu", "GLES2CommandBufferStub::OnDestroyImage");
+
+  gles2::ImageManager* image_manager = channel_->image_manager();
+  DCHECK(image_manager);
+  if (!image_manager->LookupImage(id)) {
+    LOG(ERROR) << "Image with ID doesn't exist.";
+    return;
+  }
+
+  image_manager->RemoveImage(id);
+}
+
+void GLES2CommandBufferStub::OnCreateStreamTexture(uint32_t texture_id,
+                                                   int32_t stream_id,
+                                                   bool* succeeded) {
+#if defined(OS_ANDROID)
+  *succeeded = StreamTexture::Create(this, texture_id, stream_id);
+#else
+  *succeeded = false;
+#endif
+}
+
 void GLES2CommandBufferStub::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {
   pending_swap_completed_params_.push_back({swap_id, flags});
   pending_presented_params_.push_back({swap_id, flags});
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.h b/gpu/ipc/service/gles2_command_buffer_stub.h
index 4d4530ba..8a760a5 100644
--- a/gpu/ipc/service/gles2_command_buffer_stub.h
+++ b/gpu/ipc/service/gles2_command_buffer_stub.h
@@ -10,8 +10,11 @@
 #include "build/build_config.h"
 #include "gpu/ipc/service/command_buffer_stub.h"
 #include "gpu/ipc/service/image_transport_surface_delegate.h"
+#include "ui/gfx/gpu_fence_handle.h"
 
+struct GpuCommandBufferMsg_CreateImage_Params;
 namespace gpu {
+struct Mailbox;
 
 class GPU_IPC_SERVICE_EXPORT GLES2CommandBufferStub
     : public CommandBufferStub,
@@ -50,8 +53,18 @@
   int32_t GetRouteID() const override;
 
  private:
-  void OnTakeFrontBuffer(const Mailbox& mailbox) override;
-  void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
+  bool HandleMessage(const IPC::Message& message) override;
+  void OnTakeFrontBuffer(const Mailbox& mailbox);
+  void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost);
+  void OnCreateGpuFenceFromHandle(uint32_t gpu_fence_id,
+                                  const gfx::GpuFenceHandle& handle);
+  void OnGetGpuFenceHandle(uint32_t gpu_fence_id);
+  void OnCreateImage(GpuCommandBufferMsg_CreateImage_Params params);
+  void OnDestroyImage(int32_t id);
+  void OnCreateStreamTexture(uint32_t texture_id,
+                             int32_t stream_id,
+                             bool* succeeded);
+
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
 
   // Keep a more specifically typed reference to the decoder to avoid
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi_unittest.cc b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi_unittest.cc
index c334e816..d4dc4e5 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi_unittest.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi_unittest.cc
@@ -9,9 +9,9 @@
 namespace {
 
 // Disabled by default as it requires DX11.
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GpuMemoryBufferFactoryDXGI,
-                              GpuMemoryBufferFactoryTest,
-                              GpuMemoryBufferFactoryDXGI);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GpuMemoryBufferFactoryDXGI,
+                               GpuMemoryBufferFactoryTest,
+                               GpuMemoryBufferFactoryDXGI);
 
 }  // namespace
 }  // namespace gpu
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_io_surface_unittest.cc b/gpu/ipc/service/gpu_memory_buffer_factory_io_surface_unittest.cc
index 66809f8..2e0b670 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_io_surface_unittest.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_io_surface_unittest.cc
@@ -8,9 +8,9 @@
 namespace gpu {
 namespace {
 
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryIOSurface,
-                              GpuMemoryBufferFactoryTest,
-                              GpuMemoryBufferFactoryIOSurface);
+INSTANTIATE_TYPED_TEST_SUITE_P(GpuMemoryBufferFactoryIOSurface,
+                               GpuMemoryBufferFactoryTest,
+                               GpuMemoryBufferFactoryIOSurface);
 
 }  // namespace
 }  // namespace gpu
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap_unittest.cc b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap_unittest.cc
index 2c381184..b1d1102 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap_unittest.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap_unittest.cc
@@ -8,9 +8,9 @@
 namespace gpu {
 namespace {
 
-INSTANTIATE_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryNativePixmap,
-                              GpuMemoryBufferFactoryTest,
-                              GpuMemoryBufferFactoryNativePixmap);
+INSTANTIATE_TYPED_TEST_SUITE_P(GpuMemoryBufferFactoryNativePixmap,
+                               GpuMemoryBufferFactoryTest,
+                               GpuMemoryBufferFactoryNativePixmap);
 
 }  // namespace
 }  // namespace gpu
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h b/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h
index 5678193d..b9e8aa4 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h
@@ -41,7 +41,7 @@
   GpuMemoryBufferFactoryType factory_;
 };
 
-TYPED_TEST_CASE_P(GpuMemoryBufferFactoryTest);
+TYPED_TEST_SUITE_P(GpuMemoryBufferFactoryTest);
 
 TYPED_TEST_P(GpuMemoryBufferFactoryTest, CreateGpuMemoryBuffer) {
   const gfx::GpuMemoryBufferId kBufferId(1);
@@ -76,7 +76,7 @@
 
 // The GpuMemoryBufferFactoryTest test case verifies behavior that is expected
 // from a GpuMemoryBuffer factory in order to be conformant.
-REGISTER_TYPED_TEST_CASE_P(GpuMemoryBufferFactoryTest, CreateGpuMemoryBuffer);
+REGISTER_TYPED_TEST_SUITE_P(GpuMemoryBufferFactoryTest, CreateGpuMemoryBuffer);
 
 }  // namespace gpu
 
diff --git a/gpu/ipc/service/raster_command_buffer_stub.cc b/gpu/ipc/service/raster_command_buffer_stub.cc
index 3b856eb..c033f4d4 100644
--- a/gpu/ipc/service/raster_command_buffer_stub.cc
+++ b/gpu/ipc/service/raster_command_buffer_stub.cc
@@ -193,13 +193,8 @@
   return gpu::ContextResult::kSuccess;
 }
 
-// RasterInterface clients should not manipulate the front buffer.
-void RasterCommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) {
-  NOTREACHED();
-}
-void RasterCommandBufferStub::OnReturnFrontBuffer(const Mailbox& mailbox,
-                                                  bool is_lost) {
-  NOTREACHED();
+bool RasterCommandBufferStub::HandleMessage(const IPC::Message& message) {
+  return false;
 }
 
 void RasterCommandBufferStub::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {}
diff --git a/gpu/ipc/service/raster_command_buffer_stub.h b/gpu/ipc/service/raster_command_buffer_stub.h
index 54cd8a320..ad464193 100644
--- a/gpu/ipc/service/raster_command_buffer_stub.h
+++ b/gpu/ipc/service/raster_command_buffer_stub.h
@@ -29,8 +29,7 @@
       base::UnsafeSharedMemoryRegion shared_state_shm) override;
 
  private:
-  void OnTakeFrontBuffer(const Mailbox& mailbox) override;
-  void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
+  bool HandleMessage(const IPC::Message& message) override;
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
   void SetActiveURL(GURL url) override;
 
diff --git a/gpu/ipc/service/webgpu_command_buffer_stub.cc b/gpu/ipc/service/webgpu_command_buffer_stub.cc
index 1dcc0c0..e8833f4 100644
--- a/gpu/ipc/service/webgpu_command_buffer_stub.cc
+++ b/gpu/ipc/service/webgpu_command_buffer_stub.cc
@@ -164,13 +164,8 @@
 #endif  // defined(OS_FUCHSIA)
 }
 
-// WebGPUInterface clients should not manipulate the front buffer.
-void WebGPUCommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) {
-  LOG(ERROR) << "Called WebGPUCommandBufferStub::OnTakeFrontBuffer";
-}
-void WebGPUCommandBufferStub::OnReturnFrontBuffer(const Mailbox& mailbox,
-                                                  bool is_lost) {
-  LOG(ERROR) << "Called WebGPUCommandBufferStub::OnReturnFrontBuffer";
+bool WebGPUCommandBufferStub::HandleMessage(const IPC::Message& message) {
+  return false;
 }
 
 void WebGPUCommandBufferStub::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {}
diff --git a/gpu/ipc/service/webgpu_command_buffer_stub.h b/gpu/ipc/service/webgpu_command_buffer_stub.h
index cc74b5d..344e11ca 100644
--- a/gpu/ipc/service/webgpu_command_buffer_stub.h
+++ b/gpu/ipc/service/webgpu_command_buffer_stub.h
@@ -29,8 +29,7 @@
       base::UnsafeSharedMemoryRegion shared_state_shm) override;
 
  private:
-  void OnTakeFrontBuffer(const Mailbox& mailbox) override;
-  void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
+  bool HandleMessage(const IPC::Message& message) override;
   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
 
   DISALLOW_COPY_AND_ASSIGN(WebGPUCommandBufferStub);
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm
index 96cbca5..e836f715 100644
--- a/ios/chrome/browser/passwords/password_controller.mm
+++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -295,7 +295,7 @@
 
   // Notify the password manager that the page loaded so it can clear its own
   // per-page state.
-  self.passwordManager->DidNavigateMainFrame(/*form_may_be_submitted=*/false);
+  self.passwordManager->DidNavigateMainFrame(/*form_may_be_submitted=*/true);
 
   if (!webState->ContentIsHTML()) {
     // If the current page is not HTML, it does not contain any HTML forms.
diff --git a/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.mm b/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.mm
index 25daae7..e40803f5 100644
--- a/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.mm
+++ b/ios/chrome/browser/ui/authentication/signin_earlgrey_utils.mm
@@ -47,8 +47,9 @@
 
   ios::ChromeBrowserState* browser_state =
       chrome_test_util::GetOriginalBrowserState();
-  AccountInfo info = IdentityManagerFactory::GetForBrowserState(browser_state)
-                         ->GetPrimaryAccountInfo();
+  CoreAccountInfo info =
+      IdentityManagerFactory::GetForBrowserState(browser_state)
+          ->GetPrimaryAccountInfo();
 
   GREYAssertEqual(base::SysNSStringToUTF8(identity.gaiaID), info.gaia,
                   @"Unexpected Gaia ID of the signed in user [expected = "
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h
index d6ab22f..da0d99f4 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h
@@ -24,6 +24,7 @@
 @protocol LogoVendor;
 @protocol NTPHomeConsumer;
 @class NTPHomeMetrics;
+@protocol OmniboxFocuser;
 class TemplateURLService;
 @protocol SnackbarCommands;
 @protocol UrlLoader;
@@ -45,9 +46,12 @@
 - (nullable instancetype)init NS_UNAVAILABLE;
 
 // Dispatcher.
-@property(nonatomic, weak, nullable)
-    id<ApplicationCommands, BrowserCommands, SnackbarCommands, UrlLoader>
-        dispatcher;
+@property(nonatomic, weak, nullable) id<ApplicationCommands,
+                                        BrowserCommands,
+                                        OmniboxFocuser,
+                                        SnackbarCommands,
+                                        UrlLoader>
+    dispatcher;
 // Suggestions service used to get the suggestions.
 @property(nonatomic, assign, nonnull)
     ntp_snippets::ContentSuggestionsService* suggestionsService;
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
index 2eec4f0..ca47ea3 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
@@ -37,6 +37,7 @@
 #include "ios/chrome/browser/ui/ntp/metrics.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h"
 #import "ios/chrome/browser/ui/ntp/notification_promo_whats_new.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 #include "ios/chrome/browser/ui/ui_feature_flags.h"
 #import "ios/chrome/browser/ui/url_loader.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
@@ -545,6 +546,11 @@
                                 inBackground:!incognito
                                     appendTo:kCurrentTab];
   command.originPoint = originPoint;
+  if (incognito) {
+    // Unfocus the omnibox if the new page should be opened in incognito to
+    // prevent staying stuck.
+    [self.dispatcher cancelOmniboxEdit];
+  }
   [self.dispatcher webPageOrderedOpen:command];
 }
 
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller.mm
index c9a10da..97483a4 100644
--- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller.mm
+++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller.mm
@@ -138,7 +138,7 @@
 - (void)reAuthenticateWithCompletion:(CompletionCallback)completion {
   signin_metrics::LogSigninAccessPointStarted(accessPoint_, promoAction_);
   completionCallback_ = [completion copy];
-  AccountInfo accountInfo =
+  CoreAccountInfo accountInfo =
       IdentityManagerFactory::GetForBrowserState(browserState_)
           ->GetPrimaryAccountInfo();
   std::string emailToReauthenticate = accountInfo.email;
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 4a47af7..9cbaa97 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -5011,7 +5011,8 @@
   if (context) {
     web::NavigationManager* navigationManager =
         _webStateImpl->GetNavigationManager();
-    if ((navigationManager->GetPendingItem()) ||
+    if ((navigationManager->GetPendingItem() &&
+         navigationManager->GetPendingItem()->GetURL() == webViewURL) ||
         (context->IsLoadingHtmlString()) ||
         (!web::GetWebClient()->IsSlimNavigationManagerEnabled() &&
          ui::PageTransitionCoreTypeIs(context->GetPageTransition(),
diff --git a/ios/web_view/internal/passwords/cwv_password_controller.mm b/ios/web_view/internal/passwords/cwv_password_controller.mm
index 62a88d9..628c3f1a 100644
--- a/ios/web_view/internal/passwords/cwv_password_controller.mm
+++ b/ios/web_view/internal/passwords/cwv_password_controller.mm
@@ -160,7 +160,7 @@
 
   // Notify the password manager that the page loaded so it can clear its own
   // per-page state.
-  _passwordManager->DidNavigateMainFrame(/*form_may_be_submitted=*/false);
+  _passwordManager->DidNavigateMainFrame(/*form_may_be_submitted=*/true);
 
   if (!webState->ContentIsHTML()) {
     // If the current page is not HTML, it does not contain any HTML forms.
diff --git a/net/http/http_proxy_connect_job_unittest.cc b/net/http/http_proxy_connect_job_unittest.cc
index f198875a..a8c768c 100644
--- a/net/http/http_proxy_connect_job_unittest.cc
+++ b/net/http/http_proxy_connect_job_unittest.cc
@@ -266,9 +266,9 @@
 
 // All tests are run with three different proxy types: HTTP, HTTPS (non-SPDY)
 // and SPDY.
-INSTANTIATE_TEST_CASE_P(HttpProxyType,
-                        HttpProxyConnectJobTest,
-                        ::testing::Values(HTTP, HTTPS, SPDY));
+INSTANTIATE_TEST_SUITE_P(HttpProxyType,
+                         HttpProxyConnectJobTest,
+                         ::testing::Values(HTTP, HTTPS, SPDY));
 
 TEST_P(HttpProxyConnectJobTest, NoTunnel) {
   InitProxyDelegate();
@@ -909,4 +909,4 @@
 // TODO(https://crbug.com/927096): It would be nice to also test the timeouts in
 // HttpProxyClientSocketPool.
 
-}  // namespace net
\ No newline at end of file
+}  // namespace net
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc
index f12ef851..f2cd10e 100644
--- a/net/quic/quic_chromium_client_session_test.cc
+++ b/net/quic/quic_chromium_client_session_test.cc
@@ -758,7 +758,7 @@
 
 TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeHandshakeConfirmed) {
   // Force the connection close packet to use long headers with connection ID.
-  server_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
+  server_maker_.SetEncryptionLevel(quic::ENCRYPTION_NONE);
 
   MockQuicData quic_data;
   quic_data.AddRead(ASYNC, ERR_IO_PENDING);
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h
index f3eba05..4c3a40c 100644
--- a/net/quic/quic_flags_list.h
+++ b/net/quic/quic_flags_list.h
@@ -345,3 +345,9 @@
     bool,
     FLAGS_quic_reloadable_flag_quic_simplify_build_connectivity_probing_packet,
     false)
+
+// If true, for QUIC v44+, long header packet type is determined by encryption
+// level.
+QUIC_FLAG(bool,
+          FLAGS_quic_reloadable_flag_quic_encryption_driven_header_type,
+          true)
diff --git a/net/quic/quic_test_packet_maker.cc b/net/quic/quic_test_packet_maker.cc
index a402151..89a85d0e 100644
--- a/net/quic/quic_test_packet_maker.cc
+++ b/net/quic/quic_test_packet_maker.cc
@@ -41,7 +41,10 @@
       spdy_response_framer_(spdy::SpdyFramer::ENABLE_COMPRESSION),
       perspective_(perspective),
       encryption_level_(quic::ENCRYPTION_FORWARD_SECURE),
-      long_header_type_(quic::HANDSHAKE),
+      long_header_type_(
+          FLAGS_quic_reloadable_flag_quic_encryption_driven_header_type
+              ? quic::INVALID_PACKET_TYPE
+              : quic::HANDSHAKE),
       client_headers_include_h2_stream_dependency_(
           client_headers_include_h2_stream_dependency &&
           version >= quic::QUIC_VERSION_43) {
@@ -122,7 +125,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeDummyCHLOPacket(uint64_t packet_num) {
-  encryption_level_ = quic::ENCRYPTION_NONE;
+  SetEncryptionLevel(quic::ENCRYPTION_NONE);
   SetLongHeaderType(quic::INITIAL);
   InitializeHeader(packet_num, /*include_version=*/true);
 
@@ -1289,9 +1292,30 @@
 
 void QuicTestPacketMaker::SetEncryptionLevel(quic::EncryptionLevel level) {
   encryption_level_ = level;
+  if (FLAGS_quic_reloadable_flag_quic_encryption_driven_header_type) {
+    switch (level) {
+      case quic::ENCRYPTION_NONE:
+        long_header_type_ = quic::INITIAL;
+        break;
+      case quic::ENCRYPTION_INITIAL:
+        long_header_type_ = quic::ZERO_RTT_PROTECTED;
+        break;
+      case quic::ENCRYPTION_FORWARD_SECURE:
+        long_header_type_ = quic::INVALID_PACKET_TYPE;
+        break;
+      default:
+        QUIC_BUG << quic::QuicUtils::EncryptionLevelToString(level);
+        long_header_type_ = quic::INVALID_PACKET_TYPE;
+    }
+  }
 }
 
 void QuicTestPacketMaker::SetLongHeaderType(quic::QuicLongHeaderType type) {
+  if (FLAGS_quic_reloadable_flag_quic_encryption_driven_header_type) {
+    // TODO(fayang): Remove SetLongHeaderType when deprecating
+    // FLAGS_quic_reloadable_flag_quic_encryption_driven_header_type.
+    return;
+  }
   long_header_type_ = type;
 }
 
diff --git a/net/socket/websocket_endpoint_lock_manager.cc b/net/socket/websocket_endpoint_lock_manager.cc
index 5071479d..9acdaa8 100644
--- a/net/socket/websocket_endpoint_lock_manager.cc
+++ b/net/socket/websocket_endpoint_lock_manager.cc
@@ -31,6 +31,20 @@
   }
 }
 
+WebSocketEndpointLockManager::LockReleaser::LockReleaser(
+    WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
+    IPEndPoint endpoint)
+    : websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager),
+      endpoint_(endpoint) {
+  websocket_endpoint_lock_manager->RegisterLockReleaser(this, endpoint);
+}
+
+WebSocketEndpointLockManager::LockReleaser::~LockReleaser() {
+  if (websocket_endpoint_lock_manager_) {
+    websocket_endpoint_lock_manager_->UnlockEndpoint(endpoint_);
+  }
+}
+
 WebSocketEndpointLockManager::WebSocketEndpointLockManager()
     : unlock_delay_(base::TimeDelta::FromMilliseconds(kUnlockDelayInMs)),
       pending_unlock_count_(0),
@@ -38,7 +52,6 @@
 
 WebSocketEndpointLockManager::~WebSocketEndpointLockManager() {
   DCHECK_EQ(lock_info_map_.size(), pending_unlock_count_);
-  DCHECK(socket_lock_info_map_.empty());
 }
 
 int WebSocketEndpointLockManager::LockEndpoint(const IPEndPoint& endpoint,
@@ -57,48 +70,20 @@
   return ERR_IO_PENDING;
 }
 
-void WebSocketEndpointLockManager::RememberSocket(StreamSocket* socket,
-                                                  const IPEndPoint& endpoint) {
-  auto lock_info_it = lock_info_map_.find(endpoint);
-  CHECK(lock_info_it != lock_info_map_.end());
-  bool inserted =
-      socket_lock_info_map_.insert(SocketLockInfoMap::value_type(
-                                       socket, lock_info_it)).second;
-  DCHECK(inserted);
-  DCHECK(!lock_info_it->second.socket);
-  lock_info_it->second.socket = socket;
-  DVLOG(3) << "Remembered (StreamSocket*)" << socket << " for "
-           << endpoint.ToString() << " (" << socket_lock_info_map_.size()
-           << " socket(s) remembered)";
-}
-
-void WebSocketEndpointLockManager::UnlockSocket(StreamSocket* socket) {
-  auto socket_it = socket_lock_info_map_.find(socket);
-  if (socket_it == socket_lock_info_map_.end())
-    return;
-
-  auto lock_info_it = socket_it->second;
-
-  DVLOG(3) << "Unlocking (StreamSocket*)" << socket << " for "
-           << lock_info_it->first.ToString() << " ("
-           << socket_lock_info_map_.size() << " socket(s) left)";
-  socket_lock_info_map_.erase(socket_it);
-  DCHECK_EQ(socket, lock_info_it->second.socket);
-  lock_info_it->second.socket = nullptr;
-  UnlockEndpointAfterDelay(lock_info_it->first);
-}
-
 void WebSocketEndpointLockManager::UnlockEndpoint(const IPEndPoint& endpoint) {
   auto lock_info_it = lock_info_map_.find(endpoint);
   if (lock_info_it == lock_info_map_.end())
     return;
-  if (lock_info_it->second.socket)
-    EraseSocket(lock_info_it);
+  LockReleaser* lock_releaser = lock_info_it->second.lock_releaser;
+  if (lock_releaser) {
+    lock_info_it->second.lock_releaser = nullptr;
+    lock_releaser->websocket_endpoint_lock_manager_ = nullptr;
+  }
   UnlockEndpointAfterDelay(endpoint);
 }
 
 bool WebSocketEndpointLockManager::IsEmpty() const {
-  return lock_info_map_.empty() && socket_lock_info_map_.empty();
+  return lock_info_map_.empty();
 }
 
 base::TimeDelta WebSocketEndpointLockManager::SetUnlockDelayForTesting(
@@ -108,16 +93,28 @@
   return old_delay;
 }
 
-WebSocketEndpointLockManager::LockInfo::LockInfo() : socket(nullptr) {}
+WebSocketEndpointLockManager::LockInfo::LockInfo() : lock_releaser(nullptr) {}
 WebSocketEndpointLockManager::LockInfo::~LockInfo() {
-  DCHECK(!socket);
+  DCHECK(!lock_releaser);
 }
 
 WebSocketEndpointLockManager::LockInfo::LockInfo(const LockInfo& rhs)
-    : socket(rhs.socket) {
+    : lock_releaser(rhs.lock_releaser) {
   DCHECK(!rhs.queue);
 }
 
+void WebSocketEndpointLockManager::RegisterLockReleaser(
+    LockReleaser* lock_releaser,
+    IPEndPoint endpoint) {
+  DCHECK(lock_releaser);
+  auto lock_info_it = lock_info_map_.find(endpoint);
+  CHECK(lock_info_it != lock_info_map_.end());
+  DCHECK(!lock_info_it->second.lock_releaser);
+  lock_info_it->second.lock_releaser = lock_releaser;
+  DVLOG(3) << "Registered (LockReleaser*)" << lock_releaser << " for "
+           << endpoint.ToString();
+}
+
 void WebSocketEndpointLockManager::UnlockEndpointAfterDelay(
     const IPEndPoint& endpoint) {
   DVLOG(3) << "Delaying " << unlock_delay_.InMilliseconds()
@@ -137,7 +134,7 @@
   --pending_unlock_count_;
   if (lock_info_it == lock_info_map_.end())
     return;
-  DCHECK(!lock_info_it->second.socket);
+  DCHECK(!lock_info_it->second.lock_releaser);
   LockInfo::WaiterQueue* queue = lock_info_it->second.queue.get();
   DCHECK(queue);
   if (queue->empty()) {
@@ -153,14 +150,4 @@
   next_job->GotEndpointLock();
 }
 
-void WebSocketEndpointLockManager::EraseSocket(
-    LockInfoMap::iterator lock_info_it) {
-  DVLOG(3) << "Removing (StreamSocket*)" << lock_info_it->second.socket
-           << " for " << lock_info_it->first.ToString() << " ("
-           << socket_lock_info_map_.size() << " socket(s) left)";
-  size_t erased = socket_lock_info_map_.erase(lock_info_it->second.socket);
-  DCHECK_EQ(1U, erased);
-  lock_info_it->second.socket = nullptr;
-}
-
 }  // namespace net
diff --git a/net/socket/websocket_endpoint_lock_manager.h b/net/socket/websocket_endpoint_lock_manager.h
index 02a848dc..2d7cdf5 100644
--- a/net/socket/websocket_endpoint_lock_manager.h
+++ b/net/socket/websocket_endpoint_lock_manager.h
@@ -20,8 +20,6 @@
 
 namespace net {
 
-class StreamSocket;
-
 // Keep track of ongoing WebSocket connections in order to satisfy the WebSocket
 // connection throttling requirements described in RFC6455 4.1.2:
 //
@@ -46,6 +44,26 @@
     virtual void GotEndpointLock() = 0;
   };
 
+  // LockReleaser calls UnlockEndpoint() when it is destroyed, but only if it
+  // has not already been called. Only one LockReleaser object may exist for
+  // each endpoint at a time.
+  class NET_EXPORT_PRIVATE LockReleaser final {
+   public:
+    LockReleaser(WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
+                 IPEndPoint endpoint);
+    ~LockReleaser();
+
+   private:
+    friend class WebSocketEndpointLockManager;
+
+    // This is null if UnlockEndpoint() has been called before this object was
+    // destroyed.
+    WebSocketEndpointLockManager* websocket_endpoint_lock_manager_;
+    const IPEndPoint endpoint_;
+
+    DISALLOW_COPY_AND_ASSIGN(LockReleaser);
+  };
+
   WebSocketEndpointLockManager();
   ~WebSocketEndpointLockManager();
 
@@ -55,30 +73,12 @@
   // its destructor is called.
   int LockEndpoint(const IPEndPoint& endpoint, Waiter* waiter);
 
-  // Records the IPEndPoint associated with a particular socket. This is
-  // necessary because TCPClientSocket refuses to return the PeerAddress after
-  // the connection is disconnected. The association will be forgotten when
-  // UnlockSocket() or UnlockEndpoint() is called. The |socket| pointer must not
-  // be deleted between the call to RememberSocket() and the call to
-  // UnlockSocket().
-  void RememberSocket(StreamSocket* socket, const IPEndPoint& endpoint);
-
-  // Removes the socket association that was recorded by RememberSocket(), then
-  // asynchronously releases the lock on the endpoint after a delay. If
-  // appropriate, calls |waiter->GetEndpointLock()| when the lock is
-  // released. Should be called exactly once for each |socket| that was passed
-  // to RememberSocket(). Does nothing if UnlockEndpoint() has been called since
-  // the call to RememberSocket().
-  void UnlockSocket(StreamSocket* socket);
-
   // Asynchronously releases the lock on |endpoint| after a delay. Does nothing
-  // if |endpoint| is not locked.  Removes any socket association that was
-  // recorded with RememberSocket(). If appropriate, calls
-  // |waiter->GotEndpointLock()| when the lock is released.
+  // if |endpoint| is not locked. If a LockReleaser object has been created for
+  // this endpoint, it will be unregistered.
   void UnlockEndpoint(const IPEndPoint& endpoint);
 
-  // Checks that |lock_info_map_| and |socket_lock_info_map_| are empty. For
-  // tests.
+  // Checks that |lock_info_map_| is empty. For tests.
   bool IsEmpty() const;
 
   // Changes the value of the unlock delay. Returns the previous value of the
@@ -104,35 +104,26 @@
     // until this object is deleted.
     std::unique_ptr<WaiterQueue> queue;
 
-    // This pointer is only used to identify the last instance of StreamSocket
-    // that was passed to RememberSocket() for this endpoint. It should only be
-    // compared with other pointers. It is never dereferenced and not owned. It
-    // is non-NULL if RememberSocket() has been called for this endpoint since
-    // the last call to UnlockSocket() or UnlockEndpoint().
-    StreamSocket* socket;
+    // This pointer is non-NULL if a LockReleaser object has been constructed
+    // since the last call to UnlockEndpoint().
+    LockReleaser* lock_releaser;
   };
 
   // SocketLockInfoMap requires std::map iterator semantics for LockInfoMap
   // (ie. that the iterator will remain valid as long as the entry is not
   // deleted).
   typedef std::map<IPEndPoint, LockInfo> LockInfoMap;
-  typedef std::map<StreamSocket*, LockInfoMap::iterator> SocketLockInfoMap;
 
+  // Records the association of a LockReleaser with a particular endpoint.
+  void RegisterLockReleaser(LockReleaser* lock_releaser, IPEndPoint endpoint);
   void UnlockEndpointAfterDelay(const IPEndPoint& endpoint);
   void DelayedUnlockEndpoint(const IPEndPoint& endpoint);
-  void EraseSocket(LockInfoMap::iterator lock_info_it);
 
   // If an entry is present in the map for a particular endpoint, then that
   // endpoint is locked. If LockInfo.queue is non-empty, then one or more
   // Waiters are waiting for the lock.
   LockInfoMap lock_info_map_;
 
-  // Store sockets remembered by RememberSocket() and not yet unlocked by
-  // UnlockSocket() or UnlockEndpoint(). Every entry in this map always
-  // references a live entry in lock_info_map_, and the LockInfo::socket member
-  // is non-NULL if and only if there is an entry in this map for the socket.
-  SocketLockInfoMap socket_lock_info_map_;
-
   // Time to wait between a call to Unlock* and actually unlocking the socket.
   base::TimeDelta unlock_delay_;
 
diff --git a/net/socket/websocket_endpoint_lock_manager_unittest.cc b/net/socket/websocket_endpoint_lock_manager_unittest.cc
index 44e6e920..c55e63d 100644
--- a/net/socket/websocket_endpoint_lock_manager_unittest.cc
+++ b/net/socket/websocket_endpoint_lock_manager_unittest.cc
@@ -13,7 +13,6 @@
 #include "net/log/net_log_with_source.h"
 #include "net/socket/next_proto.h"
 #include "net/socket/socket_test_util.h"
-#include "net/socket/stream_socket.h"
 #include "net/test/gtest_util.h"
 #include "net/test/test_with_scoped_task_environment.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
@@ -26,75 +25,6 @@
 
 namespace {
 
-// A StreamSocket implementation with no functionality at all.
-// TODO(ricea): If you need to use this in another file, please move it to
-// socket_test_util.h.
-class FakeStreamSocket : public StreamSocket {
- public:
-  FakeStreamSocket() = default;
-
-  // StreamSocket implementation
-  int Connect(CompletionOnceCallback callback) override { return ERR_FAILED; }
-
-  void Disconnect() override { return; }
-
-  bool IsConnected() const override { return false; }
-
-  bool IsConnectedAndIdle() const override { return false; }
-
-  int GetPeerAddress(IPEndPoint* address) const override { return ERR_FAILED; }
-
-  int GetLocalAddress(IPEndPoint* address) const override { return ERR_FAILED; }
-
-  const NetLogWithSource& NetLog() const override { return net_log_; }
-
-  bool WasEverUsed() const override { return false; }
-
-  bool WasAlpnNegotiated() const override { return false; }
-
-  NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
-
-  bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
-
-  void GetConnectionAttempts(ConnectionAttempts* out) const override {
-    out->clear();
-  }
-
-  void ClearConnectionAttempts() override {}
-
-  void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
-
-  int64_t GetTotalReceivedBytes() const override {
-    NOTIMPLEMENTED();
-    return 0;
-  }
-
-  void ApplySocketTag(const SocketTag& tag) override {}
-
-  // Socket implementation
-  int Read(IOBuffer* buf,
-           int buf_len,
-           CompletionOnceCallback callback) override {
-    return ERR_FAILED;
-  }
-
-  int Write(IOBuffer* buf,
-            int buf_len,
-            CompletionOnceCallback callback,
-            const NetworkTrafficAnnotationTag& traffic_annotation) override {
-    return ERR_FAILED;
-  }
-
-  int SetReceiveBufferSize(int32_t size) override { return ERR_FAILED; }
-
-  int SetSendBufferSize(int32_t size) override { return ERR_FAILED; }
-
- private:
-  NetLogWithSource net_log_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeStreamSocket);
-};
-
 class FakeWaiter : public WebSocketEndpointLockManager::Waiter {
  public:
   FakeWaiter() : called_(false) {}
@@ -230,67 +160,64 @@
   UnlockDummyEndpoint(1);
 }
 
-TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) {
+TEST_F(WebSocketEndpointLockManagerTest, LockReleaserWorks) {
   FakeWaiter waiters[2];
-  FakeStreamSocket dummy_socket;
   EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
                                                             &waiters[0]),
               IsOk());
   EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
                                 DummyEndpoint(), &waiters[1]));
 
-  websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
-                                                  DummyEndpoint());
-  websocket_endpoint_lock_manager_.UnlockSocket(&dummy_socket);
+  {
+    WebSocketEndpointLockManager::LockReleaser releaser(
+        &websocket_endpoint_lock_manager_, DummyEndpoint());
+  }
   RunUntilIdle();
   EXPECT_TRUE(waiters[1].called());
 
   UnlockDummyEndpoint(1);
 }
 
-// UnlockEndpoint() should cause any sockets remembered for this endpoint
-// to be forgotten.
-TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) {
+// UnlockEndpoint() should cause any LockReleasers for this endpoint to be
+// unregistered.
+TEST_F(WebSocketEndpointLockManagerTest, LockReleaserForgottenOnUnlock) {
   FakeWaiter waiter;
-  FakeStreamSocket dummy_socket;
 
   EXPECT_THAT(
       websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(), &waiter),
       IsOk());
-  websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
-                                                  DummyEndpoint());
+  WebSocketEndpointLockManager::LockReleaser releaser(
+      &websocket_endpoint_lock_manager_, DummyEndpoint());
   websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
   RunUntilIdle();
   EXPECT_TRUE(websocket_endpoint_lock_manager_.IsEmpty());
 }
 
 // When ownership of the endpoint is passed to a new waiter, the new waiter can
-// call RememberSocket() again.
-TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) {
+// construct another LockReleaser.
+TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCreateLockReleaserAgain) {
   FakeWaiter waiters[2];
-  FakeStreamSocket dummy_sockets[2];
   EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
                                                             &waiters[0]),
               IsOk());
   EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
                                 DummyEndpoint(), &waiters[1]));
 
-  websocket_endpoint_lock_manager_.RememberSocket(&dummy_sockets[0],
-                                                  DummyEndpoint());
+  WebSocketEndpointLockManager::LockReleaser releaser1(
+      &websocket_endpoint_lock_manager_, DummyEndpoint());
   websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
   RunUntilIdle();
   EXPECT_TRUE(waiters[1].called());
-  websocket_endpoint_lock_manager_.RememberSocket(&dummy_sockets[1],
-                                                  DummyEndpoint());
+  WebSocketEndpointLockManager::LockReleaser releaser2(
+      &websocket_endpoint_lock_manager_, DummyEndpoint());
 
   UnlockDummyEndpoint(1);
 }
 
-// Calling UnlockSocket() after UnlockEndpoint() does nothing.
+// Destroying LockReleaser after UnlockEndpoint() does nothing.
 TEST_F(WebSocketEndpointLockManagerTest,
-       UnlockSocketAfterUnlockEndpointDoesNothing) {
+       DestroyLockReleaserAfterUnlockEndpointDoesNothing) {
   FakeWaiter waiters[3];
-  FakeStreamSocket dummy_socket;
 
   EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
                                                             &waiters[0]),
@@ -299,10 +226,11 @@
                                 DummyEndpoint(), &waiters[1]));
   EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
                                 DummyEndpoint(), &waiters[2]));
-  websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
-                                                  DummyEndpoint());
-  websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
-  websocket_endpoint_lock_manager_.UnlockSocket(&dummy_socket);
+  {
+    WebSocketEndpointLockManager::LockReleaser releaser(
+        &websocket_endpoint_lock_manager_, DummyEndpoint());
+    websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
+  }
   RunUntilIdle();
   EXPECT_TRUE(waiters[1].called());
   EXPECT_FALSE(waiters[2].called());
diff --git a/net/socket/websocket_transport_connect_sub_job.cc b/net/socket/websocket_transport_connect_sub_job.cc
index 68ce99fc..f30e77e 100644
--- a/net/socket/websocket_transport_connect_sub_job.cc
+++ b/net/socket/websocket_transport_connect_sub_job.cc
@@ -18,21 +18,16 @@
 
 // StreamSocket wrapper that registers/unregisters the wrapped StreamSocket with
 // a WebSocketEndpointLockManager on creation/destruction.
-class WebSocketStreamSocket : public StreamSocket {
+class WebSocketStreamSocket final : public StreamSocket {
  public:
   WebSocketStreamSocket(
       std::unique_ptr<StreamSocket> wrapped_socket,
       WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
       const IPEndPoint& address)
       : wrapped_socket_(std::move(wrapped_socket)),
-        websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager) {
-    websocket_endpoint_lock_manager->RememberSocket(wrapped_socket_.get(),
-                                                    address);
-  }
+        lock_releaser_(websocket_endpoint_lock_manager, address) {}
 
-  ~WebSocketStreamSocket() override {
-    websocket_endpoint_lock_manager_->UnlockSocket(wrapped_socket_.get());
-  }
+  ~WebSocketStreamSocket() override = default;
 
   // Socket implementation:
   int Read(IOBuffer* buf,
@@ -111,7 +106,8 @@
 
  private:
   std::unique_ptr<StreamSocket> wrapped_socket_;
-  WebSocketEndpointLockManager* const websocket_endpoint_lock_manager_;
+  WebSocketEndpointLockManager::LockReleaser lock_releaser_;
+
   DISALLOW_COPY_AND_ASSIGN(WebSocketStreamSocket);
 };
 
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 2878cf28f..235c85a 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -178,7 +178,8 @@
   kAcceptedMatchingVary = 18,
   kPushDisabled = 19,
   kAlreadyInCache = 20,
-  kMaxValue = kAlreadyInCache
+  kUnsupportedStatusCode = 21,
+  kMaxValue = kUnsupportedStatusCode
 };
 
 // If these compile asserts fail then SpdyProtocolErrorDetails needs
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 2540044d2..0d8767d 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -950,6 +950,71 @@
   histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
 }
 
+// Regression test for https://crbug.com/903737: pushed response with status
+// code different from 2xx or 3xx or 416 should be rejected.
+TEST_F(SpdySessionTest, UnsupportedPushedStatusCode) {
+  base::HistogramTester histogram_tester;
+
+  spdy::SpdyHeaderBlock push_promise_header_block;
+  push_promise_header_block[spdy::kHttp2MethodHeader] = "GET";
+  spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_promise_header_block);
+  spdy::SpdySerializedFrame push_promise_frame(
+      spdy_util_.ConstructSpdyPushPromise(
+          1, 2, std::move(push_promise_header_block)));
+
+  spdy::SpdyHeaderBlock response_header_block;
+  response_header_block[spdy::kHttp2StatusHeader] = "401";
+  spdy::SpdySerializedFrame response_headers_frame(
+      spdy_util_.ConstructSpdyResponseHeaders(
+          2, std::move(response_header_block), false));
+
+  MockRead reads[] = {
+      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(push_promise_frame, 2),
+      CreateMockRead(response_headers_frame, 4), MockRead(ASYNC, 0, 6)};
+
+  spdy::SpdySerializedFrame req(
+      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
+  spdy::SpdySerializedFrame priority(
+      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
+  spdy::SpdySerializedFrame rst(
+      spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
+
+  MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
+                        CreateMockWrite(rst, 5)};
+
+  SequencedSocketData data(reads, writes);
+  session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+  AddSSLSocketData();
+
+  CreateNetworkSession();
+  CreateSpdySession();
+
+  base::WeakPtr<SpdyStream> spdy_stream =
+      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
+                                test_url_, MEDIUM, NetLogWithSource());
+  test::StreamDelegateDoNothing delegate(spdy_stream);
+  spdy_stream->SetDelegate(&delegate);
+
+  spdy::SpdyHeaderBlock headers(
+      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
+  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(1u, spdy_stream->stream_id());
+  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));
+
+  // Read the PUSH_PROMISE and HEADERS frames.
+  data.Resume();
+  base::RunLoop().RunUntilIdle();
+
+  histogram_tester.ExpectBucketCount(
+      "Net.SpdyPushedStreamFate",
+      static_cast<int>(SpdyPushedStreamFate::kUnsupportedStatusCode), 1);
+  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
+}
+
 // A session observing a network change with active streams should close
 // when the last active stream is closed.
 TEST_F(SpdySessionTest, NetworkChangeWithActiveStreams) {
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc
index 441f89f..e47e582 100644
--- a/net/spdy/spdy_stream.cc
+++ b/net/spdy/spdy_stream.cc
@@ -383,44 +383,42 @@
     base::Time response_time,
     base::TimeTicks recv_first_byte_time) {
   switch (response_state_) {
-    case READY_FOR_HEADERS:
+    case READY_FOR_HEADERS: {
       // No header block has been received yet.
       DCHECK(response_headers_.empty());
 
-      {
-        spdy::SpdyHeaderBlock::const_iterator it =
-            response_headers.find(spdy::kHttp2StatusHeader);
-        if (it == response_headers.end()) {
-          const std::string error("Response headers do not include :status.");
-          LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
-          session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR, error);
-          return;
-        }
+      spdy::SpdyHeaderBlock::const_iterator it =
+          response_headers.find(spdy::kHttp2StatusHeader);
+      if (it == response_headers.end()) {
+        const std::string error("Response headers do not include :status.");
+        LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
+        session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR, error);
+        return;
+      }
 
-        int status;
-        if (!StringToInt(it->second, &status)) {
-          const std::string error("Cannot parse :status.");
-          LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
-          session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR, error);
-          return;
-        }
+      int status;
+      if (!StringToInt(it->second, &status)) {
+        const std::string error("Cannot parse :status.");
+        LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
+        session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR, error);
+        return;
+      }
 
-        base::UmaHistogramSparse("Net.SpdyResponseCode", status);
+      base::UmaHistogramSparse("Net.SpdyResponseCode", status);
 
-        // Include 1XX responses in the TTFB as per the resource timing spec
-        // for responseStart.
-        if (recv_first_byte_time_.is_null())
-          recv_first_byte_time_ = recv_first_byte_time;
+      // Include 1XX responses in the TTFB as per the resource timing spec
+      // for responseStart.
+      if (recv_first_byte_time_.is_null())
+        recv_first_byte_time_ = recv_first_byte_time;
 
-        // Ignore informational headers like 103 Early Hints.
-        // TODO(bnc): Add support for 103 Early Hints, https://crbug.com/671310.
-        // However, do not ignore 101 Switching Protocols, because broken
-        // servers might send this as a response to a WebSocket request,
-        // in which case it needs to pass through so that the WebSocket layer
-        // can signal an error.
-        if (status / 100 == 1 && status != 101) {
-          return;
-        }
+      // Ignore informational headers like 103 Early Hints.
+      // TODO(bnc): Add support for 103 Early Hints, https://crbug.com/671310.
+      // However, do not ignore 101 Switching Protocols, because broken
+      // servers might send this as a response to a WebSocket request,
+      // in which case it needs to pass through so that the WebSocket layer
+      // can signal an error.
+      if (status / 100 == 1 && status != 101) {
+        return;
       }
 
       response_state_ = READY_FOR_DATA_OR_TRAILERS;
@@ -454,10 +452,10 @@
       DCHECK_NE(io_state_, STATE_IDLE);
 
       response_time_ = response_time;
-      SaveResponseHeaders(response_headers);
+      SaveResponseHeaders(response_headers, status);
 
       break;
-
+    }
     case READY_FOR_DATA_OR_TRAILERS:
       // Second header block is trailers.
       if (type_ == SPDY_PUSH_STREAM) {
@@ -914,7 +912,8 @@
 }
 
 void SpdyStream::SaveResponseHeaders(
-    const spdy::SpdyHeaderBlock& response_headers) {
+    const spdy::SpdyHeaderBlock& response_headers,
+    int status) {
   DCHECK(response_headers_.empty());
   if (response_headers.find("transfer-encoding") != response_headers.end()) {
     session_->ResetStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR,
@@ -927,6 +926,17 @@
     response_headers_.insert(*it);
   }
 
+  // Reject pushed stream with unsupported status code regardless of whether
+  // delegate is already attached or not.
+  if (type_ == SPDY_PUSH_STREAM &&
+      (status / 100 != 2 && status / 100 != 3 && status != 416)) {
+    SpdySession::RecordSpdyPushedStreamFateHistogram(
+        SpdyPushedStreamFate::kUnsupportedStatusCode);
+    session_->ResetStream(stream_id_, ERR_SPDY_CLIENT_REFUSED_STREAM,
+                          "Unsupported status code for pushed stream.");
+    return;
+  }
+
   // If delegate is not yet attached, OnHeadersReceived() will be called after
   // the delegate gets attached to the stream.
   if (!delegate_)
diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h
index 35fdf444..0080022 100644
--- a/net/spdy/spdy_stream.h
+++ b/net/spdy/spdy_stream.h
@@ -451,7 +451,8 @@
 
   // Saves the given headers into |response_headers_| and calls
   // OnHeadersReceived() on the delegate if attached.
-  void SaveResponseHeaders(const spdy::SpdyHeaderBlock& response_headers);
+  void SaveResponseHeaders(const spdy::SpdyHeaderBlock& response_headers,
+                           int status);
 
   static std::string DescribeState(State state);
 
diff --git a/net/third_party/quic/core/quic_control_frame_manager.cc b/net/third_party/quic/core/quic_control_frame_manager.cc
index 1d267a9..1218f1a 100644
--- a/net/third_party/quic/core/quic_control_frame_manager.cc
+++ b/net/third_party/quic/core/quic_control_frame_manager.cc
@@ -88,25 +88,6 @@
       QuicFrame(QuicMaxStreamIdFrame(++last_control_frame_id_, id)));
 }
 
-void QuicControlFrameManager::WriteOrBufferRstStreamStopSending(
-    QuicStreamId stream_id,
-    QuicRstStreamErrorCode error_code,
-    QuicStreamOffset bytes_written) {
-  const bool had_buffered_frames = HasBufferedFrames();
-  QUIC_DVLOG(1) << "Queuing RST_STREAM_FRAME";
-  control_frames_.emplace_back(QuicFrame(new QuicRstStreamFrame(
-      ++last_control_frame_id_, stream_id, error_code, bytes_written)));
-  if (session_->connection()->transport_version() == QUIC_VERSION_99) {
-    QUIC_DVLOG(1) << "Version 99, Queuing STOP_SENDING";
-    control_frames_.emplace_back(QuicFrame(new QuicStopSendingFrame(
-        ++last_control_frame_id_, stream_id, error_code)));
-  }
-  if (had_buffered_frames) {
-    return;
-  }
-  WriteBufferedFrames();
-}
-
 void QuicControlFrameManager::WritePing() {
   QUIC_DVLOG(1) << "Writing PING_FRAME";
   if (HasBufferedFrames()) {
diff --git a/net/third_party/quic/core/quic_control_frame_manager.h b/net/third_party/quic/core/quic_control_frame_manager.h
index d8671946..719aba8 100644
--- a/net/third_party/quic/core/quic_control_frame_manager.h
+++ b/net/third_party/quic/core/quic_control_frame_manager.h
@@ -61,13 +61,6 @@
   // immediately.
   void WriteOrBufferMaxStreamId(QuicStreamId id);
 
-  // Tries to send a packet with both a RST_STREAM and, if version 99, an
-  // IETF-QUIC STOP_SENDING frame. The frames are buffered if they can not
-  // be sent immediately.
-  void WriteOrBufferRstStreamStopSending(QuicControlFrameId stream_id,
-                                         QuicRstStreamErrorCode error_code,
-                                         QuicStreamOffset bytes_written);
-
   // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
   // can not be sent immediately.
   void WriteOrBufferStopSending(uint16_t code, QuicStreamId stream_id);
diff --git a/net/third_party/quic/core/quic_framer.cc b/net/third_party/quic/core/quic_framer.cc
index b0c3ada..0fe7f3c 100644
--- a/net/third_party/quic/core/quic_framer.cc
+++ b/net/third_party/quic/core/quic_framer.cc
@@ -1574,7 +1574,8 @@
   // using QUIC crypto.
   if (header->form == IETF_QUIC_LONG_HEADER_PACKET &&
       header->long_packet_type == ZERO_RTT_PROTECTED &&
-      perspective_ == Perspective::IS_CLIENT) {
+      perspective_ == Perspective::IS_CLIENT &&
+      version_.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
     if (!encrypted_reader->ReadBytes(
             reinterpret_cast<uint8_t*>(last_nonce_.data()),
             last_nonce_.size())) {
diff --git a/net/third_party/quic/core/quic_framer_test.cc b/net/third_party/quic/core/quic_framer_test.cc
index 71e5a44..c7dd6af 100644
--- a/net/third_party/quic/core/quic_framer_test.cc
+++ b/net/third_party/quic/core/quic_framer_test.cc
@@ -1450,6 +1450,10 @@
   };
   // clang-format on
 
+  if (framer_.version().handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
+    return;
+  }
+
   unsigned char* p = packet;
   size_t p_size = QUIC_ARRAYSIZE(packet);
   if (framer_.transport_version() > QUIC_VERSION_45) {
diff --git a/net/third_party/quic/core/quic_packet_creator.cc b/net/third_party/quic/core/quic_packet_creator.cc
index 7ade0a8a..e1536c4 100644
--- a/net/third_party/quic/core/quic_packet_creator.cc
+++ b/net/third_party/quic/core/quic_packet_creator.cc
@@ -26,6 +26,26 @@
 bool FLAGS_quic_enforce_single_packet_chlo = true;
 
 namespace quic {
+namespace {
+
+QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
+  switch (level) {
+    case ENCRYPTION_NONE:
+      return INITIAL;
+    case ENCRYPTION_INITIAL:
+      return ZERO_RTT_PROTECTED;
+    case ENCRYPTION_FORWARD_SECURE:
+      QUIC_BUG
+          << "Try to derive long header type for packet with encryption level: "
+          << QuicUtils::EncryptionLevelToString(level);
+      return INVALID_PACKET_TYPE;
+    default:
+      QUIC_BUG << QuicUtils::EncryptionLevelToString(level);
+      return INVALID_PACKET_TYPE;
+  }
+}
+
+}  // namespace
 
 #define ENDPOINT \
   (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
@@ -63,7 +83,9 @@
       needs_full_padding_(false),
       can_set_transmission_type_(false),
       set_transmission_type_for_next_frame_(
-          GetQuicReloadableFlag(quic_set_transmission_type_for_next_frame)) {
+          GetQuicReloadableFlag(quic_set_transmission_type_for_next_frame)),
+      encryption_level_driven_long_header_type_(
+          GetQuicReloadableFlag(quic_encryption_driven_header_type)) {
   SetMaxPacketLength(kDefaultMaxPacketSize);
 }
 
@@ -717,7 +739,10 @@
   if (!HasIetfLongHeader()) {
     return;
   }
-  header->long_packet_type = long_header_type_;
+  header->long_packet_type =
+      (encryption_level_driven_long_header_type_
+           ? EncryptionlevelToLongHeaderType(packet_.encryption_level)
+           : long_header_type_);
 }
 
 bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
diff --git a/net/third_party/quic/core/quic_packet_creator.h b/net/third_party/quic/core/quic_packet_creator.h
index beaff18..2c379f1 100644
--- a/net/third_party/quic/core/quic_packet_creator.h
+++ b/net/third_party/quic/core/quic_packet_creator.h
@@ -354,6 +354,8 @@
   SerializedPacket packet_;
 
   // Long header type of next constructed packets.
+  // TODO(fayang): remove this variable when deprecating
+  // quic_encryption_driven_header_type.
   QuicLongHeaderType long_header_type_;
 
   // Pending padding bytes to send. Pending padding bytes will be sent in next
@@ -373,6 +375,9 @@
   // Latched value of --quic_set_transmission_type_for_next_frame. Don't use
   // this variable directly, use ShouldSetTransmissionTypeForNextFrame instead.
   bool set_transmission_type_for_next_frame_;
+
+  // Latched value of quic_reloadable_flag_quic_encryption_driven_header_type.
+  const bool encryption_level_driven_long_header_type_;
 };
 
 }  // namespace quic
diff --git a/net/third_party/quic/core/quic_session.cc b/net/third_party/quic/core/quic_session.cc
index f252266..9fd8fa3 100644
--- a/net/third_party/quic/core/quic_session.cc
+++ b/net/third_party/quic/core/quic_session.cc
@@ -583,16 +583,13 @@
       // Send a RST_STREAM frame plus, if version 99, an IETF
       // QUIC STOP_SENDING frame. Both sre sent to emulate
       // the two-way close that Google QUIC's RST_STREAM does.
-      QuicConnection::ScopedPacketFlusher* flusher =
-          (connection_->transport_version() == QUIC_VERSION_99)
-              ? new QuicConnection::ScopedPacketFlusher(
-                    connection(), QuicConnection::SEND_ACK_IF_QUEUED)
-              : nullptr;
-      control_frame_manager_.WriteOrBufferRstStreamStopSending(id, error,
-                                                               bytes_written);
-      if (flusher) {
-        delete flusher;
-        flusher = nullptr;
+      if (connection_->transport_version() == QUIC_VERSION_99) {
+        QuicConnection::ScopedPacketFlusher flusher(
+            connection(), QuicConnection::SEND_ACK_IF_QUEUED);
+        control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
+        control_frame_manager_.WriteOrBufferStopSending(error, id);
+      } else {
+        control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
       }
     }
     connection_->OnStreamReset(id, error);
diff --git a/services/identity/public/cpp/BUILD.gn b/services/identity/public/cpp/BUILD.gn
index 206fe3e..2d4266a 100644
--- a/services/identity/public/cpp/BUILD.gn
+++ b/services/identity/public/cpp/BUILD.gn
@@ -67,6 +67,8 @@
     "identity_test_environment.h",
     "identity_test_utils.cc",
     "identity_test_utils.h",
+    "test_identity_manager_observer.cc",
+    "test_identity_manager_observer.h",
   ]
 
   public_deps = [
diff --git a/services/identity/public/cpp/accounts_mutator_impl.h b/services/identity/public/cpp/accounts_mutator_impl.h
index f93ac01..728f1a18 100644
--- a/services/identity/public/cpp/accounts_mutator_impl.h
+++ b/services/identity/public/cpp/accounts_mutator_impl.h
@@ -25,48 +25,30 @@
                                SigninManagerBase* signin_manager);
   ~AccountsMutatorImpl() override;
 
-  // Updates the information of the account associated with |gaia_id|, first
-  // adding that account to the system if it is not known.
+  // AccountsMutator:
   std::string AddOrUpdateAccount(
       const std::string& gaia_id,
       const std::string& email,
       const std::string& refresh_token,
       bool is_under_advanced_protection,
       signin_metrics::SourceForRefreshTokenOperation source) override;
-
-  // Updates the information about account identified by |account_id|.
   void UpdateAccountInfo(
       const std::string& account_id,
       base::Optional<bool> is_child_account,
       base::Optional<bool> is_under_advanced_protection) override;
-
-  // Removes the account given by |account_id|. Also revokes the token
-  // server-side if needed.
   void RemoveAccount(
       const std::string& account_id,
       signin_metrics::SourceForRefreshTokenOperation source) override;
-
-  // Removes all accounts.
   void RemoveAllAccounts(
       signin_metrics::SourceForRefreshTokenOperation source) override;
-
-  // Invalidates the refresh token of the primary account.
-  // The primary account must necessarily be set by the time this method
-  // is invoked.
   void InvalidateRefreshTokenForPrimaryAccount(
       signin_metrics::SourceForRefreshTokenOperation source) override;
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
-  // Removes the credentials associated to account_id from the internal storage,
-  // and moves them to |target|. The credentials are not revoked on the server,
-  // but the IdentityManager::Observer::OnRefreshTokenRemovedForAccount()
-  // notification is sent to the observers.
   void MoveAccount(AccountsMutator* target,
                    const std::string& account_id) override;
 #endif
 
-  // Updates the refresh token for the supervised user.
-  // TODO(860492): Remove this once supervised user support is removed.
   void LegacySetRefreshTokenForSupervisedUser(
       const std::string& refresh_token) override;
 
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc
index 05e37e3e..ca6caa8 100644
--- a/services/identity/public/cpp/identity_manager_unittest.cc
+++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -32,6 +32,7 @@
 #include "services/identity/public/cpp/identity_manager.h"
 #include "services/identity/public/cpp/identity_test_utils.h"
 #include "services/identity/public/cpp/primary_account_mutator.h"
+#include "services/identity/public/cpp/test_identity_manager_observer.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/network/test/test_cookie_manager.h"
 #include "services/network/test/test_url_loader_factory.h"
@@ -207,228 +208,6 @@
   base::OnceClosure on_refresh_token_revoked_callback_;
 };
 
-class TestIdentityManagerObserver : IdentityManager::Observer {
- public:
-  explicit TestIdentityManagerObserver(IdentityManager* identity_manager)
-      : identity_manager_(identity_manager) {
-    identity_manager_->AddObserver(this);
-  }
-  ~TestIdentityManagerObserver() override {
-    identity_manager_->RemoveObserver(this);
-  }
-
-  void set_on_primary_account_set_callback(base::OnceClosure callback) {
-    on_primary_account_set_callback_ = std::move(callback);
-  }
-  void set_on_primary_account_cleared_callback(base::OnceClosure callback) {
-    on_primary_account_cleared_callback_ = std::move(callback);
-  }
-  void set_on_primary_account_signin_failed_callback(
-      base::OnceClosure callback) {
-    on_primary_account_signin_failed_callback_ = std::move(callback);
-  }
-  void set_on_cookie_deleted_by_user_callback(base::OnceClosure callback) {
-    on_cookie_deleted_by_user_callback_ = std::move(callback);
-  }
-
-  const CoreAccountInfo& primary_account_from_set_callback() {
-    return primary_account_from_set_callback_;
-  }
-  const CoreAccountInfo& primary_account_from_cleared_callback() {
-    return primary_account_from_cleared_callback_;
-  }
-
-  void set_on_refresh_token_updated_callback(base::OnceClosure callback) {
-    on_refresh_token_updated_callback_ = std::move(callback);
-  }
-  // This method uses a RepeatingCallback to simplify verification of multiple
-  // removed tokens.
-  void set_on_refresh_token_removed_callback(
-      base::RepeatingCallback<void(const std::string&)> callback) {
-    on_refresh_token_removed_callback_ = std::move(callback);
-  }
-  void set_on_error_state_of_refresh_token_updated_callback(
-      base::OnceClosure callback) {
-    on_error_state_of_refresh_token_updated_callback_ = std::move(callback);
-  }
-
-  void set_on_refresh_tokens_loaded_callback(base::OnceClosure callback) {
-    on_refresh_tokens_loaded_callback_ = std::move(callback);
-  }
-
-  const CoreAccountInfo& account_from_refresh_token_updated_callback() {
-    return account_from_refresh_token_updated_callback_;
-  }
-  const std::string& account_from_refresh_token_removed_callback() {
-    return account_from_refresh_token_removed_callback_;
-  }
-  const CoreAccountInfo&
-  account_from_error_state_of_refresh_token_updated_callback() {
-    return account_from_error_state_of_refresh_token_updated_callback_;
-  }
-  const GoogleServiceAuthError&
-  error_from_error_state_of_refresh_token_updated_callback() const {
-    return error_from_error_state_of_refresh_token_updated_callback_;
-  }
-
-  void set_on_accounts_in_cookie_updated_callback(base::OnceClosure callback) {
-    on_accounts_in_cookie_updated_callback_ = std::move(callback);
-  }
-
-  const AccountsInCookieJarInfo& accounts_info_from_cookie_change_callback() {
-    return accounts_info_from_cookie_change_callback_;
-  }
-
-  const std::string& account_from_add_account_to_cookie_completed_callback()
-      const {
-    return account_from_add_account_to_cookie_completed_callback_;
-  }
-
-  const GoogleServiceAuthError&
-  error_from_add_account_to_cookie_completed_callback() const {
-    return error_from_add_account_to_cookie_completed_callback_;
-  }
-
-  const GoogleServiceAuthError& error_from_signin_failed_callback() const {
-    return google_signin_failed_error_;
-  }
-
-  // Each element represents all the changes from an individual batch that has
-  // occurred, with the elements ordered from oldest to newest batch occurrence.
-  const std::vector<std::vector<std::string>>& batch_change_records() const {
-    return batch_change_records_;
-  }
-
-  const AccountInfo& account_from_account_updated_callback() {
-    return account_from_account_updated_callback_;
-  }
-
-  const AccountInfo& account_from_account_removed_with_info_callback() {
-    return account_from_account_removed_with_info_callback_;
-  }
-
-  bool was_called_account_removed_with_info_callback() {
-    return was_called_account_removed_with_info_callback_;
-  }
-
- private:
-  // IdentityManager::Observer:
-  void OnPrimaryAccountSet(
-      const CoreAccountInfo& primary_account_info) override {
-    primary_account_from_set_callback_ = primary_account_info;
-    if (on_primary_account_set_callback_)
-      std::move(on_primary_account_set_callback_).Run();
-  }
-  void OnPrimaryAccountCleared(
-      const CoreAccountInfo& previous_primary_account_info) override {
-    primary_account_from_cleared_callback_ = previous_primary_account_info;
-    if (on_primary_account_cleared_callback_)
-      std::move(on_primary_account_cleared_callback_).Run();
-  }
-  void OnPrimaryAccountSigninFailed(
-      const GoogleServiceAuthError& error) override {
-    google_signin_failed_error_ = error;
-    if (on_primary_account_signin_failed_callback_)
-      std::move(on_primary_account_signin_failed_callback_).Run();
-  }
-  void OnRefreshTokenUpdatedForAccount(
-      const CoreAccountInfo& account_info) override {
-    if (!is_inside_batch_)
-      StartBatchOfRefreshTokenStateChanges();
-
-    batch_change_records_.rbegin()->emplace_back(account_info.account_id);
-    account_from_refresh_token_updated_callback_ = account_info;
-    if (on_refresh_token_updated_callback_)
-      std::move(on_refresh_token_updated_callback_).Run();
-  }
-  void OnRefreshTokenRemovedForAccount(const std::string& account_id) override {
-    if (!is_inside_batch_)
-      StartBatchOfRefreshTokenStateChanges();
-
-    batch_change_records_.rbegin()->emplace_back(account_id);
-    account_from_refresh_token_removed_callback_ = account_id;
-    if (on_refresh_token_removed_callback_)
-      on_refresh_token_removed_callback_.Run(account_id);
-  }
-  void OnErrorStateOfRefreshTokenUpdatedForAccount(
-      const CoreAccountInfo& account_info,
-      const GoogleServiceAuthError& error) override {
-    account_from_error_state_of_refresh_token_updated_callback_ = account_info;
-    error_from_error_state_of_refresh_token_updated_callback_ = error;
-    if (on_error_state_of_refresh_token_updated_callback_)
-      std::move(on_error_state_of_refresh_token_updated_callback_).Run();
-  }
-  void OnRefreshTokensLoaded() override {
-    if (on_refresh_tokens_loaded_callback_)
-      std::move(on_refresh_tokens_loaded_callback_).Run();
-  }
-  void OnAccountsInCookieUpdated(
-      const AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
-      const GoogleServiceAuthError& error) override {
-    accounts_info_from_cookie_change_callback_ = accounts_in_cookie_jar_info;
-    if (on_accounts_in_cookie_updated_callback_)
-      std::move(on_accounts_in_cookie_updated_callback_).Run();
-  }
-  void OnAddAccountToCookieCompleted(
-      const std::string& account_id,
-      const GoogleServiceAuthError& error) override {
-    account_from_add_account_to_cookie_completed_callback_ = account_id;
-    error_from_add_account_to_cookie_completed_callback_ = error;
-  }
-  void OnAccountsCookieDeletedByUserAction() override {
-    std::move(on_cookie_deleted_by_user_callback_).Run();
-  }
-
-  void StartBatchOfRefreshTokenStateChanges() {
-    EXPECT_FALSE(is_inside_batch_);
-    is_inside_batch_ = true;
-
-    // Start a new batch.
-    batch_change_records_.emplace_back(std::vector<std::string>());
-  }
-  void OnEndBatchOfRefreshTokenStateChanges() override {
-    EXPECT_TRUE(is_inside_batch_);
-    is_inside_batch_ = false;
-  }
-
-  void OnExtendedAccountInfoUpdated(const AccountInfo& info) override {
-    account_from_account_updated_callback_ = info;
-  }
-
-  void OnExtendedAccountInfoRemoved(const AccountInfo& info) override {
-    was_called_account_removed_with_info_callback_ = true;
-    account_from_account_removed_with_info_callback_ = info;
-  }
-
-  IdentityManager* identity_manager_;
-  base::OnceClosure on_primary_account_set_callback_;
-  base::OnceClosure on_primary_account_cleared_callback_;
-  base::OnceClosure on_primary_account_signin_failed_callback_;
-  base::OnceClosure on_refresh_token_updated_callback_;
-  base::OnceClosure on_cookie_deleted_by_user_callback_;
-  base::RepeatingCallback<void(const std::string&)>
-      on_refresh_token_removed_callback_;
-  base::OnceClosure on_error_state_of_refresh_token_updated_callback_;
-  base::OnceClosure on_refresh_tokens_loaded_callback_;
-  base::OnceClosure on_accounts_in_cookie_updated_callback_;
-  CoreAccountInfo primary_account_from_set_callback_;
-  CoreAccountInfo primary_account_from_cleared_callback_;
-  CoreAccountInfo account_from_refresh_token_updated_callback_;
-  std::string account_from_refresh_token_removed_callback_;
-  CoreAccountInfo account_from_error_state_of_refresh_token_updated_callback_;
-  AccountInfo account_from_account_updated_callback_;
-  AccountInfo account_from_account_removed_with_info_callback_;
-  GoogleServiceAuthError
-      error_from_error_state_of_refresh_token_updated_callback_;
-  AccountsInCookieJarInfo accounts_info_from_cookie_change_callback_;
-  std::string account_from_add_account_to_cookie_completed_callback_;
-  GoogleServiceAuthError error_from_add_account_to_cookie_completed_callback_;
-  GoogleServiceAuthError google_signin_failed_error_;
-  bool is_inside_batch_ = false;
-  bool was_called_account_removed_with_info_callback_ = false;
-  std::vector<std::vector<std::string>> batch_change_records_;
-};
-
 class TestIdentityManagerDiagnosticsObserver
     : IdentityManager::DiagnosticsObserver {
  public:
@@ -672,14 +451,14 @@
   signin_manager()->ForceSignOut();
 
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_primary_account_set_callback(
+  identity_manager_observer()->SetOnPrimaryAccountSetCallback(
       run_loop.QuitClosure());
 
   signin_manager()->SignIn(kTestGaiaId, kTestEmail);
   run_loop.Run();
 
   CoreAccountInfo primary_account_from_set_callback =
-      identity_manager_observer()->primary_account_from_set_callback();
+      identity_manager_observer()->PrimaryAccountFromSetCallback();
   EXPECT_EQ(kTestGaiaId, primary_account_from_set_callback.gaia);
   EXPECT_EQ(kTestEmail, primary_account_from_set_callback.email);
 
@@ -700,7 +479,7 @@
   // First ensure that the user is signed in from the POV of the
   // IdentityManager.
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_primary_account_set_callback(
+  identity_manager_observer()->SetOnPrimaryAccountSetCallback(
       run_loop.QuitClosure());
   signin_manager()->SignIn(kTestGaiaId, kTestEmail);
   run_loop.Run();
@@ -708,14 +487,14 @@
   // Sign the user out and check that the IdentityManager responds
   // appropriately.
   base::RunLoop run_loop2;
-  identity_manager_observer()->set_on_primary_account_cleared_callback(
+  identity_manager_observer()->SetOnPrimaryAccountClearedCallback(
       run_loop2.QuitClosure());
 
   signin_manager()->ForceSignOut();
   run_loop2.Run();
 
   CoreAccountInfo primary_account_from_cleared_callback =
-      identity_manager_observer()->primary_account_from_cleared_callback();
+      identity_manager_observer()->PrimaryAccountFromClearedCallback();
   EXPECT_EQ(kTestGaiaId, primary_account_from_cleared_callback.gaia);
   EXPECT_EQ(kTestEmail, primary_account_from_cleared_callback.email);
 
@@ -736,7 +515,7 @@
   // First ensure that the user is signed in from the POV of the
   // IdentityManager.
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_primary_account_set_callback(
+  identity_manager_observer()->SetOnPrimaryAccountSetCallback(
       run_loop.QuitClosure());
   signin_manager()->SignIn(kTestGaiaId, kTestEmail);
   run_loop.Run();
@@ -769,7 +548,7 @@
   // Signing out should cause IdentityManager to recognize that there is no
   // longer a primary account.
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_primary_account_cleared_callback(
+  identity_manager_observer()->SetOnPrimaryAccountClearedCallback(
       run_loop.QuitClosure());
 
   signin_manager()->ForceSignOut();
@@ -1187,22 +966,22 @@
                                              account_deleted_error);
   EXPECT_EQ(account_id2,
             identity_manager_observer()
-                ->account_from_error_state_of_refresh_token_updated_callback()
+                ->AccountFromErrorStateOfRefreshTokenUpdatedCallback()
                 .account_id);
   EXPECT_EQ(account_deleted_error,
             identity_manager_observer()
-                ->error_from_error_state_of_refresh_token_updated_callback());
+                ->ErrorFromErrorStateOfRefreshTokenUpdatedCallback());
 
   // A transient error should not cause a callback.
   token_service()->UpdateAuthErrorForTesting(primary_account_id,
                                              transient_error);
   EXPECT_EQ(account_id2,
             identity_manager_observer()
-                ->account_from_error_state_of_refresh_token_updated_callback()
+                ->AccountFromErrorStateOfRefreshTokenUpdatedCallback()
                 .account_id);
   EXPECT_EQ(account_deleted_error,
             identity_manager_observer()
-                ->error_from_error_state_of_refresh_token_updated_callback());
+                ->ErrorFromErrorStateOfRefreshTokenUpdatedCallback());
 
   // Set a different persistent error for the primary account and check that
   // it's reflected.
@@ -1210,11 +989,11 @@
                                              account_disabled_error);
   EXPECT_EQ(primary_account_id,
             identity_manager_observer()
-                ->account_from_error_state_of_refresh_token_updated_callback()
+                ->AccountFromErrorStateOfRefreshTokenUpdatedCallback()
                 .account_id);
   EXPECT_EQ(account_disabled_error,
             identity_manager_observer()
-                ->error_from_error_state_of_refresh_token_updated_callback());
+                ->ErrorFromErrorStateOfRefreshTokenUpdatedCallback());
 }
 
 TEST_F(IdentityManagerTest, GetErrorStateOfRefreshTokenForAccount) {
@@ -1491,7 +1270,7 @@
 // firing that tokens were loaded.
 TEST_F(IdentityManagerTest, LegacyLoadCredentials) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_refresh_tokens_loaded_callback(
+  identity_manager_observer()->SetOnRefreshTokensLoadedCallback(
       run_loop.QuitClosure());
 
   // Load the accounts and ensure that we see the resulting notification that
@@ -1526,7 +1305,7 @@
 #if defined(OS_IOS)
 TEST_F(IdentityManagerTest, ForceTriggerOnCookieChange) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
       run_loop.QuitClosure());
 
   signin::SetListAccountsResponseNoAccounts(test_url_loader_factory());
@@ -1628,8 +1407,7 @@
   SetRefreshTokenForPrimaryAccount(identity_manager());
 
   CoreAccountInfo account_info =
-      identity_manager_observer()
-          ->account_from_refresh_token_updated_callback();
+      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
   EXPECT_EQ(kTestGaiaId, account_info.gaia);
   EXPECT_EQ(kTestEmail, account_info.email);
 }
@@ -1641,8 +1419,7 @@
   SetInvalidRefreshTokenForPrimaryAccount(identity_manager());
 
   CoreAccountInfo account_info =
-      identity_manager_observer()
-          ->account_from_refresh_token_updated_callback();
+      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
   EXPECT_EQ(kTestGaiaId, account_info.gaia);
   EXPECT_EQ(kTestEmail, account_info.email);
 }
@@ -1654,8 +1431,9 @@
 
   RemoveRefreshTokenForPrimaryAccount(identity_manager());
 
-  EXPECT_EQ(account_id, identity_manager_observer()
-                            ->account_from_refresh_token_removed_callback());
+  EXPECT_EQ(
+      account_id,
+      identity_manager_observer()->AccountFromRefreshTokenRemovedCallback());
 }
 
 TEST_F(IdentityManagerTest,
@@ -1665,8 +1443,7 @@
   EXPECT_EQ(kTestEmail2, expected_account_info.email);
 
   CoreAccountInfo account_info =
-      identity_manager_observer()
-          ->account_from_refresh_token_updated_callback();
+      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
   EXPECT_EQ(expected_account_info.account_id, account_info.account_id);
   EXPECT_EQ(expected_account_info.gaia, account_info.gaia);
   EXPECT_EQ(expected_account_info.email, account_info.email);
@@ -1682,8 +1459,7 @@
                                    expected_account_info.account_id);
 
   CoreAccountInfo account_info =
-      identity_manager_observer()
-          ->account_from_refresh_token_updated_callback();
+      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
   EXPECT_EQ(expected_account_info.account_id, account_info.account_id);
   EXPECT_EQ(expected_account_info.gaia, account_info.gaia);
   EXPECT_EQ(expected_account_info.email, account_info.email);
@@ -1697,9 +1473,9 @@
   RemoveRefreshTokenForAccount(identity_manager(),
                                expected_account_info.account_id);
 
-  EXPECT_EQ(expected_account_info.account_id,
-            identity_manager_observer()
-                ->account_from_refresh_token_removed_callback());
+  EXPECT_EQ(
+      expected_account_info.account_id,
+      identity_manager_observer()->AccountFromRefreshTokenRemovedCallback());
 }
 
 #if !defined(OS_CHROMEOS)
@@ -1707,7 +1483,7 @@
     IdentityManagerTest,
     CallbackSentOnSecondaryAccountRefreshTokenUpdateWithValidTokenWhenNoPrimaryAccount) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_primary_account_cleared_callback(
+  identity_manager_observer()->SetOnPrimaryAccountClearedCallback(
       run_loop.QuitClosure());
   signin_manager()->ForceSignOut();
   run_loop.Run();
@@ -1717,8 +1493,7 @@
   EXPECT_EQ(kTestEmail2, expected_account_info.email);
 
   CoreAccountInfo account_info =
-      identity_manager_observer()
-          ->account_from_refresh_token_updated_callback();
+      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
   EXPECT_EQ(expected_account_info.account_id, account_info.account_id);
   EXPECT_EQ(expected_account_info.gaia, account_info.gaia);
   EXPECT_EQ(expected_account_info.email, account_info.email);
@@ -1728,7 +1503,7 @@
     IdentityManagerTest,
     CallbackSentOnSecondaryAccountRefreshTokenUpdateWithInvalidTokenWhenNoPrimaryAccount) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_primary_account_cleared_callback(
+  identity_manager_observer()->SetOnPrimaryAccountClearedCallback(
       run_loop.QuitClosure());
   signin_manager()->ForceSignOut();
   run_loop.Run();
@@ -1741,8 +1516,7 @@
                                    expected_account_info.account_id);
 
   CoreAccountInfo account_info =
-      identity_manager_observer()
-          ->account_from_refresh_token_updated_callback();
+      identity_manager_observer()->AccountFromRefreshTokenUpdatedCallback();
   EXPECT_EQ(expected_account_info.account_id, account_info.account_id);
   EXPECT_EQ(expected_account_info.gaia, account_info.gaia);
   EXPECT_EQ(expected_account_info.email, account_info.email);
@@ -1751,7 +1525,7 @@
 TEST_F(IdentityManagerTest,
        CallbackSentOnSecondaryAccountRefreshTokenRemovalWhenNoPrimaryAccount) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_primary_account_cleared_callback(
+  identity_manager_observer()->SetOnPrimaryAccountClearedCallback(
       run_loop.QuitClosure());
   signin_manager()->ForceSignOut();
   run_loop.Run();
@@ -1763,9 +1537,9 @@
   RemoveRefreshTokenForAccount(identity_manager(),
                                expected_account_info.account_id);
 
-  EXPECT_EQ(expected_account_info.account_id,
-            identity_manager_observer()
-                ->account_from_refresh_token_removed_callback());
+  EXPECT_EQ(
+      expected_account_info.account_id,
+      identity_manager_observer()->AccountFromRefreshTokenRemovedCallback());
 }
 #endif
 
@@ -1783,9 +1557,9 @@
   token_service()->RevokeCredentials(dummy_account_id);
   run_loop.RunUntilIdle();
 
-  EXPECT_EQ(dummy_account_id,
-            identity_manager_observer()
-                ->account_from_refresh_token_removed_callback());
+  EXPECT_EQ(
+      dummy_account_id,
+      identity_manager_observer()->AccountFromRefreshTokenRemovedCallback());
 }
 
 TEST_F(
@@ -1851,7 +1625,7 @@
   std::string account_id = signin_manager()->GetAuthenticatedAccountId();
 
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_refresh_tokens_loaded_callback(
+  identity_manager_observer()->SetOnRefreshTokensLoadedCallback(
       run_loop.QuitClosure());
 
   // Credentials are already loaded in SigninManager::Initialize()
@@ -1866,7 +1640,7 @@
 TEST_F(IdentityManagerTest,
        CallbackSentOnUpdateToAccountsInCookieWithNoAccounts) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
       run_loop.QuitClosure());
 
   signin::SetListAccountsResponseNoAccounts(test_url_loader_factory());
@@ -1874,7 +1648,8 @@
   run_loop.Run();
 
   const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
-      identity_manager_observer()->accounts_info_from_cookie_change_callback();
+      identity_manager_observer()
+          ->AccountsInfoFromAccountsInCookieUpdatedCallback();
   EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
   EXPECT_TRUE(accounts_in_cookie_jar_info.signed_in_accounts.empty());
 }
@@ -1882,7 +1657,7 @@
 TEST_F(IdentityManagerTest,
        CallbackSentOnUpdateToAccountsInCookieWithOneAccount) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
       run_loop.QuitClosure());
 
   signin::SetListAccountsResponseOneAccount(kTestEmail, kTestGaiaId,
@@ -1891,7 +1666,8 @@
   run_loop.Run();
 
   const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
-      identity_manager_observer()->accounts_info_from_cookie_change_callback();
+      identity_manager_observer()
+          ->AccountsInfoFromAccountsInCookieUpdatedCallback();
   EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
   ASSERT_EQ(1u, accounts_in_cookie_jar_info.signed_in_accounts.size());
   ASSERT_TRUE(accounts_in_cookie_jar_info.signed_out_accounts.empty());
@@ -1908,7 +1684,7 @@
 TEST_F(IdentityManagerTest,
        CallbackSentOnUpdateToAccountsInCookieWithTwoAccounts) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
       run_loop.QuitClosure());
 
   signin::SetListAccountsResponseTwoAccounts(kTestEmail, kTestGaiaId,
@@ -1918,7 +1694,8 @@
   run_loop.Run();
 
   const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
-      identity_manager_observer()->accounts_info_from_cookie_change_callback();
+      identity_manager_observer()
+          ->AccountsInfoFromAccountsInCookieUpdatedCallback();
   EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
   ASSERT_EQ(2u, accounts_in_cookie_jar_info.signed_in_accounts.size());
   ASSERT_TRUE(accounts_in_cookie_jar_info.signed_out_accounts.empty());
@@ -1950,7 +1727,7 @@
 
   for (const auto& signed_out_status : signed_out_status_set) {
     base::RunLoop run_loop;
-    identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+    identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
         run_loop.QuitClosure());
 
     signin::SetListAccountsResponseWithParams(
@@ -1967,7 +1744,7 @@
         signed_out_status.account_1 + signed_out_status.account_2;
     const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
         identity_manager_observer()
-            ->accounts_info_from_cookie_change_callback();
+            ->AccountsInfoFromAccountsInCookieUpdatedCallback();
     EXPECT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
     ASSERT_EQ(2 - accounts_signed_out,
               accounts_in_cookie_jar_info.signed_in_accounts.size());
@@ -2007,7 +1784,7 @@
 TEST_F(IdentityManagerTest,
        CallbackSentOnUpdateToAccountsInCookieWithStaleAccounts) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
       run_loop.QuitClosure());
 
   // Configure list accounts to return a permanent Gaia auth error.
@@ -2016,7 +1793,8 @@
   run_loop.Run();
 
   const AccountsInCookieJarInfo& accounts_in_cookie_jar_info =
-      identity_manager_observer()->accounts_info_from_cookie_change_callback();
+      identity_manager_observer()
+          ->AccountsInfoFromAccountsInCookieUpdatedCallback();
   EXPECT_FALSE(accounts_in_cookie_jar_info.accounts_are_fresh);
   EXPECT_TRUE(accounts_in_cookie_jar_info.signed_in_accounts.empty());
   EXPECT_TRUE(accounts_in_cookie_jar_info.signed_out_accounts.empty());
@@ -2024,7 +1802,7 @@
 
 TEST_F(IdentityManagerTest, GetAccountsInCookieJarWithNoAccounts) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
       run_loop.QuitClosure());
 
   signin::SetListAccountsResponseNoAccounts(test_url_loader_factory());
@@ -2052,7 +1830,7 @@
 
 TEST_F(IdentityManagerTest, GetAccountsInCookieJarWithOneAccount) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
       run_loop.QuitClosure());
 
   signin::SetListAccountsResponseOneAccount(kTestEmail, kTestGaiaId,
@@ -2089,7 +1867,7 @@
 
 TEST_F(IdentityManagerTest, GetAccountsInCookieJarWithTwoAccounts) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_accounts_in_cookie_updated_callback(
+  identity_manager_observer()->SetOnAccountsInCookieUpdatedCallback(
       run_loop.QuitClosure());
 
   signin::SetListAccountsResponseTwoAccounts(kTestEmail, kTestGaiaId,
@@ -2142,10 +1920,10 @@
   SimulateAdditionOfAccountToCookieSuccess(gaia_cookie_manager_service(),
                                            "token");
   EXPECT_EQ(identity_manager_observer()
-                ->account_from_add_account_to_cookie_completed_callback(),
+                ->AccountFromAddAccountToCookieCompletedCallback(),
             kTestAccountId);
   EXPECT_EQ(identity_manager_observer()
-                ->error_from_add_account_to_cookie_completed_callback(),
+                ->ErrorFromAddAccountToCookieCompletedCallback(),
             GoogleServiceAuthError::AuthErrorNone());
 }
 
@@ -2158,10 +1936,10 @@
   SimulateAdditionOfAccountToCookieSuccessFailure(gaia_cookie_manager_service(),
                                                   error);
   EXPECT_EQ(identity_manager_observer()
-                ->account_from_add_account_to_cookie_completed_callback(),
+                ->AccountFromAddAccountToCookieCompletedCallback(),
             kTestAccountId);
   EXPECT_EQ(identity_manager_observer()
-                ->error_from_add_account_to_cookie_completed_callback(),
+                ->ErrorFromAddAccountToCookieCompletedCallback(),
             error);
 }
 
@@ -2273,7 +2051,7 @@
   base::RunLoop().RunUntilIdle();
 
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_cookie_deleted_by_user_callback(
+  identity_manager_observer()->SetOnCookieDeletedByUserCallback(
       run_loop.QuitClosure());
 
   const std::vector<net::CanonicalCookie>& cookies = result.cookies();
@@ -2324,7 +2102,7 @@
   base::RunLoop().RunUntilIdle();
 
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_cookie_deleted_by_user_callback(
+  identity_manager_observer()->SetOnCookieDeletedByUserCallback(
       run_loop.QuitClosure());
 
   const std::vector<net::CanonicalCookie>& cookies = result.cookies();
@@ -2351,11 +2129,11 @@
   std::string account_id = signin_manager()->GetAuthenticatedAccountId();
   token_service()->UpdateCredentials(account_id, "refresh_token");
 
-  EXPECT_EQ(1ul, identity_manager_observer()->batch_change_records().size());
+  EXPECT_EQ(1ul, identity_manager_observer()->BatchChangeRecords().size());
   EXPECT_EQ(1ul,
-            identity_manager_observer()->batch_change_records().at(0).size());
+            identity_manager_observer()->BatchChangeRecords().at(0).size());
   EXPECT_EQ(account_id,
-            identity_manager_observer()->batch_change_records().at(0).at(0));
+            identity_manager_observer()->BatchChangeRecords().at(0).at(0));
 }
 
 // Checks that FindAccountInfoForAccountWithRefreshTokenByAccountId() returns
@@ -2437,7 +2215,7 @@
 // Checks that AreRefreshTokensLoaded() returns true after LoadCredentials.
 TEST_F(IdentityManagerTest, AreRefreshTokensLoaded) {
   base::RunLoop run_loop;
-  identity_manager_observer()->set_on_refresh_tokens_loaded_callback(
+  identity_manager_observer()->SetOnRefreshTokensLoadedCallback(
       run_loop.QuitClosure());
 
   // Credentials are already loaded in SigninManager::Initialize()
@@ -2475,13 +2253,12 @@
   account_tracker()->SetAccountInfoFromUserInfo(account_info.account_id,
                                                 &user_info);
 
-  EXPECT_EQ(account_info.account_id,
-            identity_manager_observer()
-                ->account_from_account_updated_callback()
-                .account_id);
-  EXPECT_EQ(account_info.email, identity_manager_observer()
-                                    ->account_from_account_updated_callback()
-                                    .email);
+  EXPECT_EQ(account_info.account_id, identity_manager_observer()
+                                         ->AccountFromAccountUpdatedCallback()
+                                         .account_id);
+  EXPECT_EQ(
+      account_info.email,
+      identity_manager_observer()->AccountFromAccountUpdatedCallback().email);
 }
 
 TEST_F(IdentityManagerTest, TestOnAccountRemovedWithInfoCallback) {
@@ -2493,17 +2270,17 @@
 
   // Check if OnAccountRemovedWithInfo is called after removing |account_info|
   // by RemoveAccount().
-  EXPECT_TRUE(identity_manager_observer()
-                  ->was_called_account_removed_with_info_callback());
+  EXPECT_TRUE(
+      identity_manager_observer()->WasCalledAccountRemovedWithInfoCallback());
 
   // Check if the passed AccountInfo is the same to the removing one.
   EXPECT_EQ(account_info.account_id,
             identity_manager_observer()
-                ->account_from_account_removed_with_info_callback()
+                ->AccountFromAccountRemovedWithInfoCallback()
                 .account_id);
   EXPECT_EQ(account_info.email,
             identity_manager_observer()
-                ->account_from_account_removed_with_info_callback()
+                ->AccountFromAccountRemovedWithInfoCallback()
                 .email);
 }
 
diff --git a/services/identity/public/cpp/test_identity_manager_observer.cc b/services/identity/public/cpp/test_identity_manager_observer.cc
new file mode 100644
index 0000000..b7e170d
--- /dev/null
+++ b/services/identity/public/cpp/test_identity_manager_observer.cc
@@ -0,0 +1,251 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/identity/public/cpp/test_identity_manager_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include <utility>
+
+namespace identity {
+
+TestIdentityManagerObserver::TestIdentityManagerObserver(
+    IdentityManager* identity_manager)
+    : identity_manager_(identity_manager) {
+  identity_manager_->AddObserver(this);
+}
+
+TestIdentityManagerObserver::~TestIdentityManagerObserver() {
+  identity_manager_->RemoveObserver(this);
+}
+
+void TestIdentityManagerObserver::SetOnPrimaryAccountSetCallback(
+    base::OnceClosure callback) {
+  on_primary_account_set_callback_ = std::move(callback);
+}
+
+const CoreAccountInfo&
+TestIdentityManagerObserver::PrimaryAccountFromSetCallback() {
+  return primary_account_from_set_callback_;
+}
+
+void TestIdentityManagerObserver::SetOnPrimaryAccountClearedCallback(
+    base::OnceClosure callback) {
+  on_primary_account_cleared_callback_ = std::move(callback);
+}
+
+const CoreAccountInfo&
+TestIdentityManagerObserver::PrimaryAccountFromClearedCallback() {
+  return primary_account_from_cleared_callback_;
+}
+
+void TestIdentityManagerObserver::SetOnPrimaryAccountSigninFailedCallback(
+    base::OnceClosure callback) {
+  on_primary_account_signin_failed_callback_ = std::move(callback);
+}
+
+const GoogleServiceAuthError&
+TestIdentityManagerObserver::ErrorFromSigninFailedCallback() const {
+  return google_signin_failed_error_;
+}
+
+void TestIdentityManagerObserver::SetOnRefreshTokenUpdatedCallback(
+    base::OnceClosure callback) {
+  on_refresh_token_updated_callback_ = std::move(callback);
+}
+
+const CoreAccountInfo&
+TestIdentityManagerObserver::AccountFromRefreshTokenUpdatedCallback() {
+  return account_from_refresh_token_updated_callback_;
+}
+
+void TestIdentityManagerObserver::SetOnErrorStateOfRefreshTokenUpdatedCallback(
+    base::OnceClosure callback) {
+  on_error_state_of_refresh_token_updated_callback_ = std::move(callback);
+}
+
+const CoreAccountInfo& TestIdentityManagerObserver::
+    AccountFromErrorStateOfRefreshTokenUpdatedCallback() {
+  return account_from_error_state_of_refresh_token_updated_callback_;
+}
+
+const GoogleServiceAuthError&
+TestIdentityManagerObserver::ErrorFromErrorStateOfRefreshTokenUpdatedCallback()
+    const {
+  return error_from_error_state_of_refresh_token_updated_callback_;
+}
+
+// This method uses a RepeatingCallback to simplify verification of multiple
+// removed tokens.
+void TestIdentityManagerObserver::SetOnRefreshTokenRemovedCallback(
+    base::RepeatingCallback<void(const std::string&)> callback) {
+  on_refresh_token_removed_callback_ = std::move(callback);
+}
+
+const std::string&
+TestIdentityManagerObserver::AccountFromRefreshTokenRemovedCallback() {
+  return account_from_refresh_token_removed_callback_;
+}
+
+void TestIdentityManagerObserver::SetOnRefreshTokensLoadedCallback(
+    base::OnceClosure callback) {
+  on_refresh_tokens_loaded_callback_ = std::move(callback);
+}
+
+void TestIdentityManagerObserver::SetOnAccountsInCookieUpdatedCallback(
+    base::OnceClosure callback) {
+  on_accounts_in_cookie_updated_callback_ = std::move(callback);
+}
+
+const AccountsInCookieJarInfo&
+TestIdentityManagerObserver::AccountsInfoFromAccountsInCookieUpdatedCallback() {
+  return accounts_info_from_cookie_change_callback_;
+}
+
+void TestIdentityManagerObserver::SetOnAddAccountToCookieCompletedCallback(
+    base::OnceClosure callback) {
+  on_add_account_to_cookie_completed_callback_ = std::move(callback);
+}
+
+const std::string&
+TestIdentityManagerObserver::AccountFromAddAccountToCookieCompletedCallback()
+    const {
+  return account_from_add_account_to_cookie_completed_callback_;
+}
+
+const GoogleServiceAuthError&
+TestIdentityManagerObserver::ErrorFromAddAccountToCookieCompletedCallback()
+    const {
+  return error_from_add_account_to_cookie_completed_callback_;
+}
+
+void TestIdentityManagerObserver::SetOnCookieDeletedByUserCallback(
+    base::OnceClosure callback) {
+  on_cookie_deleted_by_user_callback_ = std::move(callback);
+}
+
+const AccountInfo&
+TestIdentityManagerObserver::AccountFromAccountUpdatedCallback() {
+  return account_from_account_updated_callback_;
+}
+
+const AccountInfo&
+TestIdentityManagerObserver::AccountFromAccountRemovedWithInfoCallback() {
+  return account_from_account_removed_with_info_callback_;
+}
+
+bool TestIdentityManagerObserver::WasCalledAccountRemovedWithInfoCallback() {
+  return was_called_account_removed_with_info_callback_;
+}
+
+// Each element represents all the changes from an individual batch that has
+// occurred, with the elements ordered from oldest to newest batch occurrence.
+const std::vector<std::vector<std::string>>&
+TestIdentityManagerObserver::BatchChangeRecords() const {
+  return batch_change_records_;
+}
+
+// IdentityManager::Observer:
+void TestIdentityManagerObserver::OnPrimaryAccountSet(
+    const CoreAccountInfo& primary_account_info) {
+  primary_account_from_set_callback_ = primary_account_info;
+  if (on_primary_account_set_callback_)
+    std::move(on_primary_account_set_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnPrimaryAccountCleared(
+    const CoreAccountInfo& previous_primary_account_info) {
+  primary_account_from_cleared_callback_ = previous_primary_account_info;
+  if (on_primary_account_cleared_callback_)
+    std::move(on_primary_account_cleared_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnPrimaryAccountSigninFailed(
+    const GoogleServiceAuthError& error) {
+  google_signin_failed_error_ = error;
+  if (on_primary_account_signin_failed_callback_)
+    std::move(on_primary_account_signin_failed_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnRefreshTokenUpdatedForAccount(
+    const CoreAccountInfo& account_info) {
+  if (!is_inside_batch_)
+    StartBatchOfRefreshTokenStateChanges();
+
+  batch_change_records_.rbegin()->emplace_back(account_info.account_id);
+  account_from_refresh_token_updated_callback_ = account_info;
+  if (on_refresh_token_updated_callback_)
+    std::move(on_refresh_token_updated_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnRefreshTokenRemovedForAccount(
+    const std::string& account_id) {
+  if (!is_inside_batch_)
+    StartBatchOfRefreshTokenStateChanges();
+
+  batch_change_records_.rbegin()->emplace_back(account_id);
+  account_from_refresh_token_removed_callback_ = account_id;
+  if (on_refresh_token_removed_callback_)
+    on_refresh_token_removed_callback_.Run(account_id);
+}
+
+void TestIdentityManagerObserver::OnErrorStateOfRefreshTokenUpdatedForAccount(
+    const CoreAccountInfo& account_info,
+    const GoogleServiceAuthError& error) {
+  account_from_error_state_of_refresh_token_updated_callback_ = account_info;
+  error_from_error_state_of_refresh_token_updated_callback_ = error;
+  if (on_error_state_of_refresh_token_updated_callback_)
+    std::move(on_error_state_of_refresh_token_updated_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnRefreshTokensLoaded() {
+  if (on_refresh_tokens_loaded_callback_)
+    std::move(on_refresh_tokens_loaded_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnAccountsInCookieUpdated(
+    const AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
+    const GoogleServiceAuthError& error) {
+  accounts_info_from_cookie_change_callback_ = accounts_in_cookie_jar_info;
+  if (on_accounts_in_cookie_updated_callback_)
+    std::move(on_accounts_in_cookie_updated_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnAddAccountToCookieCompleted(
+    const std::string& account_id,
+    const GoogleServiceAuthError& error) {
+  account_from_add_account_to_cookie_completed_callback_ = account_id;
+  error_from_add_account_to_cookie_completed_callback_ = error;
+  if (on_add_account_to_cookie_completed_callback_)
+    std::move(on_add_account_to_cookie_completed_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnAccountsCookieDeletedByUserAction() {
+  std::move(on_cookie_deleted_by_user_callback_).Run();
+}
+
+void TestIdentityManagerObserver::OnExtendedAccountInfoUpdated(
+    const AccountInfo& info) {
+  account_from_account_updated_callback_ = info;
+}
+
+void TestIdentityManagerObserver::OnExtendedAccountInfoRemoved(
+    const AccountInfo& info) {
+  was_called_account_removed_with_info_callback_ = true;
+  account_from_account_removed_with_info_callback_ = info;
+}
+
+void TestIdentityManagerObserver::StartBatchOfRefreshTokenStateChanges() {
+  EXPECT_FALSE(is_inside_batch_);
+  is_inside_batch_ = true;
+
+  // Start a new batch.
+  batch_change_records_.emplace_back(std::vector<std::string>());
+}
+
+void TestIdentityManagerObserver::OnEndBatchOfRefreshTokenStateChanges() {
+  EXPECT_TRUE(is_inside_batch_);
+  is_inside_batch_ = false;
+}
+
+}  // namespace identity
diff --git a/services/identity/public/cpp/test_identity_manager_observer.h b/services/identity/public/cpp/test_identity_manager_observer.h
new file mode 100644
index 0000000..65639c6
--- /dev/null
+++ b/services/identity/public/cpp/test_identity_manager_observer.h
@@ -0,0 +1,148 @@
+// Copyright 2017 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 SERVICES_IDENTITY_PUBLIC_CPP_TEST_IDENTITY_MANAGER_OBSERVER_H_
+#define SERVICES_IDENTITY_PUBLIC_CPP_TEST_IDENTITY_MANAGER_OBSERVER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "components/signin/core/browser/account_info.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "services/identity/public/cpp/accounts_in_cookie_jar_info.h"
+#include "services/identity/public/cpp/identity_manager.h"
+
+namespace identity {
+
+// Class that observes events from identity::IdentityManager. It allows setting
+// |OnceClosure| callbacks to be executed for the observed events and retrieving
+// the potential results and/or errors returned after such events have occurred.
+class TestIdentityManagerObserver : IdentityManager::Observer {
+ public:
+  explicit TestIdentityManagerObserver(IdentityManager* identity_manager);
+  ~TestIdentityManagerObserver() override;
+
+  void SetOnPrimaryAccountSetCallback(base::OnceClosure callback);
+  const CoreAccountInfo& PrimaryAccountFromSetCallback();
+
+  void SetOnPrimaryAccountClearedCallback(base::OnceClosure callback);
+  const CoreAccountInfo& PrimaryAccountFromClearedCallback();
+
+  void SetOnPrimaryAccountSigninFailedCallback(base::OnceClosure callback);
+  const GoogleServiceAuthError& ErrorFromSigninFailedCallback() const;
+
+  void SetOnRefreshTokenUpdatedCallback(base::OnceClosure callback);
+  const CoreAccountInfo& AccountFromRefreshTokenUpdatedCallback();
+
+  void SetOnErrorStateOfRefreshTokenUpdatedCallback(base::OnceClosure callback);
+  const CoreAccountInfo& AccountFromErrorStateOfRefreshTokenUpdatedCallback();
+  const GoogleServiceAuthError&
+  ErrorFromErrorStateOfRefreshTokenUpdatedCallback() const;
+
+  // This method uses a RepeatingCallback to simplify verification of multiple
+  // removed tokens.
+  void SetOnRefreshTokenRemovedCallback(
+      base::RepeatingCallback<void(const std::string&)> callback);
+  const std::string& AccountFromRefreshTokenRemovedCallback();
+
+  void SetOnRefreshTokensLoadedCallback(base::OnceClosure callback);
+
+  void SetOnAccountsInCookieUpdatedCallback(base::OnceClosure callback);
+  const AccountsInCookieJarInfo&
+  AccountsInfoFromAccountsInCookieUpdatedCallback();
+
+  void SetOnAddAccountToCookieCompletedCallback(base::OnceClosure callback);
+  const std::string& AccountFromAddAccountToCookieCompletedCallback() const;
+  const GoogleServiceAuthError& ErrorFromAddAccountToCookieCompletedCallback()
+      const;
+
+  void SetOnCookieDeletedByUserCallback(base::OnceClosure callback);
+
+  const AccountInfo& AccountFromAccountUpdatedCallback();
+  const AccountInfo& AccountFromAccountRemovedWithInfoCallback();
+  bool WasCalledAccountRemovedWithInfoCallback();
+
+  // Each element represents all the changes from an individual batch that has
+  // occurred, with the elements ordered from oldest to newest batch occurrence.
+  const std::vector<std::vector<std::string>>& BatchChangeRecords() const;
+
+ private:
+  // IdentityManager::Observer:
+  void OnPrimaryAccountSet(
+      const CoreAccountInfo& primary_account_info) override;
+  void OnPrimaryAccountCleared(
+      const CoreAccountInfo& previous_primary_account_info) override;
+  void OnPrimaryAccountSigninFailed(
+      const GoogleServiceAuthError& error) override;
+
+  void OnRefreshTokenUpdatedForAccount(
+      const CoreAccountInfo& account_info) override;
+  void OnRefreshTokenRemovedForAccount(const std::string& account_id) override;
+  void OnErrorStateOfRefreshTokenUpdatedForAccount(
+      const CoreAccountInfo& account_info,
+      const GoogleServiceAuthError& error) override;
+  void OnRefreshTokensLoaded() override;
+
+  void OnAccountsInCookieUpdated(
+      const AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
+      const GoogleServiceAuthError& error) override;
+  void OnAddAccountToCookieCompleted(
+      const std::string& account_id,
+      const GoogleServiceAuthError& error) override;
+  void OnAccountsCookieDeletedByUserAction() override;
+
+  void OnExtendedAccountInfoUpdated(const AccountInfo& info) override;
+  void OnExtendedAccountInfoRemoved(const AccountInfo& info) override;
+
+  void StartBatchOfRefreshTokenStateChanges();
+  void OnEndBatchOfRefreshTokenStateChanges() override;
+
+  IdentityManager* identity_manager_;
+
+  base::OnceClosure on_primary_account_set_callback_;
+  CoreAccountInfo primary_account_from_set_callback_;
+
+  base::OnceClosure on_primary_account_cleared_callback_;
+  CoreAccountInfo primary_account_from_cleared_callback_;
+
+  base::OnceClosure on_primary_account_signin_failed_callback_;
+  GoogleServiceAuthError google_signin_failed_error_;
+
+  base::OnceClosure on_refresh_token_updated_callback_;
+  CoreAccountInfo account_from_refresh_token_updated_callback_;
+
+  base::OnceClosure on_error_state_of_refresh_token_updated_callback_;
+  CoreAccountInfo account_from_error_state_of_refresh_token_updated_callback_;
+  GoogleServiceAuthError
+      error_from_error_state_of_refresh_token_updated_callback_;
+
+  base::RepeatingCallback<void(const std::string&)>
+      on_refresh_token_removed_callback_;
+  std::string account_from_refresh_token_removed_callback_;
+
+  base::OnceClosure on_refresh_tokens_loaded_callback_;
+
+  base::OnceClosure on_accounts_in_cookie_updated_callback_;
+  AccountsInCookieJarInfo accounts_info_from_cookie_change_callback_;
+
+  base::OnceClosure on_add_account_to_cookie_completed_callback_;
+  std::string account_from_add_account_to_cookie_completed_callback_;
+  GoogleServiceAuthError error_from_add_account_to_cookie_completed_callback_;
+
+  base::OnceClosure on_cookie_deleted_by_user_callback_;
+
+  AccountInfo account_from_account_updated_callback_;
+  AccountInfo account_from_account_removed_with_info_callback_;
+
+  bool is_inside_batch_ = false;
+  bool was_called_account_removed_with_info_callback_ = false;
+  std::vector<std::vector<std::string>> batch_change_records_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestIdentityManagerObserver);
+};
+
+}  // namespace identity
+
+#endif  // SERVICES_IDENTITY_PUBLIC_CPP_TEST_IDENTITY_MANAGER_OBSERVER_H_
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 7bfd18b..00066bac 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -42,14 +42,6 @@
 const base::Feature kDelayRequestsOnMultiplexedConnections{
     "DelayRequestsOnMultiplexedConnections", base::FEATURE_ENABLED_BY_DEFAULT};
 
-// When kUnthrottleRequestsAfterLongQueuingDelay is enabled, an upper bound
-// is placed on how long the resource scheduler can queue any given request.
-// Once a request is queued for more than the specified duration, the request
-// is dispatched to the network.
-const base::Feature kUnthrottleRequestsAfterLongQueuingDelay{
-    "UnthrottleRequestsAfterLongQueuingDelay",
-    base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Kill switch for enforcing
 // URLLoaderFactoryParams::request_initiator_origin_lock for Cross-Origin Read
 // Blocking.  When enabled, then CORB treats |request_initiator| as opaque
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index c871268..72618b3 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -26,8 +26,6 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kDelayRequestsOnMultiplexedConnections;
 COMPONENT_EXPORT(NETWORK_CPP)
-extern const base::Feature kUnthrottleRequestsAfterLongQueuingDelay;
-COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kEnforceRequestInitiatorLockForCorb;
 
 }  // namespace features
diff --git a/services/network/resource_scheduler.cc b/services/network/resource_scheduler.cc
index 2be8dae..8da4f77 100644
--- a/services/network/resource_scheduler.cc
+++ b/services/network/resource_scheduler.cc
@@ -1001,9 +1001,7 @@
   Client* client = it->second.get();
   // TODO(crbug.com/873959): Remove this CHECK once the investigation is done.
   CHECK(client);
-  DCHECK(!base::FeatureList::IsEnabled(
-             features::kUnthrottleRequestsAfterLongQueuingDelay) ||
-         client->HasNoPendingRequests() ||
+  DCHECK(client->HasNoPendingRequests() ||
          IsLongQueuedRequestsDispatchTimerRunning());
   // ResourceDispatcherHost cancels all requests except for cross-renderer
   // navigations, async revalidations and detachable requests after
@@ -1027,11 +1025,6 @@
 }
 
 void ResourceScheduler::StartLongQueuedRequestsDispatchTimerIfNeeded() {
-  if (!base::FeatureList::IsEnabled(
-          features::kUnthrottleRequestsAfterLongQueuingDelay)) {
-    return;
-  }
-
   bool pending_request_found = false;
   for (const auto& client : client_map_) {
     if (!client.second->HasNoPendingRequests()) {
diff --git a/services/network/resource_scheduler_params_manager.cc b/services/network/resource_scheduler_params_manager.cc
index d3dbf8f..690de0c 100644
--- a/services/network/resource_scheduler_params_manager.cc
+++ b/services/network/resource_scheduler_params_manager.cc
@@ -19,7 +19,11 @@
 
 // The maximum number of delayable requests to allow to be in-flight at any
 // point in time (across all hosts).
-static const size_t kDefaultMaxNumDelayableRequestsPerClient = 10;
+constexpr size_t kDefaultMaxNumDelayableRequestsPerClient = 10;
+
+// Value by which HTTP RTT estimate is multiplied to get the maximum queuing
+// duration.
+constexpr int kHttpRttMultiplierForQueuingDuration = 30;
 
 // Reads experiment parameters and returns them.
 ResourceSchedulerParamsManager::ParamsForNetworkQualityContainer
@@ -133,38 +137,39 @@
     }
   }
 
-  if (base::FeatureList::IsEnabled(
-          features::kUnthrottleRequestsAfterLongQueuingDelay)) {
-    int http_rtt_multiplier = base::GetFieldTrialParamByFeatureAsInt(
-        features::kUnthrottleRequestsAfterLongQueuingDelay,
-        "http_rtt_multiplier", -1);
+  for (int ect = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
+       ect <= net::EFFECTIVE_CONNECTION_TYPE_4G; ++ect) {
+    net::EffectiveConnectionType effective_connection_type =
+        static_cast<net::EffectiveConnectionType>(ect);
+    base::TimeDelta http_rtt =
+        net::NetworkQualityEstimatorParams::GetDefaultTypicalHttpRtt(
+            effective_connection_type);
+    base::TimeDelta max_queuing_time =
+        http_rtt * kHttpRttMultiplierForQueuingDuration;
 
-    if (http_rtt_multiplier > 0) {
-      for (int ect = net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
-           ect <= net::EFFECTIVE_CONNECTION_TYPE_4G; ++ect) {
-        net::EffectiveConnectionType effective_connection_type =
-            static_cast<net::EffectiveConnectionType>(ect);
-        base::TimeDelta http_rtt =
-            net::NetworkQualityEstimatorParams::GetDefaultTypicalHttpRtt(
-                effective_connection_type);
-        base::TimeDelta max_queuing_time = http_rtt * http_rtt_multiplier;
-        if (max_queuing_time < kLowerBoundQueuingDuration)
-          max_queuing_time = kLowerBoundQueuingDuration;
-        if (max_queuing_time > kUpperBoundQueuingDuration)
-          max_queuing_time = kUpperBoundQueuingDuration;
+    // If GetDefaultTypicalHttpRtt returns a null value, set
+    // |max_queuing_time| to kUpperBoundQueuingDuration, This may happen
+    // when |ect| is UNKNOWN or OFFLINE. Both these cases are very rare, but
+    // it's important to handle them to ensure that |max_queuing_time|
+    // is set to some non-zero value in all cases. This ensures that the
+    // requests that are queued for too long are always unthrottled.
+    if (http_rtt.is_zero())
+      max_queuing_time = kUpperBoundQueuingDuration;
+    if (max_queuing_time < kLowerBoundQueuingDuration)
+      max_queuing_time = kLowerBoundQueuingDuration;
+    if (max_queuing_time > kUpperBoundQueuingDuration)
+      max_queuing_time = kUpperBoundQueuingDuration;
 
-        ResourceSchedulerParamsManager::ParamsForNetworkQualityContainer::
-            iterator iter = result.find(effective_connection_type);
-        if (iter != result.end()) {
-          iter->second.max_queuing_time = max_queuing_time;
-        } else {
-          result.emplace(std::make_pair(
-              effective_connection_type,
-              ResourceSchedulerParamsManager::ParamsForNetworkQuality(
-                  kDefaultMaxNumDelayableRequestsPerClient, 0.0, false,
-                  max_queuing_time)));
-        }
-      }
+    ResourceSchedulerParamsManager::ParamsForNetworkQualityContainer::iterator
+        iter = result.find(effective_connection_type);
+    if (iter != result.end()) {
+      iter->second.max_queuing_time = max_queuing_time;
+    } else {
+      result.emplace(std::make_pair(
+          effective_connection_type,
+          ResourceSchedulerParamsManager::ParamsForNetworkQuality(
+              kDefaultMaxNumDelayableRequestsPerClient, 0.0, false,
+              max_queuing_time)));
     }
   }
 
diff --git a/services/network/resource_scheduler_params_manager_unittest.cc b/services/network/resource_scheduler_params_manager_unittest.cc
index ada30053..f11dc46 100644
--- a/services/network/resource_scheduler_params_manager_unittest.cc
+++ b/services/network/resource_scheduler_params_manager_unittest.cc
@@ -20,8 +20,13 @@
 
 namespace {
 
-static constexpr base::TimeDelta kLowerBoundQueuingDuration =
+// Should remain synchronized with the values in
+// resouce_scheduler_params_manager.cc.
+constexpr base::TimeDelta kLowerBoundQueuingDuration =
     base::TimeDelta::FromSeconds(15);
+constexpr base::TimeDelta kUpperBoundQueuingDuration =
+    base::TimeDelta::FromSeconds(120);
+constexpr int kHttpRttMultiplierForQueuingDuration = 30;
 
 class ResourceSchedulerParamsManagerTest : public testing::Test {
  public:
@@ -104,7 +109,7 @@
             resource_scheduler_params_manager
                 .GetParamsForEffectiveConnectionType(effective_connection_type)
                 .delay_requests_on_multiplexed_connections);
-        EXPECT_FALSE(
+        EXPECT_TRUE(
             resource_scheduler_params_manager
                 .GetParamsForEffectiveConnectionType(effective_connection_type)
                 .max_queuing_time.has_value());
@@ -123,7 +128,7 @@
             resource_scheduler_params_manager
                 .GetParamsForEffectiveConnectionType(effective_connection_type)
                 .delay_requests_on_multiplexed_connections);
-        EXPECT_FALSE(
+        EXPECT_TRUE(
             resource_scheduler_params_manager
                 .GetParamsForEffectiveConnectionType(effective_connection_type)
                 .max_queuing_time.has_value());
@@ -143,7 +148,7 @@
             resource_scheduler_params_manager
                 .GetParamsForEffectiveConnectionType(effective_connection_type)
                 .delay_requests_on_multiplexed_connections);
-        EXPECT_FALSE(
+        EXPECT_TRUE(
             resource_scheduler_params_manager
                 .GetParamsForEffectiveConnectionType(effective_connection_type)
                 .max_queuing_time.has_value());
@@ -214,9 +219,9 @@
       EXPECT_TRUE(resource_scheduler_params_manager
                       .GetParamsForEffectiveConnectionType(ect)
                       .delay_requests_on_multiplexed_connections);
-      EXPECT_FALSE(resource_scheduler_params_manager
-                       .GetParamsForEffectiveConnectionType(ect)
-                       .max_queuing_time.has_value());
+      EXPECT_TRUE(resource_scheduler_params_manager
+                      .GetParamsForEffectiveConnectionType(ect)
+                      .max_queuing_time.has_value());
 
     } else if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_3G) {
       EXPECT_EQ(10u, resource_scheduler_params_manager
@@ -228,9 +233,9 @@
       EXPECT_FALSE(resource_scheduler_params_manager
                        .GetParamsForEffectiveConnectionType(ect)
                        .delay_requests_on_multiplexed_connections);
-      EXPECT_FALSE(resource_scheduler_params_manager
-                       .GetParamsForEffectiveConnectionType(ect)
-                       .max_queuing_time.has_value());
+      EXPECT_TRUE(resource_scheduler_params_manager
+                      .GetParamsForEffectiveConnectionType(ect)
+                      .max_queuing_time.has_value());
 
     } else {
       VerifyDefaultParams(
@@ -249,18 +254,6 @@
   scoped_refptr<base::FieldTrial> trial =
       base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
 
-  std::map<std::string, std::string> params;
-  params["http_rtt_multiplier"] = "20";
-  ASSERT_TRUE(
-      base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
-          kTrialName, kGroupName, params));
-
-  std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
-  feature_list->RegisterFieldTrialOverride(
-      features::kUnthrottleRequestsAfterLongQueuingDelay.name,
-      base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
-  scoped_feature_list.InitWithFeatureList(std::move(feature_list));
-
   ResourceSchedulerParamsManager resource_scheduler_params_manager;
 
   for (int effective_connection_type = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
@@ -282,7 +275,7 @@
       EXPECT_TRUE(resource_scheduler_params_manager
                       .GetParamsForEffectiveConnectionType(ect)
                       .delay_requests_on_multiplexed_connections);
-      EXPECT_EQ(typical_http_rtt * 20,
+      EXPECT_EQ(typical_http_rtt * kHttpRttMultiplierForQueuingDuration,
                 resource_scheduler_params_manager
                     .GetParamsForEffectiveConnectionType(ect)
                     .max_queuing_time);
@@ -326,9 +319,10 @@
       EXPECT_FALSE(resource_scheduler_params_manager
                        .GetParamsForEffectiveConnectionType(ect)
                        .delay_requests_on_multiplexed_connections);
-      EXPECT_FALSE(resource_scheduler_params_manager
-                       .GetParamsForEffectiveConnectionType(ect)
-                       .max_queuing_time.has_value());
+      EXPECT_EQ(kUpperBoundQueuingDuration,
+                resource_scheduler_params_manager
+                    .GetParamsForEffectiveConnectionType(ect)
+                    .max_queuing_time);
     }
   }
 }
@@ -393,9 +387,9 @@
       EXPECT_TRUE(resource_scheduler_params_manager
                       .GetParamsForEffectiveConnectionType(ect)
                       .delay_requests_on_multiplexed_connections);
-      EXPECT_FALSE(resource_scheduler_params_manager
-                       .GetParamsForEffectiveConnectionType(ect)
-                       .max_queuing_time.has_value());
+      EXPECT_TRUE(resource_scheduler_params_manager
+                      .GetParamsForEffectiveConnectionType(ect)
+                      .max_queuing_time.has_value());
 
     } else if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_3G) {
       EXPECT_EQ(12u, resource_scheduler_params_manager
@@ -407,9 +401,9 @@
       EXPECT_TRUE(resource_scheduler_params_manager
                       .GetParamsForEffectiveConnectionType(ect)
                       .delay_requests_on_multiplexed_connections);
-      EXPECT_FALSE(resource_scheduler_params_manager
-                       .GetParamsForEffectiveConnectionType(ect)
-                       .max_queuing_time.has_value());
+      EXPECT_TRUE(resource_scheduler_params_manager
+                      .GetParamsForEffectiveConnectionType(ect)
+                      .max_queuing_time.has_value());
 
     } else if (effective_connection_type == net::EFFECTIVE_CONNECTION_TYPE_4G) {
       EXPECT_EQ(14u, resource_scheduler_params_manager
@@ -421,9 +415,9 @@
       EXPECT_FALSE(resource_scheduler_params_manager
                        .GetParamsForEffectiveConnectionType(ect)
                        .delay_requests_on_multiplexed_connections);
-      EXPECT_FALSE(resource_scheduler_params_manager
-                       .GetParamsForEffectiveConnectionType(ect)
-                       .max_queuing_time.has_value());
+      EXPECT_TRUE(resource_scheduler_params_manager
+                      .GetParamsForEffectiveConnectionType(ect)
+                      .max_queuing_time.has_value());
 
     } else {
       VerifyDefaultParams(resource_scheduler_params_manager, ect);
@@ -576,10 +570,10 @@
                 .GetParamsForEffectiveConnectionType(
                     net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G)
                 .non_delayable_weight);
-  EXPECT_FALSE(resource_scheduler_params_manager
-                   .GetParamsForEffectiveConnectionType(
-                       net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G)
-                   .max_queuing_time.has_value());
+  EXPECT_TRUE(resource_scheduler_params_manager
+                  .GetParamsForEffectiveConnectionType(
+                      net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G)
+                  .max_queuing_time.has_value());
 
   VerifyDefaultParams(resource_scheduler_params_manager,
                       net::EFFECTIVE_CONNECTION_TYPE_2G);
@@ -593,10 +587,10 @@
                                          .GetParamsForEffectiveConnectionType(
                                              net::EFFECTIVE_CONNECTION_TYPE_3G)
                                          .non_delayable_weight);
-  EXPECT_FALSE(resource_scheduler_params_manager
-                   .GetParamsForEffectiveConnectionType(
-                       net::EFFECTIVE_CONNECTION_TYPE_3G)
-                   .max_queuing_time.has_value());
+  EXPECT_TRUE(resource_scheduler_params_manager
+                  .GetParamsForEffectiveConnectionType(
+                      net::EFFECTIVE_CONNECTION_TYPE_3G)
+                  .max_queuing_time.has_value());
 
   VerifyDefaultParams(resource_scheduler_params_manager,
                       net::EFFECTIVE_CONNECTION_TYPE_4G);
diff --git a/services/network/resource_scheduler_unittest.cc b/services/network/resource_scheduler_unittest.cc
index c436b87..ffc9a0d 100644
--- a/services/network/resource_scheduler_unittest.cc
+++ b/services/network/resource_scheduler_unittest.cc
@@ -1652,9 +1652,6 @@
 // Verify that the timer to dispatch long queued requests starts only when there
 // are requests in-flight.
 TEST_F(ResourceSchedulerTest, MaxQueuingDelayTimerRunsOnRequestSchedule) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitFromCommandLine(
-      features::kUnthrottleRequestsAfterLongQueuingDelay.name, "");
   base::TimeDelta max_queuing_time = base::TimeDelta::FromSeconds(15);
   InitializeMaxQueuingDelayExperiment(max_queuing_time);
   network_quality_estimator_.SetAndNotifyObserversOfEffectiveConnectionType(
diff --git a/services/tracing/perfetto/json_trace_exporter.cc b/services/tracing/perfetto/json_trace_exporter.cc
index 35e2b17..1f4db61 100644
--- a/services/tracing/perfetto/json_trace_exporter.cc
+++ b/services/tracing/perfetto/json_trace_exporter.cc
@@ -296,6 +296,8 @@
   dict->SetInteger("data_sources_seen", trace_stats.data_sources_seen());
   dict->SetInteger("tracing_sessions", trace_stats.tracing_sessions());
   dict->SetInteger("total_buffers", trace_stats.total_buffers());
+  dict->SetInteger("chunks_discarded", trace_stats.chunks_discarded());
+  dict->SetInteger("patches_discarded", trace_stats.patches_discarded());
   auto buf_list = std::make_unique<base::ListValue>();
   for (const auto& buf_stats : trace_stats.buffer_stats()) {
     base::Value buf_value(base::Value::Type::DICTIONARY);
diff --git a/services/tracing/public/mojom/OWNERS b/services/tracing/public/mojom/OWNERS
index 2c44a46..ae29a36aa 100644
--- a/services/tracing/public/mojom/OWNERS
+++ b/services/tracing/public/mojom/OWNERS
@@ -1,6 +1,6 @@
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
-per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
 per-file *.typemap=set noparent
 per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/services/tracing/public/mojom/chrome_config_struct_traits.cc b/services/tracing/public/mojom/chrome_config_mojom_traits.cc
similarity index 88%
rename from services/tracing/public/mojom/chrome_config_struct_traits.cc
rename to services/tracing/public/mojom/chrome_config_mojom_traits.cc
index 5280078..50790115 100644
--- a/services/tracing/public/mojom/chrome_config_struct_traits.cc
+++ b/services/tracing/public/mojom/chrome_config_mojom_traits.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 "services/tracing/public/mojom/chrome_config_struct_traits.h"
+#include "services/tracing/public/mojom/chrome_config_mojom_traits.h"
 
 #include <utility>
 
diff --git a/services/tracing/public/mojom/chrome_config_struct_traits.h b/services/tracing/public/mojom/chrome_config_mojom_traits.h
similarity index 80%
rename from services/tracing/public/mojom/chrome_config_struct_traits.h
rename to services/tracing/public/mojom/chrome_config_mojom_traits.h
index e6c4437..e033a50 100644
--- a/services/tracing/public/mojom/chrome_config_struct_traits.h
+++ b/services/tracing/public/mojom/chrome_config_mojom_traits.h
@@ -5,8 +5,8 @@
 // This defines mappings from mojom IPC representations to their native perfetto
 // equivalents.
 
-#ifndef SERVICES_TRACING_PUBLIC_MOJOM_CHROME_CONFIG_STRUCT_TRAITS_H_
-#define SERVICES_TRACING_PUBLIC_MOJOM_CHROME_CONFIG_STRUCT_TRAITS_H_
+#ifndef SERVICES_TRACING_PUBLIC_MOJOM_CHROME_CONFIG_MOJOM_TRAITS_H_
+#define SERVICES_TRACING_PUBLIC_MOJOM_CHROME_CONFIG_MOJOM_TRAITS_H_
 
 #include <string>
 
@@ -27,4 +27,4 @@
                    perfetto::ChromeConfig* out);
 };
 }  // namespace mojo
-#endif  // SERVICES_TRACING_PUBLIC_MOJOM_CHROME_CONFIG_STRUCT_TRAITS_H_
+#endif  // SERVICES_TRACING_PUBLIC_MOJOM_CHROME_CONFIG_MOJOM_TRAITS_H_
diff --git a/services/tracing/public/mojom/commit_data_request_struct_traits.cc b/services/tracing/public/mojom/commit_data_request_mojom_traits.cc
similarity index 96%
rename from services/tracing/public/mojom/commit_data_request_struct_traits.cc
rename to services/tracing/public/mojom/commit_data_request_mojom_traits.cc
index 6446ea8..ee6fc85 100644
--- a/services/tracing/public/mojom/commit_data_request_struct_traits.cc
+++ b/services/tracing/public/mojom/commit_data_request_mojom_traits.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 "services/tracing/public/mojom/commit_data_request_struct_traits.h"
+#include "services/tracing/public/mojom/commit_data_request_mojom_traits.h"
 
 #include <utility>
 
diff --git a/services/tracing/public/mojom/commit_data_request_struct_traits.h b/services/tracing/public/mojom/commit_data_request_mojom_traits.h
similarity index 93%
rename from services/tracing/public/mojom/commit_data_request_struct_traits.h
rename to services/tracing/public/mojom/commit_data_request_mojom_traits.h
index 216a50d..8b5c468 100644
--- a/services/tracing/public/mojom/commit_data_request_struct_traits.h
+++ b/services/tracing/public/mojom/commit_data_request_mojom_traits.h
@@ -5,8 +5,8 @@
 // This defines mappings from mojom IPC representations to their native perfetto
 // equivalents.
 
-#ifndef SERVICES_TRACING_PUBLIC_MOJOM_COMMIT_DATA_REQUEST_STRUCT_TRAITS_H_
-#define SERVICES_TRACING_PUBLIC_MOJOM_COMMIT_DATA_REQUEST_STRUCT_TRAITS_H_
+#ifndef SERVICES_TRACING_PUBLIC_MOJOM_COMMIT_DATA_REQUEST_MOJOM_TRAITS_H_
+#define SERVICES_TRACING_PUBLIC_MOJOM_COMMIT_DATA_REQUEST_MOJOM_TRAITS_H_
 
 #include <string>
 #include <vector>
@@ -107,4 +107,4 @@
                    perfetto::CommitDataRequest* out);
 };
 }  // namespace mojo
-#endif  // SERVICES_TRACING_PUBLIC_MOJOM_COMMIT_DATA_REQUEST_STRUCT_TRAITS_H_
+#endif  // SERVICES_TRACING_PUBLIC_MOJOM_COMMIT_DATA_REQUEST_MOJOM_TRAITS_H_
diff --git a/services/tracing/public/mojom/data_source_config_struct_traits.cc b/services/tracing/public/mojom/data_source_config_mojom_traits.cc
similarity index 86%
rename from services/tracing/public/mojom/data_source_config_struct_traits.cc
rename to services/tracing/public/mojom/data_source_config_mojom_traits.cc
index bd1ca60..11f8d894 100644
--- a/services/tracing/public/mojom/data_source_config_struct_traits.cc
+++ b/services/tracing/public/mojom/data_source_config_mojom_traits.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "services/tracing/public/mojom/data_source_config_struct_traits.h"
+#include "services/tracing/public/mojom/data_source_config_mojom_traits.h"
 
 #include <utility>
 
-#include "services/tracing/public/mojom/chrome_config_struct_traits.h"
+#include "services/tracing/public/mojom/chrome_config_mojom_traits.h"
 
 namespace mojo {
 bool StructTraits<tracing::mojom::DataSourceConfigDataView,
diff --git a/services/tracing/public/mojom/data_source_config_struct_traits.h b/services/tracing/public/mojom/data_source_config_mojom_traits.h
similarity index 87%
rename from services/tracing/public/mojom/data_source_config_struct_traits.h
rename to services/tracing/public/mojom/data_source_config_mojom_traits.h
index 9a2fda2e..e749282 100644
--- a/services/tracing/public/mojom/data_source_config_struct_traits.h
+++ b/services/tracing/public/mojom/data_source_config_mojom_traits.h
@@ -5,8 +5,8 @@
 // This defines mappings from mojom IPC representations to their native perfetto
 // equivalents.
 
-#ifndef SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_CONFIG_STRUCT_TRAITS_H_
-#define SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_CONFIG_STRUCT_TRAITS_H_
+#ifndef SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_CONFIG_MOJOM_TRAITS_H_
+#define SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_CONFIG_MOJOM_TRAITS_H_
 
 #include <string>
 
@@ -45,4 +45,4 @@
                    perfetto::DataSourceConfig* out);
 };
 }  // namespace mojo
-#endif  // SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_CONFIG_STRUCT_TRAITS_H_
+#endif  // SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_CONFIG_MOJOM_TRAITS_H_
diff --git a/services/tracing/public/mojom/data_source_descriptor_struct_traits.cc b/services/tracing/public/mojom/data_source_descriptor_mojom_traits.cc
similarity index 88%
rename from services/tracing/public/mojom/data_source_descriptor_struct_traits.cc
rename to services/tracing/public/mojom/data_source_descriptor_mojom_traits.cc
index ed48852..70bdb076 100644
--- a/services/tracing/public/mojom/data_source_descriptor_struct_traits.cc
+++ b/services/tracing/public/mojom/data_source_descriptor_mojom_traits.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 "services/tracing/public/mojom/data_source_descriptor_struct_traits.h"
+#include "services/tracing/public/mojom/data_source_descriptor_mojom_traits.h"
 
 #include <utility>
 
diff --git a/services/tracing/public/mojom/data_source_descriptor_struct_traits.h b/services/tracing/public/mojom/data_source_descriptor_mojom_traits.h
similarity index 86%
rename from services/tracing/public/mojom/data_source_descriptor_struct_traits.h
rename to services/tracing/public/mojom/data_source_descriptor_mojom_traits.h
index b6b09ed7..c440766 100644
--- a/services/tracing/public/mojom/data_source_descriptor_struct_traits.h
+++ b/services/tracing/public/mojom/data_source_descriptor_mojom_traits.h
@@ -5,8 +5,8 @@
 // This defines mappings from mojom IPC representations to their native perfetto
 // equivalents.
 
-#ifndef SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_DESCRIPTOR_STRUCT_TRAITS_H_
-#define SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_DESCRIPTOR_STRUCT_TRAITS_H_
+#ifndef SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_DESCRIPTOR_MOJOM_TRAITS_H_
+#define SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_DESCRIPTOR_MOJOM_TRAITS_H_
 
 #include <string>
 
@@ -30,4 +30,4 @@
                    perfetto::DataSourceDescriptor* out);
 };
 }  // namespace mojo
-#endif  // SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_DESCRIPTOR_STRUCT_TRAITS_H_
+#endif  // SERVICES_TRACING_PUBLIC_MOJOM_DATA_SOURCE_DESCRIPTOR_MOJOM_TRAITS_H_
diff --git a/services/tracing/public/mojom/perfetto_service.typemap b/services/tracing/public/mojom/perfetto_service.typemap
index 246cb23..20807443 100644
--- a/services/tracing/public/mojom/perfetto_service.typemap
+++ b/services/tracing/public/mojom/perfetto_service.typemap
@@ -6,20 +6,20 @@
   "//third_party/perfetto/include/perfetto/tracing/core/chrome_config.h",
 ]
 traits_headers = [
-  "//services/tracing/public/mojom/commit_data_request_struct_traits.h",
-  "//services/tracing/public/mojom/data_source_config_struct_traits.h",
-  "//services/tracing/public/mojom/data_source_descriptor_struct_traits.h",
-  "//services/tracing/public/mojom/chrome_config_struct_traits.h",
+  "//services/tracing/public/mojom/commit_data_request_mojom_traits.h",
+  "//services/tracing/public/mojom/data_source_config_mojom_traits.h",
+  "//services/tracing/public/mojom/data_source_descriptor_mojom_traits.h",
+  "//services/tracing/public/mojom/chrome_config_mojom_traits.h",
 ]
 sources = [
-  "//services/tracing/public/mojom/chrome_config_struct_traits.cc",
-  "//services/tracing/public/mojom/chrome_config_struct_traits.h",
-  "//services/tracing/public/mojom/commit_data_request_struct_traits.cc",
-  "//services/tracing/public/mojom/commit_data_request_struct_traits.h",
-  "//services/tracing/public/mojom/data_source_config_struct_traits.cc",
-  "//services/tracing/public/mojom/data_source_config_struct_traits.h",
-  "//services/tracing/public/mojom/data_source_descriptor_struct_traits.cc",
-  "//services/tracing/public/mojom/data_source_descriptor_struct_traits.h",
+  "//services/tracing/public/mojom/chrome_config_mojom_traits.cc",
+  "//services/tracing/public/mojom/chrome_config_mojom_traits.h",
+  "//services/tracing/public/mojom/commit_data_request_mojom_traits.cc",
+  "//services/tracing/public/mojom/commit_data_request_mojom_traits.h",
+  "//services/tracing/public/mojom/data_source_config_mojom_traits.cc",
+  "//services/tracing/public/mojom/data_source_config_mojom_traits.h",
+  "//services/tracing/public/mojom/data_source_descriptor_mojom_traits.cc",
+  "//services/tracing/public/mojom/data_source_descriptor_mojom_traits.h",
 ]
 public_deps = [
   "//third_party/perfetto:libperfetto",
diff --git a/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter b/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter
index fcbf9f5..a817505 100644
--- a/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_webview_instrumentation_test_apk.filter
@@ -19,13 +19,8 @@
 -org.chromium.android_webview.test.AwContentsClientShouldInterceptRequestTest.testLoadDataUrlShouldTriggerShouldInterceptRequest
 -org.chromium.android_webview.test.AwContentsClientShouldInterceptRequestTest.testLoadDataWithBaseUrlTriggersShouldInterceptRequest
 
-# https://crbug.com/893568
--org.chromium.android_webview.test.AwContentsTest.testDownload
-
 # https://crbug.com/893572
 -org.chromium.android_webview.test.ClientOnPageStartedTest.testBrowserInitiatedRedirectHangingNavigation
--org.chromium.android_webview.test.ClientOnPageStartedTest.testNotCalledForDownloadContentDisposition
--org.chromium.android_webview.test.ClientOnPageStartedTest.testNotCalledForDownloadPdf
 -org.chromium.android_webview.test.ClientOnPageStartedTest.testRendererInitiatedRedirectHangingNavigation
 
 # https://crbug.com/893575
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index af2a381..00135ca21 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4983,28 +4983,6 @@
             ]
         }
     ],
-    "UnthrottleRequestsAfterLongQueuingDelay": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "UnthrottleRequestsAfterLongQueuingDelay",
-                    "params": {
-                        "http_rtt_multiplier": "30"
-                    },
-                    "enable_features": [
-                        "UnthrottleRequestsAfterLongQueuingDelay"
-                    ]
-                }
-            ]
-        }
-    ],
     "UpdateClientUseJSON": [
         {
             "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 67bb611c..3b668afe 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -160,6 +160,10 @@
 #endif
 };
 
+// Enable text snippets in URL fragments. https://crbug.com/919204.
+const base::Feature kTextFragmentAnchor{"TextFragmentAnchor",
+                                        base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables the site isolated Wasm code cache that is keyed on the resource URL
 // and the origin lock of the renderer that is requesting the resource. When
 // this flag is enabled, content/GeneratedCodeCache handles code cache requests.
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index d3c1132..5acf74f 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -47,6 +47,7 @@
     kServiceWorkerAggressiveCodeCache;
 BLINK_COMMON_EXPORT extern const base::Feature kStopInBackground;
 BLINK_COMMON_EXPORT extern const base::Feature kStopNonTimersInBackground;
+BLINK_COMMON_EXPORT extern const base::Feature kTextFragmentAnchor;
 BLINK_COMMON_EXPORT extern const base::Feature kWasmCodeCache;
 BLINK_COMMON_EXPORT extern const base::Feature kWritableFilesAPI;
 BLINK_COMMON_EXPORT extern const base::Feature kForbidSyncXHRInPageDismissal;
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom
index b963fed3..65ead71 100644
--- a/third_party/blink/public/platform/web_feature.mojom
+++ b/third_party/blink/public/platform/web_feature.mojom
@@ -2225,6 +2225,7 @@
   kV8UserActivation_HasBeenActive_AttributeGetter = 2785,
   kV8UserActivation_IsActive_AttributeGetter = 2786,
   kTextEncoderEncodeInto = 2787,
+  kInvalidBasicCardMethodData = 2788,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_layer_tree_view.h b/third_party/blink/public/platform/web_layer_tree_view.h
index fb2104a..9768ecb 100644
--- a/third_party/blink/public/platform/web_layer_tree_view.h
+++ b/third_party/blink/public/platform/web_layer_tree_view.h
@@ -143,6 +143,11 @@
     return nullptr;
   }
 
+  // Start and Stop defering commits to the compositor. Defering commits
+  // allows document lifecycle updates but does not commit the layer tree.
+  virtual void StartDeferringCommits() {}
+  virtual void StopDeferringCommits() {}
+
   struct ViewportLayers {
     cc::ElementId overscroll_elasticity_element_id;
     scoped_refptr<cc::Layer> page_scale;
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
index 3d0806a..f0aada9 100644
--- a/third_party/blink/public/platform/web_runtime_features.h
+++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -120,6 +120,8 @@
   BLINK_PLATFORM_EXPORT static void EnableMediaCapture(bool);
   BLINK_PLATFORM_EXPORT static void EnableMediaSession(bool);
   BLINK_PLATFORM_EXPORT static void EnableMiddleClickAutoscroll(bool);
+  BLINK_PLATFORM_EXPORT static void EnableMimeHandlerViewInCrossProcessFrame(
+      bool);
   BLINK_PLATFORM_EXPORT static void EnableModernMediaControls(bool);
   BLINK_PLATFORM_EXPORT static void EnableNavigatorContentUtils(bool);
   BLINK_PLATFORM_EXPORT static void EnableNetInfoDownlinkMax(bool);
@@ -169,6 +171,7 @@
   BLINK_PLATFORM_EXPORT static void EnableSerial(bool);
   BLINK_PLATFORM_EXPORT static void EnableSharedArrayBuffer(bool);
   BLINK_PLATFORM_EXPORT static void EnableSharedWorker(bool);
+  BLINK_PLATFORM_EXPORT static void EnableTextFragmentAnchor(bool);
   BLINK_PLATFORM_EXPORT static void EnableTouchEventFeatureDetection(bool);
   BLINK_PLATFORM_EXPORT static void EnableUserActivationSameOriginVisibility(
       bool);
@@ -202,7 +205,6 @@
   EnableSendBeaconThrowForBlobWithNonSimpleType(bool);
   BLINK_PLATFORM_EXPORT static void EnableBackgroundVideoTrackOptimization(
       bool);
-  BLINK_PLATFORM_EXPORT static void EnableNewRemotePlaybackPipeline(bool);
   BLINK_PLATFORM_EXPORT static void EnableVideoFullscreenOrientationLock(bool);
   BLINK_PLATFORM_EXPORT static void EnableVideoRotateToFullscreen(bool);
   BLINK_PLATFORM_EXPORT static void EnableVideoFullscreenDetection(bool);
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS
index 9761c59..6d31d06d 100644
--- a/third_party/blink/renderer/core/DEPS
+++ b/third_party/blink/renderer/core/DEPS
@@ -2,6 +2,7 @@
     "+base/atomic_sequence_num.h",
     "+base/files/file.h",
     "+base/memory/scoped_refptr.h",
+    "+base/metrics/field_trial_params.h",
     "+base/strings/stringprintf.h",
     "+base/synchronization/waitable_event.h",
     "+base/task/sequence_manager/task_time_observer.h",
diff --git a/third_party/blink/renderer/core/clipboard/system_clipboard.h b/third_party/blink/renderer/core/clipboard/system_clipboard.h
index ca65a4414..091e1b6 100644
--- a/third_party/blink/renderer/core/clipboard/system_clipboard.h
+++ b/third_party/blink/renderer/core/clipboard/system_clipboard.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/public/mojom/clipboard/clipboard.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
@@ -19,6 +20,8 @@
 // This singleton provides read/write access to the system clipboard,
 // mediating between core classes and mojom::ClipboardHost.
 class CORE_EXPORT SystemClipboard {
+  USING_FAST_MALLOC(SystemClipboard);
+
  public:
   static SystemClipboard& GetInstance();
 
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 66272331..b019839 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2047,7 +2047,8 @@
   DCHECK(GetDocument().InStyleRecalc());
 
   ComputedStyle* style = MutableComputedStyle();
-  if (!style && !ChildNeedsReattachLayoutTree()) {
+  if ((!style || style->Display() == EDisplay::kNone) &&
+      !ChildNeedsReattachLayoutTree()) {
     Node::AttachLayoutTree(context);
     return;
   }
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder.cc b/third_party/blink/renderer/core/dom/layout_tree_builder.cc
index 28d64ae1..c6cc46b8 100644
--- a/third_party/blink/renderer/core/dom/layout_tree_builder.cc
+++ b/third_party/blink/renderer/core/dom/layout_tree_builder.cc
@@ -78,6 +78,7 @@
     : LayoutTreeBuilder(element, nullptr), style_(style) {
   DCHECK(element.CanParticipateInFlatTree());
   DCHECK(style_);
+  DCHECK(!style_->IsEnsuredInDisplayNone());
   // TODO(ecobos): Move the first-letter logic inside ParentLayoutObject too?
   // It's an extra (unnecessary) check for text nodes, though.
   if (element.IsFirstLetterPseudoElement()) {
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
index 11a3fa6..2f0c6d09 100644
--- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -1155,6 +1155,8 @@
     HTMLPlugInElement& plugin_element,
     const KURL& resource_url,
     const String& suggesed_mime_type) {
+  if (!RuntimeEnabledFeatures::MimeHandlerViewInCrossProcessFrameEnabled())
+    return false;
   return web_frame_->Client()->IsPluginHandledExternally(
       &plugin_element, resource_url, suggesed_mime_type);
 }
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 34812f3..d972bff 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3450,4 +3450,14 @@
   scoped_defer_main_frame_update_ = layer_tree_view_->DeferMainFrameUpdate();
 }
 
+void WebViewImpl::StartDeferringCommits() {
+  if (layer_tree_view_)
+    layer_tree_view_->StartDeferringCommits();
+}
+
+void WebViewImpl::StopDeferringCommits() {
+  if (layer_tree_view_)
+    layer_tree_view_->StopDeferringCommits();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
index 16d50a57..60d70f5 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -390,7 +390,9 @@
       const IntRect& caret_bounds_in_document,
       bool zoom_into_legible_scale);
 
-  void StopDeferringCommits() { scoped_defer_main_frame_update_.reset(); }
+  void StopDeferringMainFrameUpdate() {
+    scoped_defer_main_frame_update_.reset();
+  }
 
   // This function checks the element ids of ScrollableAreas only and returns
   // the equivalent DOM Node if such exists.
@@ -399,6 +401,9 @@
 
   void DeferMainFrameUpdateForTesting();
 
+  void StartDeferringCommits();
+  void StopDeferringCommits();
+
  private:
   FRIEND_TEST_ALL_PREFIXES(WebFrameTest, DivScrollIntoEditableTest);
   FRIEND_TEST_ALL_PREFIXES(WebFrameTest,
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 38d835a5..73a5ea3 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -30,9 +30,12 @@
 #include <memory>
 #include <utility>
 
+#include "base/feature_list.h"
 #include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial_params.h"
 #include "base/numerics/safe_conversions.h"
 #include "cc/layers/picture_layer.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/public/platform/web_rect.h"
 #include "third_party/blink/public/platform/web_scroll_into_view_params.h"
@@ -191,6 +194,25 @@
   }
 }
 
+// Default value and parameter name for how long we want to delay the
+// compositor commit beyond the start of document lifdecycle updates to avoid
+// flash between navigations. The delay should be small enough so that it won't
+// confuse users expecting a new page to appear after navigation and the omnibar
+// has updated the url display.
+constexpr int kAvoidFlashCommitDelayDefaultInMs = 200;
+constexpr char kAvoidFlashCommitDelayParameterName[] = "commit_delay";
+
+// Get the field trial parameter value for AvoidFlashBetweenNavigation.
+base::TimeDelta GetCommitDelayForAvoidFlashBetweenNavigation() {
+  DCHECK(base::FeatureList::IsEnabled(
+      blink::features::kAvoidFlashBetweenNavigation));
+  return base::TimeDelta::FromMilliseconds(
+      base::GetFieldTrialParamByFeatureAsInt(
+          blink::features::kAvoidFlashBetweenNavigation,
+          kAvoidFlashCommitDelayParameterName,
+          kAvoidFlashCommitDelayDefaultInMs));
+}
+
 }  // namespace
 
 // The maximum number of updatePlugins iterations that should be done before
@@ -4046,10 +4068,37 @@
 
   SetupRenderThrottling();
   UpdateRenderThrottlingStatus(hidden_for_throttling_, subtree_throttled_);
+
   // The compositor will "defer commits" for the main frame until we
   // explicitly request them.
-  if (GetFrame().IsMainFrame())
-    GetFrame().GetPage()->GetChromeClient().BeginLifecycleUpdates();
+  if (!GetFrame().IsMainFrame())
+    return;
+
+  // Determine if we want to defer commits to the compositor once lifecycle
+  // updates start. Doing so allows us to update the page lifecycle but not
+  // present the results to screen until we see first contentful paint is
+  // available or until a timer expires.
+  // This is enabled only if kAvoidFlashBetweenNavigation is enabled, and
+  // the document loading is a regular HTML served over HTTP/HTTPs.
+  Document* document = GetFrame().GetDocument();
+  if (base::FeatureList::IsEnabled(
+          blink::features::kAvoidFlashBetweenNavigation) &&
+      document && document->Url().ProtocolIsInHTTPFamily() &&
+      document->IsHTMLDocument()) {
+    GetFrame()
+        .GetTaskRunner(TaskType::kInternalDefault)
+        ->PostDelayedTask(FROM_HERE,
+                          WTF::Bind(&LocalFrameView::DeferredCommitsTimerFired,
+                                    WrapWeakPersistent(this)),
+                          GetCommitDelayForAvoidFlashBetweenNavigation());
+    GetFrame().GetPage()->GetChromeClient().StartDeferringCommits();
+  }
+  GetFrame().GetPage()->GetChromeClient().BeginLifecycleUpdates();
+}
+
+void LocalFrameView::DeferredCommitsTimerFired() {
+  if (GetFrame().GetPage())
+    GetFrame().GetPage()->GetChromeClient().StopDeferringCommits();
 }
 
 void LocalFrameView::SetInitialViewportSize(const IntSize& viewport_size) {
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h
index 0841f3a..7cf80d8b 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.h
+++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -768,6 +768,10 @@
   void SetupPrintContext();
   void ClearPrintContext();
 
+  // The callback invoked when the timer triggers to stop deferring commits
+  // on navigation.
+  void DeferredCommitsTimerFired();
+
   // Returns whether the lifecycle was succesfully updated to the
   // target state.
   bool UpdateLifecyclePhases(DocumentLifecycle::LifecycleState target_state,
diff --git a/third_party/blink/renderer/core/html/track/text_track_container.cc b/third_party/blink/renderer/core/html/track/text_track_container.cc
index feded82..96f2cdc 100644
--- a/third_party/blink/renderer/core/html/track/text_track_container.cc
+++ b/third_party/blink/renderer/core/html/track/text_track_container.cc
@@ -108,8 +108,7 @@
   // for lack of per-spec vh/vw support) but the whole media element is used
   // for cue rendering. This is inconsistent. See also the somewhat related
   // spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=28105
-  LayoutSize video_size =
-      ToLayoutVideo(*media_layout_object).ReplacedContentRect().Size();
+  LayoutSize video_size = ToLayoutBox(media_layout_object)->ContentSize();
   LayoutUnit smallest_dimension =
       std::min(video_size.Height(), video_size.Width());
   float font_size = smallest_dimension * 0.05f;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index 06b0e6f..4a840f8d 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -103,6 +103,8 @@
                      const cc::OverscrollBehavior&) override {}
 
   void BeginLifecycleUpdates() override {}
+  void StartDeferringCommits() override {}
+  void StopDeferringCommits() override {}
 
   bool HadFormInteraction() const override { return false; }
 
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h
index b7f82bd..cc6a2f1 100644
--- a/third_party/blink/renderer/core/page/chrome_client.h
+++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -138,6 +138,8 @@
   virtual bool HadFormInteraction() const = 0;
 
   virtual void BeginLifecycleUpdates() = 0;
+  virtual void StartDeferringCommits() = 0;
+  virtual void StopDeferringCommits() = 0;
 
   // Start a system drag and drop operation.
   virtual void StartDragging(LocalFrame*,
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc
index c6cc290..99da786 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -931,13 +931,21 @@
 }
 
 void ChromeClientImpl::BeginLifecycleUpdates() {
-  web_view_->StopDeferringCommits();
+  web_view_->StopDeferringMainFrameUpdate();
   // The WidgetClient is null for some WebViews, in which case they can not
   // composite.
   if (web_view_->WidgetClient())
     web_view_->WidgetClient()->ScheduleAnimation();
 }
 
+void ChromeClientImpl::StartDeferringCommits() {
+  web_view_->StartDeferringCommits();
+}
+
+void ChromeClientImpl::StopDeferringCommits() {
+  web_view_->StopDeferringCommits();
+}
+
 cc::EventListenerProperties ChromeClientImpl::EventListenerProperties(
     LocalFrame* frame,
     cc::EventListenerClass event_class) const {
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.h b/third_party/blink/renderer/core/page/chrome_client_impl.h
index b949ed7..30e52bc 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.h
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -66,6 +66,8 @@
   void TakeFocus(WebFocusType) override;
   void FocusedNodeChanged(Node* from_node, Node* to_node) override;
   void BeginLifecycleUpdates() override;
+  void StartDeferringCommits() override;
+  void StopDeferringCommits() override;
   bool HadFormInteraction() const override;
   void StartDragging(LocalFrame*,
                      const WebDragData&,
diff --git a/third_party/blink/renderer/core/streams/queue_with_sizes_test.cc b/third_party/blink/renderer/core/streams/queue_with_sizes_test.cc
index 5eeb46cb..dc6a6b82 100644
--- a/third_party/blink/renderer/core/streams/queue_with_sizes_test.cc
+++ b/third_party/blink/renderer/core/streams/queue_with_sizes_test.cc
@@ -60,11 +60,11 @@
   EXPECT_TRUE(queue->IsEmpty());
 }
 
-INSTANTIATE_TEST_CASE_P(,
-                        QueueWithSizesBadSizeTest,
-                        Values(-1,
-                               std::numeric_limits<double>::quiet_NaN(),
-                               std::numeric_limits<double>::infinity()));
+INSTANTIATE_TEST_SUITE_P(,
+                         QueueWithSizesBadSizeTest,
+                         Values(-1,
+                                std::numeric_limits<double>::quiet_NaN(),
+                                std::numeric_limits<double>::infinity()));
 
 TEST(QueueWithSizesTest, DequeueReturnsSameObject) {
   V8TestingScope scope;
diff --git a/third_party/blink/renderer/core/streams/writable_stream_test.cc b/third_party/blink/renderer/core/streams/writable_stream_test.cc
index 6eaff0d..fe69ef3 100644
--- a/third_party/blink/renderer/core/streams/writable_stream_test.cc
+++ b/third_party/blink/renderer/core/streams/writable_stream_test.cc
@@ -116,7 +116,7 @@
   EXPECT_EQ(ToCoreString(result.As<v8::String>()), "a");
 }
 
-INSTANTIATE_TEST_CASE_P(, WritableStreamTest, ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(, WritableStreamTest, ::testing::Values(false, true));
 
 }  // namespace
 
diff --git a/third_party/blink/renderer/modules/payments/can_make_payment_test.cc b/third_party/blink/renderer/modules/payments/can_make_payment_test.cc
index 21860ed..07946ba 100644
--- a/third_party/blink/renderer/modules/payments/can_make_payment_test.cc
+++ b/third_party/blink/renderer/modules/payments/can_make_payment_test.cc
@@ -225,10 +225,10 @@
   EXPECT_EQ("true", captor);
 }
 
-INSTANTIATE_TEST_CASE_P(ProgrammaticCanMakePaymentTest,
-                        CanMakePaymentTest,
-                        ::testing::Values(HasEnrolledInstrumentEnabled::kYes,
-                                          HasEnrolledInstrumentEnabled::kNo));
+INSTANTIATE_TEST_SUITE_P(ProgrammaticCanMakePaymentTest,
+                         CanMakePaymentTest,
+                         ::testing::Values(HasEnrolledInstrumentEnabled::kYes,
+                                           HasEnrolledInstrumentEnabled::kNo));
 
 }  // namespace
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc
index 49bedb1e..791c248 100644
--- a/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -494,7 +494,8 @@
                                       output->supported_types, exception_state);
 }
 
-void StringifyAndParseMethodSpecificData(const String& supported_method,
+void StringifyAndParseMethodSpecificData(ExecutionContext& execution_context,
+                                         const String& supported_method,
                                          const ScriptValue& input,
                                          PaymentMethodDataPtr& output,
                                          ExceptionState& exception_state) {
@@ -527,10 +528,14 @@
     if (exception_state.HadException())
       exception_state.ClearException();
   }
+
   if (supported_method == "basic-card") {
     SetBasicCardMethodData(input, output, exception_state);
-    if (exception_state.HadException())
+    if (exception_state.HadException()) {
+      UseCounter::Count(&execution_context,
+                        WebFeature::kInvalidBasicCardMethodData);
       exception_state.ClearException();
+    }
   }
 }
 
@@ -610,7 +615,7 @@
 
     if (modifier->hasData() && !modifier->data().IsEmpty()) {
       StringifyAndParseMethodSpecificData(
-          modifier->supportedMethod(), modifier->data(),
+          execution_context, modifier->supportedMethod(), modifier->data(),
           output.back()->method_data, exception_state);
     } else {
       output.back()->method_data->stringified_data = "";
@@ -746,8 +751,8 @@
     if (payment_method_data->hasData() &&
         !payment_method_data->data().IsEmpty()) {
       StringifyAndParseMethodSpecificData(
-          payment_method_data->supportedMethod(), payment_method_data->data(),
-          output.back(), exception_state);
+          execution_context, payment_method_data->supportedMethod(),
+          payment_method_data->data(), output.back(), exception_state);
     } else {
       output.back()->stringified_data = "";
     }
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc b/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
index 5464f63..13153e5 100644
--- a/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
+++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
@@ -359,7 +359,6 @@
 }
 
 TEST_F(RemotePlaybackTest, IsListening) {
-  ScopedNewRemotePlaybackPipelineForTest new_remote_playback_pipeline(true);
   V8TestingScope scope;
 
   auto page_holder = DummyPageHolder::Create();
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
index 5258667f..79cd453 100644
--- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -247,6 +247,10 @@
   RuntimeEnabledFeatures::SetMediaSessionEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnableMimeHandlerViewInCrossProcessFrame(bool enable) {
+  RuntimeEnabledFeatures::SetMimeHandlerViewInCrossProcessFrameEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnableModernMediaControls(bool enable) {
   RuntimeEnabledFeatures::SetModernMediaControlsEnabled(enable);
 }
@@ -420,6 +424,10 @@
   RuntimeEnabledFeatures::SetSharedWorkerEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnableTextFragmentAnchor(bool enable) {
+  RuntimeEnabledFeatures::SetTextFragmentIdentifiersEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnablePreciseMemoryInfo(bool enable) {
   RuntimeEnabledFeatures::SetPreciseMemoryInfoEnabled(enable);
 }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 7b962b8..e1ff8729 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -836,7 +836,12 @@
       name: "MiddleClickAutoscroll",
       status: "test",
     },
+    // Specific mime-types such as PDF are rendered in cross-process frames.
     {
+      name: "MimeHandlerViewInCrossProcessFrame",
+    },
+    {
+
       name: "MobileLayoutTheme",
     },
     {
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index 743d3dc..a2c97ef 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -168,6 +168,7 @@
             # Feature list checking.
             'base::Feature.*',
             'base::FEATURE_.+',
+            "base::GetFieldTrial.*",
             'features::.+',
 
             # PartitionAlloc
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests
index bb2fca52..08d3207b 100644
--- a/third_party/blink/web_tests/SlowTests
+++ b/third_party/blink/web_tests/SlowTests
@@ -48,10 +48,8 @@
 crbug.com/24182 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cues-cuechange.html [ Slow ]
 crbug.com/24182 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cues-enter-exit.html [ Slow ]
 crbug.com/24182 media/controls/controls-cast-do-not-fade-out.html [ Slow ]
-crbug.com/24182 virtual/new-remote-playback-pipeline/media/controls/controls-cast-do-not-fade-out.html [ Slow ]
 crbug.com/24182 virtual/video-surface-layer/media/controls/controls-cast-do-not-fade-out.html [ Slow ]
 crbug.com/24182 media/controls/controls-cast-overlay-slow-fade.html [ Slow ]
-crbug.com/24182 virtual/new-remote-playback-pipeline/media/controls/controls-cast-overlay-slow-fade.html [ Slow ]
 crbug.com/24182 virtual/video-surface-layer/media/controls/controls-cast-overlay-slow-fade.html [ Slow ]
 crbug.com/24182 svg/filters/big-sized-filter.svg [ Slow ]
 crbug.com/24182 tables/mozilla/other/slashlogo.html [ Slow ]
@@ -249,7 +247,6 @@
 
 # Media controls tests have to wait for panel to fade out.
 crbug.com/722825 media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Slow ]
-crbug.com/722825 virtual/new-remote-playback-pipeline/media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Slow ]
 
 crbug.com/719298 fast/dnd/dropEffect-for-effectAllowed.html [ Slow ]
 
@@ -300,7 +297,6 @@
 crbug.com/779956 [ Linux ] external/wpt/offscreen-canvas/drawing-images-to-the-canvas/2d.drawImage.zerosource.worker.html [ Slow ]
 
 crbug.com/793771 media/controls/modern/scrubbing.html [ Slow ]
-crbug.com/793771 virtual/new-remote-playback-pipeline/media/controls/modern/scrubbing.html [ Slow ]
 crbug.com/793771 virtual/video-surface-layer/media/controls/modern/scrubbing.html [ Slow ]
 
 # These tests need to do many iterations and so can't be fast.
@@ -387,7 +383,6 @@
 crbug.com/864887 [ Mac ] fast/scroll-snap/snaps-after-scrollbar-scrolling.html [ Slow ]
 
 crbug.com/865262 [ Mac ] media/controls/text-track-menu-pointer-selection.html [ Slow ]
-crbug.com/865262 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/text-track-menu-pointer-selection.html [ Slow ]
 crbug.com/876050 [ Mac ] virtual/video-surface-layer/media/controls/text-track-menu-pointer-selection.html [ Slow ]
 
 crbug.com/910627 webexposed/global-interface-listing-shared-worker.html [ Slow ]
@@ -1119,8 +1114,6 @@
 crbug.com/874695 virtual/mouseevent_fractional/fast/events/middleClickAutoscroll-nested-divs-forbidden.html [ Slow ]
 crbug.com/874695 virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-click.html [ Slow ]
 crbug.com/874695 virtual/mouseevent_fractional/fast/events/touch/touch-slider-no-js-touch-listener.html [ Slow ]
-crbug.com/874695 virtual/new-remote-playback-pipeline/http/tests/media/controls/toggle-class-with-state-source-buffer.html [ Slow ]
-crbug.com/874695 virtual/new-remote-playback-pipeline/media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Slow ]
 crbug.com/874695 virtual/origin-policy/external/wpt/origin-policy/origin-policy.https.tentative.html [ Slow ]
 crbug.com/874695 virtual/outofblink-cors/external/wpt/fetch/api/abort/general.any.sharedworker.html [ Slow ]
 crbug.com/874695 virtual/outofblink-cors/external/wpt/fetch/api/abort/general.any.worker.html [ Slow ]
@@ -1578,7 +1571,6 @@
 crbug.com/912364 [ Mac ] virtual/user-activation-v2/fast/events/no-fake-mousemove.html [ Slow ]
 crbug.com/914981 [ Mac ] media/controls/overflow-menu-pointer-selection.html [ Slow ]
 crbug.com/914981 [ Mac ] virtual/mouseevent_fractional/fast/events/no-fake-mousemove.html [ Slow ]
-crbug.com/914981 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/overflow-menu-pointer-selection.html [ Slow ]
 crbug.com/914981 [ Mac ] virtual/video-surface-layer/media/controls/overflow-menu-pointer-selection.html [ Slow ]
 crbug.com/914981 [ Mac ] fast/events/no-fake-mousemove.html [ Slow ]
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 787ed91..a056130 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -114,7 +114,6 @@
 # These two are left over from crbug.com/881040, I rebaselined them twice and
 # they continue to fail.
 crbug.com/881040 media/controls/lazy-loaded-style.html [ Failure Pass ]
-crbug.com/881040 virtual/new-remote-playback-pipeline/media/controls/lazy-loaded-style.html [ Failure Pass ]
 
 # With --enable-display-compositor-pixel-dump enabled by default, these three
 # tests fail. See crbug.com/887140 for more info.
@@ -326,21 +325,15 @@
 crbug.com/857490 virtual/mouseevent_fractional/fast/events/touch/gesture/touch-gesture-fling-with-page-scale.html [ Skip ]
 crbug.com/857490 virtual/mouseevent_fractional/fast/events/wheel/mainthread-touchpad-fling-latching.html [ Skip ]
 crbug.com/857490 virtual/mouseevent_fractional/fast/events/wheel/wheel-fling-cancel.html [ Skip ]
-crbug.com/857490 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Skip ]
-crbug.com/857490 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects.html [ Skip ]
 crbug.com/857490 virtual/scroll_customization/fast/events/touch/gesture/pad-gesture-cancel.html [ Skip ]
 crbug.com/857490 virtual/scroll_customization/fast/events/touch/gesture/pad-gesture-fling.html [ Skip ]
 crbug.com/857490 virtual/scroll_customization/fast/events/touch/gesture/touch-gesture-fling-with-page-scale.html [ Skip ]
 crbug.com/857490 virtual/scroll_customization/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html [ Skip ]
-crbug.com/857490 virtual/scroll_customization/fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Skip ]
-crbug.com/857490 virtual/scroll_customization/fast/events/touch/compositor-touch-hit-rects.html [ Skip ]
 crbug.com/857490 virtual/user-activation-v2/fast/events/touch/gesture/pad-gesture-cancel.html [ Skip ]
 crbug.com/857490 virtual/user-activation-v2/fast/events/touch/gesture/pad-gesture-fling.html [ Skip ]
 crbug.com/857490 virtual/user-activation-v2/fast/events/touch/gesture/touch-gesture-fling-with-page-scale.html [ Skip ]
 crbug.com/857490 virtual/user-activation-v2/fast/events/wheel/mainthread-touchpad-fling-latching.html [ Skip ]
 crbug.com/857490 virtual/user-activation-v2/fast/events/wheel/wheel-fling-cancel.html [ Skip ]
-crbug.com/857490 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Skip ]
-crbug.com/857490 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Skip ]
 
 # Tests not yet passing with Blink FractionalScrollOffsets enabled.
 crbug.com/414283 virtual/fractional_scrolling/fast/scrolling/fractional-scroll-offset-fixed-position-non-composited.html [ Failure ]
@@ -502,7 +495,6 @@
 crbug.com/417223 external/wpt/css/css-position/position-relative-table-tr-top.html [ Failure ]
 
 crbug.com/722825 media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout Pass ]
-crbug.com/722825 virtual/new-remote-playback-pipeline/media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout Pass ]
 crbug.com/722825 virtual/video-surface-layer/media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout Pass ]
 crbug.com/876050 virtual/video-surface-layer/media/controls/text-track-menu-pointer-selection.html [ Pass Failure ]
 
@@ -3065,6 +3057,28 @@
 crbug.com/918664 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/block-size-with-min-or-max-content-table-1a.html [ Failure Pass ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Linux ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https.html [ Crash ]
+crbug.com/626703 [ Linux ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/shared-worker-controlled.https.html [ Crash ]
+crbug.com/626703 [ Retina ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-default-feature-policy.https.html [ Timeout ]
+crbug.com/626703 [ Linux ] virtual/layout_ng/external/wpt/css/CSS2/abspos/abspos-containing-block-initial-001.xht [ Crash ]
+crbug.com/626703 [ Retina ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/GUM-non-applicable-constraint.https.html [ Timeout ]
+crbug.com/626703 [ Linux ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/clients-matchall.https.html [ Crash ]
+crbug.com/626703 [ Retina ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/skip-waiting.https.html [ Timeout ]
+crbug.com/626703 [ Linux ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/activate-event-after-install-state-change.https.html [ Crash ]
+crbug.com/626703 [ Linux ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/clients-matchall-exact-controller.https.html [ Crash ]
+crbug.com/626703 [ Retina ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/import-scripts-resource-map.https.html [ Timeout ]
+crbug.com/626703 [ Linux ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html [ Crash ]
+crbug.com/626703 [ Retina ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/claim-not-using-registration.https.html [ Timeout ]
+crbug.com/626703 [ Retina ] virtual/freeze-frames/external/wpt/lifecycle/freeze.html [ Timeout ]
+crbug.com/626703 [ Linux ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/fetch-cors-xhr.https.html [ Crash ]
+crbug.com/626703 [ Retina ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/navigation-preload/request-headers.https.html [ Timeout ]
+crbug.com/626703 [ Retina ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/register-same-scope-different-script-url.https.html [ Timeout ]
+crbug.com/626703 [ Retina ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/navigation-preload/get-state.https.html [ Timeout ]
+crbug.com/626703 [ Linux ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/fetch-request-css-images.https.html [ Crash ]
+crbug.com/626703 [ Retina ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https.html [ Timeout ]
+crbug.com/626703 [ Linux ] virtual/layout_ng/external/wpt/css/CSS2/linebox/vertical-align-004.xht [ Crash ]
+crbug.com/626703 [ Retina ] virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/clients-get-cross-origin.https.html [ Timeout ]
+crbug.com/626703 [ Retina ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStream-audio-only.https.html [ Timeout ]
 crbug.com/626703 crbug.com/930297 [ Linux ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Timeout Pass Failure ]
 crbug.com/626703 [ Win7 ] external/wpt/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-intrinsic-ratio-007v.html [ Failure ]
@@ -4567,7 +4581,6 @@
 # Sheriff failures 2018-08-15
 crbug.com/874567 [ Mac ] svg/custom/getscreenctm-in-scrollable-div-area-nested.xhtml [ Pass Failure ]
 crbug.com/874837 [ Win ] ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling.htm [ Pass Failure ]
-crbug.com/874866 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-backwards-at-start.html [ Pass Timeout ]
 crbug.com/874931 virtual/threaded/fast/scroll-behavior/smooth-scroll/mousewheel-scroll.html [ Pass Failure Crash ]
 crbug.com/875003 [ Win ] editing/caret/caret-is-hidden-when-no-focus.html [ Pass Failure ]
 
@@ -4660,8 +4673,6 @@
 
 crbug.com/746128 [ Win7 Debug ] media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Failure ]
 crbug.com/746128 [ Mac ] media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Failure Pass ]
-crbug.com/746128 [ Win7 Debug ] virtual/new-remote-playback-pipeline/media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Failure ]
-crbug.com/746128 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/video-enter-exit-fullscreen-without-hovering-doesnt-show-controls.html [ Failure Pass ]
 
 # Sheriff failures 2017-08-04
 crbug.com/626703 [ Win7 Release ] external/wpt/html/semantics/tabular-data/processing-model-1/span-limits.html [ Timeout ]
@@ -4681,12 +4692,9 @@
 crbug.com/832169 virtual/video-surface-layer/media/media-controls-fit-properly-while-zoomed.html [ Failure Pass ]
 crbug.com/832447 media/controls/controls-page-zoom-in.html [ Failure Pass ]
 crbug.com/832447 media/controls/controls-page-zoom-out.html [ Failure Pass ]
-crbug.com/832447 virtual/new-remote-playback-pipeline/media/controls/controls-page-zoom-in.html [ Failure Pass ]
-crbug.com/832447 virtual/new-remote-playback-pipeline/media/controls/controls-page-zoom-out.html [ Failure Pass ]
 crbug.com/832447 virtual/video-surface-layer/media/controls/controls-page-zoom-in.html [ Failure Pass ]
 crbug.com/832447 virtual/video-surface-layer/media/controls/controls-page-zoom-out.html [ Failure Pass ]
 crbug.com/849694 [ Mac ] http/tests/media/controls/toggle-class-with-state-source-buffer.html [ Failure Pass ]
-crbug.com/849694 [ Mac ] virtual/new-remote-playback-pipeline/http/tests/media/controls/toggle-class-with-state-source-buffer.html [ Failure Pass ]
 
 # ContentSecurityPolicy modifies the SchemeRegistry before some initialization.
 crbug.com/686118 http/tests/security/contentSecurityPolicy/register-bypassing-scheme.html [ Pass Crash ]
@@ -4950,25 +4958,15 @@
 crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-on-play-button.html [ Skip ]
 crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ]
 crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/click-anywhere-to-play-pause.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-backwards.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-forwards.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-on-play-button.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/click-anywhere-to-play-pause.html [ Skip ]
 
 # Seen flaky on Linux, suppressing on Windows as well
 crbug.com/831720 [ Win ] media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
 crbug.com/831720 [ Linux ] media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
-crbug.com/831720 [ Win ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
-crbug.com/831720 [ Linux ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
 crbug.com/831720 [ Win ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
 crbug.com/831720 [ Linux ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
 crbug.com/831720 [ Mac ] media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 crbug.com/831720 [ Win ] media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 crbug.com/831720 [ Linux ] media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
-crbug.com/831720 [ Win ] virtual/new-remote-playback-pipeline/media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
-crbug.com/831720 [ Linux ] virtual/new-remote-playback-pipeline/media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 crbug.com/831720 virtual/video-surface-layer/media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 
 crbug.com/802915 css3/blending/isolation-should-include-non-local-background.html [ Failure ]
@@ -4980,7 +4978,6 @@
 
 # Does not work on Mac
 crbug.com/793771 [ Mac ] media/controls/modern/scrubbing.html [ Skip ]
-crbug.com/793771 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/scrubbing.html [ Skip ]
 crbug.com/914981 [ Mac ] virtual/video-surface-layer/media/controls/modern/scrubbing.html [ Skip ]
 crbug.com/916902 [ Mac ] virtual/fractional_scrolling/fast/scrolling/overflow-scrollability.html [ Skip ]
 
@@ -5015,7 +5012,6 @@
 crbug.com/814585 [ Linux ] fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-cjk.html [ Pass Failure ]
 
 # Sheriff failures 2018-02-22
-crbug.com/789921 virtual/new-remote-playback-pipeline/media/controls/repaint-on-resize.html [ Failure Pass ]
 crbug.com/789921 virtual/video-surface-layer/media/controls/repaint-on-resize.html [ Failure Pass ]
 crbug.com/814889 idle-callback/test-runner-run-idle-tasks.html [ Crash Timeout Pass ]
 crbug.com/814953 fast/replaced/no-focus-ring-iframe.html [ Failure Pass ]
@@ -5095,8 +5091,6 @@
 # Sheriff 2018-03-22
 crbug.com/824775 [ Win ] media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
 crbug.com/824775 [ Mac ] media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
-crbug.com/824775 [ Win ] virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
-crbug.com/824775 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
 crbug.com/824775 [ Win ] virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
 crbug.com/824775 [ Mac ] virtual/video-surface-layer/media/controls/video-controls-with-cast-rendering.html [ Pass Failure ]
 crbug.com/824830 fast/peerconnection/RTCPeerConnection-many.html [ Timeout Crash Failure Pass ]
@@ -5173,7 +5167,6 @@
 
 # Sheriff 2018-04-13
 crbug.com/833655 [ Linux ] media/controls/closed-captions-dynamic-update.html [ Skip ]
-crbug.com/833655 [ Linux ] virtual/new-remote-playback-pipeline/media/controls/closed-captions-dynamic-update.html [ Skip ]
 crbug.com/833655 [ Linux ] virtual/video-surface-layer/media/controls/closed-captions-dynamic-update.html [ Skip ]
 crbug.com/833658 [ Linux ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ]
 crbug.com/833658 [ Win ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ]
@@ -5210,7 +5203,6 @@
 crbug.com/846997 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Timeout Pass ]
 crbug.com/849284 [ Mac ] http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Timeout Pass ]
 crbug.com/846982 http/tests/devtools/editor/text-editor-formatter.js [ Timeout Pass ]
-crbug.com/847094 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/tap-to-hide-controls.html [ Skip ]
 crbug.com/846981 fast/webgl/texImage-imageBitmap-from-imageData-resize.html [ Pass Timeout ]
 ### See crbug.com/891427 comment near the top of this file:
 ###crbug.com/847114 [ Linux ] http/tests/devtools/tracing/decode-resize.js [ Pass Failure ]
@@ -5266,7 +5258,6 @@
 crbug.com/853360 [ Mac ] http/tests/misc/slow-loading-image-in-pattern.html [ Pass Timeout Failure ]
 crbug.com/853360 [ Mac ] paint/invalidation/media-audio-no-spurious-repaints.html [ Failure ]
 crbug.com/853360 [ Mac ] tables/mozilla/bugs/bug30692.html [ Failure ]
-crbug.com/853360 [ Mac ] virtual/new-remote-playback-pipeline/http/tests/media/controls/toggle-class-with-state-source.html [ Pass Timeout ]
 crbug.com/853360 [ Mac ] virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance.html [ Failure ]
 crbug.com/853360 [ Mac ] virtual/scalefactor200/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ]
 crbug.com/853360 [ Mac ] fast/forms/calendar-picker/calendar-picker-appearance-ru.html [ Failure ]
@@ -5788,7 +5779,6 @@
 # Sheriff 2018-12-13
 crbug.com/878226 fast/dynamic/window-resize-scrollbars-test.html [ Pass Timeout ]
 crbug.com/910452 media/controls/buttons-after-reset.html [ Pass Failure ]
-crbug.com/910452 virtual/new-remote-playback-pipeline/media/controls/buttons-after-reset.html [ Pass Failure ]
 crbug.com/910452 virtual/video-surface-layer/media/controls/buttons-after-reset.html [ Pass Failure ]
 crbug.com/914782 [ Linux ] fast/scrolling/no-hover-during-scroll.html [ Pass Failure ]
 
@@ -5959,11 +5949,6 @@
 crbug.com/922951 virtual/gpu/fast/canvas/OffscreenCanvas-placeholder-createImageBitmap.html [ Skip ]
 crbug.com/922951 virtual/gpu/fast/canvas/color-space/canvas-drawImage-offscreenCanvas.html [ Skip ]
 crbug.com/922951 virtual/mouseevent_fractional/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ]
-crbug.com/922951 virtual/new-remote-playback-pipeline/media/controls/modern/scrubbing-stops-when-controls-hidden.html [ Skip ]
-crbug.com/922951 virtual/new-remote-playback-pipeline/media/controls/overflow-menu-hide-on-click-outside-stoppropagation.html [ Skip ]
-crbug.com/922951 virtual/new-remote-playback-pipeline/media/controls/overflow-menu-hide-on-click-outside.html [ Skip ]
-crbug.com/922951 virtual/new-remote-playback-pipeline/media/controls/overflow-menu-hide-on-click-panel.html [ Skip ]
-crbug.com/922951 virtual/new-remote-playback-pipeline/media/controls/overflow-menu-toggle-class-for-animation.html [ Skip ]
 crbug.com/922951 virtual/outofblink-cors-ns/http/tests/security/offscreencanvas-placeholder-read-blocked-no-crossorigin.html [ Skip ]
 crbug.com/922951 virtual/outofblink-cors/http/tests/security/offscreencanvas-placeholder-read-blocked-no-crossorigin.html [ Skip ]
 crbug.com/922951 virtual/feature-policy-for-sandbox/http/tests/security/offscreencanvas-placeholder-read-blocked-no-crossorigin.html [ Skip ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index eb167e9..ee8cc7c6c 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -427,26 +427,6 @@
     "args": ["--enable-print-browser"]
   },
   {
-    "prefix": "new-remote-playback-pipeline",
-    "base": "media/remoteplayback",
-    "args": ["--enable-features=NewRemotePlaybackPipeline"]
-  },
-  {
-    "prefix": "new-remote-playback-pipeline",
-    "base": "media/controls",
-    "args": ["--enable-features=NewRemotePlaybackPipeline"]
-  },
-  {
-    "prefix": "new-remote-playback-pipeline",
-    "base": "external/wpt/remote-playback",
-    "args": ["--enable-features=NewRemotePlaybackPipeline"]
-  },
-  {
-    "prefix": "new-remote-playback-pipeline",
-    "base": "http/tests/media/controls",
-    "args": ["--enable-features=NewRemotePlaybackPipeline"]
-  },
-  {
     "prefix": "high-contrast-mode",
     "base": "paint/high-contrast-mode/image-filter-all",
     "args": ["--blink-settings=highContrastMode=3,highContrastImagePolicy=0"]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index af04a746..104c1f6 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -186313,6 +186313,11 @@
      {}
     ]
    ],
+   "signed-exchange/resources/sxg/sxg-merkle-integrity-error.sxg": [
+    [
+     {}
+    ]
+   ],
    "signed-exchange/resources/sxg/sxg-noncacheable.sxg": [
     [
      {}
@@ -279727,6 +279732,12 @@
      {}
     ]
    ],
+   "signed-exchange/sxg-merkle-integrity-error.tentative.html": [
+    [
+     "/signed-exchange/sxg-merkle-integrity-error.tentative.html",
+     {}
+    ]
+   ],
    "signed-exchange/sxg-non-secure-origin.tentative.html": [
     [
      "/signed-exchange/sxg-non-secure-origin.tentative.html",
@@ -279739,6 +279750,12 @@
      {}
     ]
    ],
+   "signed-exchange/sxg-prefetch-merkle-integrity-error.tentative.html": [
+    [
+     "/signed-exchange/sxg-prefetch-merkle-integrity-error.tentative.html",
+     {}
+    ]
+   ],
    "signed-exchange/sxg-prefetch-resource-timing.tentative.html": [
     [
      "/signed-exchange/sxg-prefetch-resource-timing.tentative.html",
@@ -394307,11 +394324,11 @@
    "support"
   ],
   "domparsing/XMLSerializer-serializeToString-expected.txt": [
-   "e7272dd7fa2ec543b2c4064230e30e3fd3a2fb26",
+   "fc008ec96a92108431f392e24fbefa986a83960d",
    "support"
   ],
   "domparsing/XMLSerializer-serializeToString.html": [
-   "5ae5bbb82b86909365a071f984b834c2e97f66fd",
+   "5f7e2bb0d4b459bd20acb43aca19b848920ac8bb",
    "testharness"
   ],
   "domparsing/createContextualFragment.html": [
@@ -422271,7 +422288,7 @@
    "support"
   ],
   "interfaces/webxr.idl": [
-   "2bc100e100d89da510c56dc51d13d45335f67740",
+   "d175729ca20fd66b0d1d8a32ef32e0957c58548f",
    "support"
   ],
   "interfaces/worklets.idl": [
@@ -450811,7 +450828,7 @@
    "support"
   ],
   "signed-exchange/resources/generate-test-sxgs.sh": [
-   "7c953940cb308b669a647a4a2d5c5bbc83c60200",
+   "bb95df83295e1b2f81a569e93fd5d9d0ce548574",
    "support"
   ],
   "signed-exchange/resources/inner-url.html": [
@@ -450878,6 +450895,10 @@
    "1678b751bcba390d35687730bb24e13232e33eda",
    "support"
   ],
+  "signed-exchange/resources/sxg/sxg-merkle-integrity-error.sxg": [
+   "0c6dce01da270bdacf5d280551d56d1519aff3a3",
+   "support"
+  ],
   "signed-exchange/resources/sxg/sxg-noncacheable.sxg": [
    "88439982f6044b3ddbd1a1e0198bebb6409b0837",
    "support"
@@ -450926,6 +450947,10 @@
    "17ca0768d6f8e0e1a4bccf707d8e34c6dbfdfc8c",
    "testharness"
   ],
+  "signed-exchange/sxg-merkle-integrity-error.tentative.html": [
+   "5f923d205421ca30e360ddf0de41bb64733de1d3",
+   "testharness"
+  ],
   "signed-exchange/sxg-non-secure-origin.tentative.html": [
    "84938da76d09dbe4f045b763e49ba95a4936003f",
    "testharness"
@@ -450934,6 +450959,10 @@
    "1315360745789655acb926d7e8bafea9322c3a25",
    "testharness"
   ],
+  "signed-exchange/sxg-prefetch-merkle-integrity-error.tentative.html": [
+   "2086c38545d7df43dbe913b78ef1030c476b3649",
+   "testharness"
+  ],
   "signed-exchange/sxg-prefetch-resource-timing.tentative.html": [
    "5b60ab9e1a12e2b169c4972c422ddbe3ebc5f581",
    "testharness"
@@ -463219,7 +463248,7 @@
    "support"
   ],
   "webxr/idlharness.https.window-expected.txt": [
-   "6e0c787dc8ba4a8e0560ed843da2b6f6b9eded77",
+   "588b212fa11411f9fe57b1a56e2247f2735a2164",
    "support"
   ],
   "webxr/idlharness.https.window.js": [
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/base64.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/data-urls/base64.any-expected.txt
deleted file mode 100644
index 34eb7944..0000000
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/base64.any-expected.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-This is a testharness.js-based test.
-Found 79 tests; 75 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Setup.
-PASS data: URL base64 handling: ""
-PASS data: URL base64 handling: "abcd"
-PASS data: URL base64 handling: " abcd"
-PASS data: URL base64 handling: "abcd "
-PASS data: URL base64 handling: " abcd==="
-PASS data: URL base64 handling: "abcd=== "
-PASS data: URL base64 handling: "abcd ==="
-PASS data: URL base64 handling: "a"
-PASS data: URL base64 handling: "ab"
-PASS data: URL base64 handling: "abc"
-PASS data: URL base64 handling: "abcde"
-PASS data: URL base64 handling: "𐀀"
-PASS data: URL base64 handling: "="
-PASS data: URL base64 handling: "=="
-PASS data: URL base64 handling: "==="
-PASS data: URL base64 handling: "===="
-PASS data: URL base64 handling: "====="
-PASS data: URL base64 handling: "a="
-PASS data: URL base64 handling: "a=="
-PASS data: URL base64 handling: "a==="
-PASS data: URL base64 handling: "a===="
-PASS data: URL base64 handling: "a====="
-PASS data: URL base64 handling: "ab="
-PASS data: URL base64 handling: "ab=="
-PASS data: URL base64 handling: "ab==="
-PASS data: URL base64 handling: "ab===="
-PASS data: URL base64 handling: "ab====="
-PASS data: URL base64 handling: "abc="
-PASS data: URL base64 handling: "abc=="
-PASS data: URL base64 handling: "abc==="
-PASS data: URL base64 handling: "abc===="
-PASS data: URL base64 handling: "abc====="
-PASS data: URL base64 handling: "abcd="
-PASS data: URL base64 handling: "abcd=="
-PASS data: URL base64 handling: "abcd==="
-PASS data: URL base64 handling: "abcd===="
-PASS data: URL base64 handling: "abcd====="
-PASS data: URL base64 handling: "abcde="
-PASS data: URL base64 handling: "abcde=="
-PASS data: URL base64 handling: "abcde==="
-PASS data: URL base64 handling: "abcde===="
-PASS data: URL base64 handling: "abcde====="
-PASS data: URL base64 handling: "=a"
-PASS data: URL base64 handling: "=a="
-PASS data: URL base64 handling: "a=b"
-PASS data: URL base64 handling: "a=b="
-PASS data: URL base64 handling: "ab=c"
-PASS data: URL base64 handling: "ab=c="
-PASS data: URL base64 handling: "abc=d"
-PASS data: URL base64 handling: "abc=d="
-PASS data: URL base64 handling: "ab\vcd"
-PASS data: URL base64 handling: "ab\tcd"
-PASS data: URL base64 handling: "ab\ncd"
-FAIL data: URL base64 handling: "ab\fcd" promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-PASS data: URL base64 handling: "ab\rcd"
-PASS data: URL base64 handling: "ab cd"
-PASS data: URL base64 handling: "ab cd"
-FAIL data: URL base64 handling: "ab\t\n\f\r cd" promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-FAIL data: URL base64 handling: " \t\n\f\r ab\t\n\f\r cd\t\n\f\r " promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-FAIL data: URL base64 handling: "ab\t\n\f\r =\t\n\f\r =\t\n\f\r " promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-PASS data: URL base64 handling: "A"
-PASS data: URL base64 handling: "/A"
-PASS data: URL base64 handling: "//A"
-PASS data: URL base64 handling: "///A"
-PASS data: URL base64 handling: "////A"
-PASS data: URL base64 handling: "/"
-PASS data: URL base64 handling: "A/"
-PASS data: URL base64 handling: "AA/"
-PASS data: URL base64 handling: "AAAA/"
-PASS data: URL base64 handling: "AAA/"
-PASS data: URL base64 handling: "\0nonsense"
-PASS data: URL base64 handling: "abcd\0nonsense"
-PASS data: URL base64 handling: "YQ"
-PASS data: URL base64 handling: "YR"
-PASS data: URL base64 handling: "~~"
-PASS data: URL base64 handling: ".."
-PASS data: URL base64 handling: "--"
-PASS data: URL base64 handling: "__"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/base64.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/data-urls/base64.any.worker-expected.txt
deleted file mode 100644
index 34eb7944..0000000
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/base64.any.worker-expected.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-This is a testharness.js-based test.
-Found 79 tests; 75 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Setup.
-PASS data: URL base64 handling: ""
-PASS data: URL base64 handling: "abcd"
-PASS data: URL base64 handling: " abcd"
-PASS data: URL base64 handling: "abcd "
-PASS data: URL base64 handling: " abcd==="
-PASS data: URL base64 handling: "abcd=== "
-PASS data: URL base64 handling: "abcd ==="
-PASS data: URL base64 handling: "a"
-PASS data: URL base64 handling: "ab"
-PASS data: URL base64 handling: "abc"
-PASS data: URL base64 handling: "abcde"
-PASS data: URL base64 handling: "𐀀"
-PASS data: URL base64 handling: "="
-PASS data: URL base64 handling: "=="
-PASS data: URL base64 handling: "==="
-PASS data: URL base64 handling: "===="
-PASS data: URL base64 handling: "====="
-PASS data: URL base64 handling: "a="
-PASS data: URL base64 handling: "a=="
-PASS data: URL base64 handling: "a==="
-PASS data: URL base64 handling: "a===="
-PASS data: URL base64 handling: "a====="
-PASS data: URL base64 handling: "ab="
-PASS data: URL base64 handling: "ab=="
-PASS data: URL base64 handling: "ab==="
-PASS data: URL base64 handling: "ab===="
-PASS data: URL base64 handling: "ab====="
-PASS data: URL base64 handling: "abc="
-PASS data: URL base64 handling: "abc=="
-PASS data: URL base64 handling: "abc==="
-PASS data: URL base64 handling: "abc===="
-PASS data: URL base64 handling: "abc====="
-PASS data: URL base64 handling: "abcd="
-PASS data: URL base64 handling: "abcd=="
-PASS data: URL base64 handling: "abcd==="
-PASS data: URL base64 handling: "abcd===="
-PASS data: URL base64 handling: "abcd====="
-PASS data: URL base64 handling: "abcde="
-PASS data: URL base64 handling: "abcde=="
-PASS data: URL base64 handling: "abcde==="
-PASS data: URL base64 handling: "abcde===="
-PASS data: URL base64 handling: "abcde====="
-PASS data: URL base64 handling: "=a"
-PASS data: URL base64 handling: "=a="
-PASS data: URL base64 handling: "a=b"
-PASS data: URL base64 handling: "a=b="
-PASS data: URL base64 handling: "ab=c"
-PASS data: URL base64 handling: "ab=c="
-PASS data: URL base64 handling: "abc=d"
-PASS data: URL base64 handling: "abc=d="
-PASS data: URL base64 handling: "ab\vcd"
-PASS data: URL base64 handling: "ab\tcd"
-PASS data: URL base64 handling: "ab\ncd"
-FAIL data: URL base64 handling: "ab\fcd" promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-PASS data: URL base64 handling: "ab\rcd"
-PASS data: URL base64 handling: "ab cd"
-PASS data: URL base64 handling: "ab cd"
-FAIL data: URL base64 handling: "ab\t\n\f\r cd" promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-FAIL data: URL base64 handling: " \t\n\f\r ab\t\n\f\r cd\t\n\f\r " promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-FAIL data: URL base64 handling: "ab\t\n\f\r =\t\n\f\r =\t\n\f\r " promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-PASS data: URL base64 handling: "A"
-PASS data: URL base64 handling: "/A"
-PASS data: URL base64 handling: "//A"
-PASS data: URL base64 handling: "///A"
-PASS data: URL base64 handling: "////A"
-PASS data: URL base64 handling: "/"
-PASS data: URL base64 handling: "A/"
-PASS data: URL base64 handling: "AA/"
-PASS data: URL base64 handling: "AAAA/"
-PASS data: URL base64 handling: "AAA/"
-PASS data: URL base64 handling: "\0nonsense"
-PASS data: URL base64 handling: "abcd\0nonsense"
-PASS data: URL base64 handling: "YQ"
-PASS data: URL base64 handling: "YR"
-PASS data: URL base64 handling: "~~"
-PASS data: URL base64 handling: ".."
-PASS data: URL base64 handling: "--"
-PASS data: URL base64 handling: "__"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any-expected.txt
index a0a3296b..1e47de1 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 45 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 71 tests; 46 PASS, 25 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup.
 PASS "data://test/,X"
 FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -49,7 +49,7 @@
 PASS "data:x/x;base64;charset=x;base64,WA"
 FAIL "data:x/x;base64;base64x,WA" assert_array_equals: lengths differ, expected 2 got 1
 PASS "data:;base64,W%20A"
-FAIL "data:;base64,W%0CA" promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS "data:;base64,W%0CA"
 PASS "data:x;base64x,WA"
 FAIL "data:x;base64;x,WA" assert_array_equals: lengths differ, expected 2 got 1
 PASS "data:x;base64=x,WA"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt
index a0a3296b..1e47de1 100644
--- a/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/fetch/data-urls/processing.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 71 tests; 45 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 71 tests; 46 PASS, 25 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Setup.
 PASS "data://test/,X"
 FAIL "data://test:test/,X" assert_unreached: Should have rejected: undefined Reached unreachable code
@@ -49,7 +49,7 @@
 PASS "data:x/x;base64;charset=x;base64,WA"
 FAIL "data:x/x;base64;base64x,WA" assert_array_equals: lengths differ, expected 2 got 1
 PASS "data:;base64,W%20A"
-FAIL "data:;base64,W%0CA" promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS "data:;base64,W%0CA"
 PASS "data:x;base64x,WA"
 FAIL "data:x;base64;x,WA" assert_array_equals: lengths differ, expected 2 got 1
 PASS "data:x;base64=x,WA"
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
index 2bc100e..d175729c 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
@@ -78,12 +78,12 @@
 [SecureContext, Exposed=Window] interface XRFrame {
   readonly attribute XRSession session;
 
-  XRViewerPose? getViewerPose(optional XRReferenceSpace referenceSpace);
-  XRInputPose? getInputPose(XRInputSource inputSource, optional XRReferenceSpace referenceSpace);
+  XRViewerPose? getViewerPose(XRReferenceSpace referenceSpace);
+  XRPose? getPose(XRSpace space, XRSpace relativeTo);
 };
 
 [SecureContext, Exposed=Window] interface XRSpace : EventTarget {
-  XRRigidTransform? getTransformTo(XRSpace other);
+
 };
 
 enum XRReferenceSpaceType {
@@ -159,8 +159,12 @@
   readonly attribute Float32Array matrix;
 };
 
-[SecureContext, Exposed=Window] interface XRViewerPose {
+[SecureContext, Exposed=Window] interface XRPose {
   readonly attribute XRRigidTransform transform;
+  readonly attribute boolean emulatedPosition;
+};
+
+[SecureContext, Exposed=Window] interface XRViewerPose : XRPose {
   readonly attribute FrozenArray<XRView> views;
 };
 
@@ -180,13 +184,8 @@
 interface XRInputSource {
   readonly attribute XRHandedness handedness;
   readonly attribute XRTargetRayMode targetRayMode;
-};
-
-[SecureContext, Exposed=Window]
-interface XRInputPose {
-  readonly attribute boolean emulatedPosition;
-  readonly attribute XRRay targetRay;
-  readonly attribute XRRigidTransform? gripTransform;
+  readonly attribute XRSpace targetRaySpace;
+  readonly attribute XRSpace? gripSpace;
 };
 
 [SecureContext, Exposed=Window] interface XRLayer {};
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_change-touch-action-onpointerdown_touch.html
similarity index 95%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_change-touch-action-onpointerdown_touch.html
index 04d56cb7a..72f1e6d3 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_change-touch-action-onpointerdown_touch.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <script src="pointerevent_support.js"></script>
         <style>
             #target0 {
@@ -124,6 +127,9 @@
                 on_event(target0, 'pointerup', function(event) {
                     firstTouchCompleted = true;
                 });
+
+                // Inject touch inputs.
+                touchScrollInTarget(target0, 'down');
             }
         </script>
         <h1>touch-action: auto to none</h1>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercancel_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercancel_touch.html
similarity index 93%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercancel_touch-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercancel_touch.html
index 70a65ee..b41c5014 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercancel_touch-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercancel_touch.html
@@ -5,6 +5,9 @@
         <meta name="viewport" content="width=device-width">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <!-- Additional helper script for common checks across event types -->
         <script type="text/javascript" src="pointerevent_support.js"></script>
@@ -66,6 +69,9 @@
                     });
                     test_pointerEvent.done();
                 });
+
+                // Inject touch inputs.
+                touchScrollInTarget(target0, 'down');
             }
         </script>
         <h1>Pointer Events pointercancel Tests</h1>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerleave_after_pointercancel_touch.html
similarity index 91%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerleave_after_pointercancel_touch.html
index 56be265..73806f5d 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerleave_after_pointercancel_touch.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <!-- Additional helper script for common checks across event types -->
         <script type="text/javascript" src="pointerevent_support.js"></script>
     </head>
@@ -54,6 +57,9 @@
                         }
                     }
                 });
+
+                // Inject touch inputs.
+                touchScrollInTarget(target0, 'down');
             }
 
         </script>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerout_after_pointercancel_touch.html
similarity index 91%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerout_after_pointercancel_touch.html
index 1888591a..67559cb 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointerout_after_pointercancel_touch.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <!-- Additional helper script for common checks across event types -->
         <script type="text/javascript" src="pointerevent_support.js"></script>
     </head>
@@ -55,6 +58,9 @@
                         }
                     }
                 });
+
+                // Inject touch inputs.
+                touchScrollInTarget(target0, 'down');
             }
 
         </script>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch.html
similarity index 92%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch.html
index 49784004..8133dadc 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <script src="pointerevent_support.js"></script>
     </head>
     <body class="scrollable">
@@ -64,6 +67,9 @@
                     event_log.push('pointercancel@target0');
                     pointercancelGot = true;
                 });
+
+                // Inject touch inputs.
+                touchScrollInTarget(target0, 'down');
             }
         </script>
         <h1>Pointer Events Capture Test</h1>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js
index 5c35e016..0d5b6b040 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_support.js
@@ -252,3 +252,35 @@
 function checkPointerEventType(event) {
     assert_equals(event.pointerType, expectedPointerType, "pointerType should be the same as the requested device.");
 }
+
+function touchScrollInTarget(target, direction) {
+    var x_delta = 0;
+    var y_delta = 0;
+    if (direction == "down") {
+        x_delta = 0;
+        y_delta = -10;
+    } else if (direction == "up") {
+        x_delta = 0;
+        y_delta = 10;
+    } else if (direction == "right") {
+        x_delta = -10;
+        y_delta = 0;
+    } else if (direction == "left") {
+        x_delta = 10;
+        y_delta = 0;
+    } else {
+        throw("scroll direction '" + direction + "' is not expected, direction should be 'down', 'up', 'left' or 'right'");
+    }
+    return new test_driver.Actions()
+                   .addPointer("pointer1", "touch")
+                   .pointerMove(0, 0, {origin: target})
+                   .pointerDown()
+                   .pointerMove(x_delta, y_delta, {origin: target})
+                   .pointerMove(2 * x_delta, 2 * y_delta, {origin: target})
+                   .pointerMove(3 * x_delta, 3 * y_delta, {origin: target})
+                   .pointerMove(4 * x_delta, 4 * y_delta, {origin: target})
+                   .pointerMove(5 * x_delta, 5 * y_delta, {origin: target})
+                   .pointerMove(6 * x_delta, 6 * y_delta, {origin: target})
+                   .pointerUp()
+                   .send();
+}
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-auto-css_touch.html
similarity index 93%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-auto-css_touch.html
index f5e9d12..ccacde4 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-auto-css_touch.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <script src="pointerevent_support.js"></script>
         <style>
             #target0 {
@@ -118,6 +121,10 @@
                         updateDescriptionComplete();
                     }
                 });
+
+                // Inject touch inputs.
+                touchScrollInTarget(target0, 'down').then(function() {
+                    return touchScrollInTarget(target0, 'right'); });
             }
         </script>
         <h1>touch-action: auto</h1>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch.html
similarity index 93%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch.html
index d87d2b3..d09e6c5 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <script src="pointerevent_support.js"></script>
         <style>
             #divParent {
@@ -118,6 +121,10 @@
                         updateDescriptionComplete();
                     }
                 });
+
+                // Inject touch inputs.
+                touchScrollInTarget(scrollTarget, 'down').then(function() {
+                    return touchScrollInTarget(scrollTarget, 'right'); });
             }
 
             function enableScrolling() {
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch.html
similarity index 93%
rename from third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html
rename to third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch.html
index 0c900ff..d5d49453 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch.html
@@ -6,6 +6,9 @@
         <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
         <script src="/resources/testharness.js"></script>
         <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
         <script src="pointerevent_support.js"></script>
         <style>
             #target0 {
@@ -115,6 +118,10 @@
                         updateDescriptionComplete();
                     }
                 });
+
+                // Inject touch inputs.
+                touchScrollInTarget(target0, 'down').then(function() {
+                    return touchScrollInTarget(target0, 'right'); });
             }
         </script>
         <h1>touch-action: pan-x pan-y</h1>
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
index 6e0c787..588b212 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 215 tests; 199 PASS, 16 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 214 tests; 187 PASS, 27 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS Partial interface Navigator: original interface defined
 PASS Partial dictionary WebGLContextAttributes: original dictionary defined
@@ -59,15 +59,14 @@
 PASS XRFrame interface: existence and properties of interface prototype object's "constructor" property
 PASS XRFrame interface: existence and properties of interface prototype object's @@unscopables property
 PASS XRFrame interface: attribute session
-FAIL XRFrame interface: operation getViewerPose(XRReferenceSpace) assert_equals: property has wrong .length expected 0 but got 1
-FAIL XRFrame interface: operation getInputPose(XRInputSource, XRReferenceSpace) assert_equals: property has wrong .length expected 1 but got 2
+PASS XRFrame interface: operation getViewerPose(XRReferenceSpace)
+FAIL XRFrame interface: operation getPose(XRSpace, XRSpace) assert_own_property: interface prototype object missing non-static operation expected property "getPose" missing
 PASS XRSpace interface: existence and properties of interface object
 PASS XRSpace interface object length
 PASS XRSpace interface object name
 PASS XRSpace interface: existence and properties of interface prototype object
 PASS XRSpace interface: existence and properties of interface prototype object's "constructor" property
 PASS XRSpace interface: existence and properties of interface prototype object's @@unscopables property
-PASS XRSpace interface: operation getTransformTo(XRSpace)
 PASS XRReferenceSpace interface: existence and properties of interface object
 PASS XRReferenceSpace interface object length
 PASS XRReferenceSpace interface object name
@@ -134,13 +133,20 @@
 PASS XRRay interface: attribute origin
 PASS XRRay interface: attribute direction
 FAIL XRRay interface: attribute matrix assert_true: The prototype object must have a property "matrix" expected true got false
-PASS XRViewerPose interface: existence and properties of interface object
+FAIL XRPose interface: existence and properties of interface object assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+FAIL XRPose interface object length assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+FAIL XRPose interface object name assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+FAIL XRPose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+FAIL XRPose interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+FAIL XRPose interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+FAIL XRPose interface: attribute transform assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+FAIL XRPose interface: attribute emulatedPosition assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
+FAIL XRViewerPose interface: existence and properties of interface object assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
 PASS XRViewerPose interface object length
 PASS XRViewerPose interface object name
-PASS XRViewerPose interface: existence and properties of interface prototype object
+FAIL XRViewerPose interface: existence and properties of interface prototype object assert_own_property: self does not have own property "XRPose" expected property "XRPose" missing
 PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property
 PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property
-PASS XRViewerPose interface: attribute transform
 PASS XRViewerPose interface: attribute views
 PASS XRInputSource interface: existence and properties of interface object
 PASS XRInputSource interface object length
@@ -150,15 +156,8 @@
 PASS XRInputSource interface: existence and properties of interface prototype object's @@unscopables property
 PASS XRInputSource interface: attribute handedness
 PASS XRInputSource interface: attribute targetRayMode
-PASS XRInputPose interface: existence and properties of interface object
-PASS XRInputPose interface object length
-PASS XRInputPose interface object name
-PASS XRInputPose interface: existence and properties of interface prototype object
-PASS XRInputPose interface: existence and properties of interface prototype object's "constructor" property
-PASS XRInputPose interface: existence and properties of interface prototype object's @@unscopables property
-PASS XRInputPose interface: attribute emulatedPosition
-PASS XRInputPose interface: attribute targetRay
-PASS XRInputPose interface: attribute gripTransform
+FAIL XRInputSource interface: attribute targetRaySpace assert_true: The prototype object must have a property "targetRaySpace" expected true got false
+FAIL XRInputSource interface: attribute gripSpace assert_true: The prototype object must have a property "gripSpace" expected true got false
 PASS XRLayer interface: existence and properties of interface object
 PASS XRLayer interface object length
 PASS XRLayer interface object name
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual-automation.js
deleted file mode 100644
index fe24736..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual-automation.js
+++ /dev/null
@@ -1,6 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return touchScrollInTarget('#target0', 'down');
-}
-
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointercancel_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointercancel_touch-manual-automation.js
deleted file mode 100644
index c46cb0a..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointercancel_touch-manual-automation.js
+++ /dev/null
@@ -1,7 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return touchScrollInTarget('#target0', 'down');
-}
-
-
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual-automation.js
deleted file mode 100644
index c46cb0a..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual-automation.js
+++ /dev/null
@@ -1,7 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return touchScrollInTarget('#target0', 'down');
-}
-
-
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual-automation.js
deleted file mode 100644
index fe24736..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual-automation.js
+++ /dev/null
@@ -1,6 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return touchScrollInTarget('#target0', 'down');
-}
-
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual-automation.js
deleted file mode 100644
index fe24736..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual-automation.js
+++ /dev/null
@@ -1,6 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return touchScrollInTarget('#target0', 'down');
-}
-
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-auto-css_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-auto-css_touch-manual-automation.js
deleted file mode 100644
index f3e2b84a..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-auto-css_touch-manual-automation.js
+++ /dev/null
@@ -1,8 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return touchScrollInTarget('#target0', 'down').then(function() {
-    return touchScrollInTarget('#target0', 'right');
-  });
-}
-
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual-automation.js
deleted file mode 100644
index 1c006c4..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual-automation.js
+++ /dev/null
@@ -1,7 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return touchScrollInTarget('#scrollTarget', 'down').then(function() {
-    return touchScrollInTarget('#scrollTarget', 'right');
-  });
-}
diff --git a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual-automation.js b/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual-automation.js
deleted file mode 100644
index 4a2a9a4..0000000
--- a/third_party/blink/web_tests/external/wpt_automation/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual-automation.js
+++ /dev/null
@@ -1,7 +0,0 @@
-importAutomationScript('/pointerevents/pointerevent_common_input.js');
-
-function inject_input() {
-  return touchScrollInTarget('#target0', 'down').then(function() {
-    return touchScrollInTarget('#target0', 'right');
-  });
-}
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-dnd-rendering-expected.html b/third_party/blink/web_tests/fast/canvas/canvas-dnd-rendering-expected.html
new file mode 100644
index 0000000..bef55a8
--- /dev/null
+++ b/third_party/blink/web_tests/fast/canvas/canvas-dnd-rendering-expected.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+p:first-child { padding-left:12px; }
+</style>
+<p>
+  <canvas width="100" height="100">Canvas</canvas>
+</p>
+<script>
+var canvas = document.querySelector('canvas'),
+c = canvas.getContext('2d');
+c.fillRect(0,0,100,100);
+</script>
+</html>
+
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-dnd-rendering.html b/third_party/blink/web_tests/fast/canvas/canvas-dnd-rendering.html
new file mode 100644
index 0000000..bef55a8
--- /dev/null
+++ b/third_party/blink/web_tests/fast/canvas/canvas-dnd-rendering.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+p:first-child { padding-left:12px; }
+</style>
+<p>
+  <canvas width="100" height="100">Canvas</canvas>
+</p>
+<script>
+var canvas = document.querySelector('canvas'),
+c = canvas.getContext('2d');
+c.fillRect(0,0,100,100);
+</script>
+</html>
+
diff --git a/third_party/blink/web_tests/fast/css/reattach-ensured-in-display-none-crash.html b/third_party/blink/web_tests/fast/css/reattach-ensured-in-display-none-crash.html
new file mode 100644
index 0000000..fedd4be
--- /dev/null
+++ b/third_party/blink/web_tests/fast/css/reattach-ensured-in-display-none-crash.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<div id="outer">
+  <div style="display: none">
+    <span id=inner></span>
+  </div>
+</div>
+<script>
+test(() => {
+    let style = getComputedStyle(inner);
+    style.color;
+    outer.style.display = 'inline';
+    // Don't crash:
+    outer.offsetTop;
+}, 'Nodes with styles in display:none subtrees should not cause crash on reattach');
+</script>
diff --git a/third_party/blink/web_tests/resources/testdriver-vendor.js b/third_party/blink/web_tests/resources/testdriver-vendor.js
index a806a721..7a7dc03 100644
--- a/third_party/blink/web_tests/resources/testdriver-vendor.js
+++ b/third_party/blink/web_tests/resources/testdriver-vendor.js
@@ -84,6 +84,7 @@
     for (let i = 0; i < actions.length; i++) {
       var last_x_position = 0;
       var last_y_position = 0;
+      var first_pointer_down = false;
       for (let j = 0; j < actions[i].actions.length; j++) {
         if ('origin' in actions[i].actions[j]) {
           if (actions[i].actions[j].origin == "viewport") {
@@ -126,6 +127,16 @@
           actions[i].actions[j].x = last_x_position;
           actions[i].actions[j].y = last_y_position;
         }
+
+        if ('parameters' in actions[i] && actions[i].parameters.pointerType == "touch") {
+          if (actions[i].actions[j].type == "pointerMove" && !first_pointer_down) {
+            actions[i].actions.splice(j--, 1);
+          } else if (actions[i].actions[j].type == "pointerDown") {
+            first_pointer_down = true;
+          } else if (actions[i].actions[j].type == "pointerUp") {
+            first_pointer_down = false;
+          }
+        }
       }
     }
 
diff --git a/third_party/libdrm/BUILD.gn b/third_party/libdrm/BUILD.gn
index a3fed9d6..3fc3cc3 100644
--- a/third_party/libdrm/BUILD.gn
+++ b/third_party/libdrm/BUILD.gn
@@ -19,8 +19,14 @@
   # Suppress this warning for now.  This may be removed once
   # https://patchwork.kernel.org/patch/9628231/ lands.
   cflags = [ "-Wno-#pragma-messages" ]
+
   if (is_clang) {
-    cflags += [ "-Wno-enum-conversion" ]
+    cflags += [
+      "-Wno-enum-conversion",
+
+      # TODO(crbug.com/932060) fix unused result from asprintf in modetest.c.
+      "-Wno-unused-result",
+    ]
   }
 }
 
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index cdd1027..debbb0d 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -17592,6 +17592,15 @@
   </description>
 </action>
 
+<action name="Signin_Signin_BackOnAdvancedSyncSettings">
+  <owner>tangltom@chromium.org</owner>
+  <description>
+    Recorded when the user clicks the &quot;browser back&quot; or the
+    &quot;settings back&quot; button to leave the sync settings page during the
+    advanced sync opt-in flow.
+  </description>
+</action>
+
 <action name="Signin_Signin_CancelAdvancedSyncSettings">
   <owner>tangltom@chromium.org</owner>
   <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index ae7ca53..d3dafb2 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -3204,15 +3204,6 @@
   <int value="2" label="New profile created"/>
 </enum>
 
-<enum name="AutofillProfileSyncChangeOrigin">
-  <int value="0" label="Change in a local profile"/>
-  <int value="1"
-      label="Change in a converted local profile (that still equals to a
-             server profile)"/>
-  <int value="2" label="Resolving conflict in incremental remote update"/>
-  <int value="3" label="Upload / conflict resolution in initial sync"/>
-</enum>
-
 <enum name="AutofillQuality">
   <int value="0" label="Submitted"/>
   <int value="1" label="Autofilled"/>
@@ -4840,6 +4831,11 @@
   <int value="1" label="Expired"/>
 </enum>
 
+<enum name="BooleanFocused">
+  <int value="0" label="Unfocused"/>
+  <int value="1" label="Focused"/>
+</enum>
+
 <enum name="BooleanForced">
   <int value="0" label="Not forced"/>
   <int value="1" label="Forced"/>
@@ -21578,6 +21574,7 @@
   <int value="2785" label="V8UserActivation_HasBeenActive_AttributeGetter"/>
   <int value="2786" label="V8UserActivation_IsActive_AttributeGetter"/>
   <int value="2787" label="TextEncoderEncodeInto"/>
+  <int value="2788" label="InvalidBasicCardMethodData"/>
 </enum>
 
 <enum name="FeaturePolicyFeature">
@@ -31197,6 +31194,7 @@
   <int value="-1248478422" label="enable-zip-archiver-packer"/>
   <int value="-1246840031" label="OptInImeMenu:disabled"/>
   <int value="-1241747717" label="enable-android-password-link"/>
+  <int value="-1239262870" label="TextFragmentAnchor:enabled"/>
   <int value="-1237621246" label="WebXRGamepadSupport:disabled"/>
   <int value="-1236065190" label="HardwareMediaKeyHandling:disabled"/>
   <int value="-1235586511" label="enable-datasaver-prompt"/>
@@ -32893,6 +32891,7 @@
   <int value="1702821235" label="WebAssembly:enabled"/>
   <int value="1705724232" label="use-android-midi-api"/>
   <int value="1707283026" label="SyncPseudoUSSExtensions:disabled"/>
+  <int value="1708118086" label="TextFragmentAnchor:disabled"/>
   <int value="1713230497" label="ColorCorrectRendering:disabled"/>
   <int value="1715338237" label="ContextualSearchSecondTap:disabled"/>
   <int value="1716104463" label="enable-fullscreen-app-list"/>
@@ -42601,6 +42600,39 @@
   </int>
 </enum>
 
+<enum name="PietErrorCode">
+  <summary>
+    Piet Error Code as defined in
+    com.google.search.now.ui.piet.ErrorsProto.ErrorCode, which located in
+    /third_party/feed/src/main/proto/search/now/ui/piet/errors.proto.
+  </summary>
+  <int value="0" label="ERR_UNSPECIFIED"/>
+  <int value="1" label="ERR_MISSING_STYLESHEET"/>
+  <int value="2" label="ERR_DUPLICATE_STYLESHEET"/>
+  <int value="3" label="ERR_MISSING_STYLE"/>
+  <int value="4" label="ERR_DUPLICATE_STYLE"/>
+  <int value="5" label="ERR_MISSING_TEMPLATE"/>
+  <int value="6" label="ERR_DUPLICATE_TEMPLATE"/>
+  <int value="8" label="ERR_MISSING_BINDING_VALUE"/>
+  <int value="9" label="ERR_DUPLICATE_BINDING_VALUE"/>
+  <int value="10" label="ERR_BINDING_VALUE_TYPE_MISMATCH"/>
+  <int value="101" label="ERR_MISSING_FONTS"/>
+  <int value="102" label="ERR_MISSING_IMAGE_URL"/>
+  <int value="103" label="ERR_IMAGE_UNAVAILABLE"/>
+  <int value="104" label="ERR_MISSING_CUSTOM_ELEMENT_RENDERER"/>
+  <int value="105" label="ERR_INVALID_GRADIENT_DIRECTION"/>
+  <int value="106" label="ERR_MISSING_ACTION_HANDLER"/>
+  <int value="107" label="ERR_CONTENT_WIDTH_GRID_CELL_WITH_INVALID_CONTENT"/>
+  <int value="108" label="ERR_GRID_CELL_WIDTH_WITHOUT_CONTENTS"/>
+  <int value="109" label="ERR_INVALID_MEDIA_QUERY_CONDITION"/>
+  <int value="110" label="ERR_MISSING_ELEMENT_CONTENTS"/>
+  <int value="111" label="ERR_MISSING_OR_UNHANDLED_CONTENT"/>
+  <int value="201" label="ERR_UNSUPPORTED_FEATURE"/>
+  <int value="202" label="ERR_PROTO_TOO_LARGE"/>
+  <int value="203" label="ERR_POOR_FRAME_RATE"/>
+  <int value="204" label="ERR_CHUNKED_TEXT_WITH_SINGLE_CHUNK"/>
+</enum>
+
 <enum name="PingResult">
   <int value="0" label="Success"/>
   <int value="1" label="Response started"/>
@@ -49552,6 +49584,7 @@
   <int value="18" label="ACCEPTED_MATCHING_VARY"/>
   <int value="19" label="PUSH_DISABLED"/>
   <int value="20" label="ALREADY_IN_CACHE"/>
+  <int value="21" label="UNSUPPORTED_STATUS_CODE"/>
 </enum>
 
 <enum name="SpdySessionGet">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index cfa0c11..0e2009f5 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -9587,7 +9587,7 @@
 </histogram>
 
 <histogram name="BackgroundMode.TimeBeforeOptimizedRestart" units="ms">
-  <owner>dgn@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>
     The duration of a session before the browser got restarted in the background
     by the BackgroundOptimizer to purge the memory.
@@ -17280,6 +17280,26 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSuggestions.Feed.InterestHeader.NotInterestedInSource"
+    units="index" expires_after="2020-02-01">
+  <owner>gangwu@chromium.org</owner>
+  <owner>fgorski@chromium.org</owner>
+  <summary>
+    The position of an interest header on the NTP that the user has indicated
+    they aren't interested in the story's source.
+  </summary>
+</histogram>
+
+<histogram name="ContentSuggestions.Feed.InterestHeader.NotInterestedInTopic"
+    units="index" expires_after="2020-02-01">
+  <owner>gangwu@chromium.org</owner>
+  <owner>fgorski@chromium.org</owner>
+  <summary>
+    The position of an interest header on the NTP that the user has indicated
+    they aren't interested in the story's topic.
+  </summary>
+</histogram>
+
 <histogram name="ContentSuggestions.Feed.LoadKeysSuccess" enum="BooleanSuccess"
     expires_after="2019-10-01">
   <owner>gangwu@chromium.org</owner>
@@ -17417,6 +17437,16 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSuggestions.Feed.Piet.FrameRenderingErrorCode"
+    enum="PietErrorCode" expires_after="2020-02-01">
+  <owner>gangwu@chromium.org</owner>
+  <owner>fgorski@chromium.org</owner>
+  <summary>
+    Android: The integer error code when Piet wants to report events that
+    occurred during Frame rendering.
+  </summary>
+</histogram>
+
 <histogram name="ContentSuggestions.Feed.RequestSizeKB.Compressed" units="KB">
   <obsolete>
     Deprecated in favor of
@@ -37651,7 +37681,7 @@
 </histogram>
 
 <histogram name="GCM.CheckinRequestStatus" enum="GCMCheckinRequestStatus">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>Status code of the outcome of a GCM checkin request.</summary>
 </histogram>
 
@@ -37687,7 +37717,7 @@
 </histogram>
 
 <histogram name="GCM.ConnectionLatency" units="ms">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>
     The time between the initiation of a connection and the successful
     completion of it.
@@ -37778,7 +37808,7 @@
 </histogram>
 
 <histogram name="GCM.DataMessageBurstReceivedInterval" units="ms">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>
     Interval between two successive received data message bursts.
   </summary>
@@ -37830,7 +37860,7 @@
 </histogram>
 
 <histogram name="GCM.FirstReceivedDataMessageLatencyAfterConnection" units="ms">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>
     The time between the successful completion of the connection and the arrival
     of the first data message.
@@ -37908,12 +37938,12 @@
 </histogram>
 
 <histogram name="GCM.ReceivedDataMessageBurstSize" units="messages">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>Number of messages in a received GCM data message burst.</summary>
 </histogram>
 
 <histogram name="GCM.ReceivedDataMessageIntervalWithinBurst" units="ms">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>
     Interval between messages within a received GCM data message burst.
   </summary>
@@ -37950,7 +37980,7 @@
 
 <histogram name="GCM.RegistrationRequestStatus"
     enum="GCMRegistrationRequestStatus">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>
     Status code of the outcome of a GCM registration request. The Unknown error
     case was split up in M56 (merged mid-beta to M55) to separate out the
@@ -38068,7 +38098,7 @@
 
 <histogram name="GCM.UnregistrationRequestStatus"
     enum="GCMUnregistrationRequestStatus">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>Status code of the outcome of a GCM unregistration request.</summary>
 </histogram>
 
@@ -42573,7 +42603,7 @@
 
 <histogram name="InstanceID.DeleteToken.RequestStatus"
     enum="GCMUnregistrationRequestStatus">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>Status code of the outcome of DeleteToken request.</summary>
 </histogram>
 
@@ -42612,7 +42642,7 @@
 
 <histogram name="InstanceID.GetToken.RequestStatus"
     enum="GCMRegistrationRequestStatus">
-  <owner>juyik@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>Status code of the outcome of GetToken request.</summary>
 </histogram>
 
@@ -44720,7 +44750,8 @@
 </histogram>
 
 <histogram name="Launch.WebAppDisplayMode" enum="WebAppDisplayMode">
-  <owner>piotrs@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
+  <owner>yfriedman@chromium.org</owner>
   <summary>
     Records the display mode (as defined in the Web App Manifest spec) at the
     launch of the Added to Home screen or installed Web App (including WebAPKs).
@@ -49739,6 +49770,17 @@
   </summary>
 </histogram>
 
+<histogram name="Media.Session.UserAction.Focus" enum="BooleanFocused"
+    expires_after="M77">
+  <owner>steimel@chromium.org</owner>
+  <owner>media-dev@chromium.org</owner>
+  <summary>
+    The focused state of the WebContents associated with the MediaSession that
+    the user is interacting with. Recorded when the user interacts with a
+    MediaSession (e.g. by pressing the play/pause key on their keyboard).
+  </summary>
+</histogram>
+
 <histogram name="Media.SRC.PreloadAutoHasPoster" enum="Boolean">
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -71808,7 +71850,7 @@
 
 <histogram name="Notifications.NotificationHelper.ComServerModuleStatus"
     enum="NotificationHelperComServerModuleStatus">
-  <owner>chengx@chromium.org</owner>
+  <owner>finnur@chromium.org</owner>
   <summary>
     The execute status of a ComServerModule class instance. Logged whenever a
     notification_helper process is launched by Windows.
@@ -71851,7 +71893,7 @@
 </histogram>
 
 <histogram name="Notifications.NotificationHelper.ServerRuntime" units="ms">
-  <owner>chengx@chromium.org</owner>
+  <owner>finnur@chromium.org</owner>
   <summary>
     The runtime of the notification_helper server process. This process is
     created when a notification is activated from the Windows Action Center.
@@ -91297,7 +91339,7 @@
 </histogram>
 
 <histogram name="PushMessaging.ReceivedMessageInBackground" enum="Boolean">
-  <owner>dgn@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
   <summary>
     Whenever a Service Worker receives a push message, this records whether
     Chrome is completely running in the background. A successful report means
@@ -114162,26 +114204,6 @@
   </summary>
 </histogram>
 
-<histogram name="Sync.AutofillProfile.AddOrUpdateOrigin"
-    enum="AutofillProfileSyncChangeOrigin" expires_after="M75">
-  <owner>jkrcal@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Reported for autofill profile sync once per every locally committed entity
-    creation/update. It breaks down the origin of such a local change.
-  </summary>
-</histogram>
-
-<histogram name="Sync.AutofillProfile.DeleteOrigin"
-    enum="AutofillProfileSyncChangeOrigin" expires_after="M73">
-  <owner>jkrcal@chromium.org</owner>
-  <owner>treib@chromium.org</owner>
-  <summary>
-    Reported for autofill profile sync once per every locally committed entity
-    deletion. It breaks down the origin of such a local deletion.
-  </summary>
-</histogram>
-
 <histogram name="Sync.AutofillProfileAssociationTime" units="ms">
   <obsolete>
     Replaced by Sync.AutofillProfilesAssociationTime.
@@ -125949,7 +125971,8 @@
 </histogram>
 
 <histogram name="Webapp.Install.DisplayMode" enum="WebAppDisplayMode">
-  <owner>piotrs@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
+  <owner>yfriedman@chromium.org</owner>
   <summary>
     Records the display mode (as defined in the Web App Manifest spec) at the
     install time of a WebApp (including WebApks).
@@ -126007,7 +126030,8 @@
 </histogram>
 
 <histogram name="Webapp.NavigationStatus" enum="BooleanSuccess">
-  <owner>piotrs@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
+  <owner>yfriedman@chromium.org</owner>
   <summary>
     Records whether the top-level navigations in standalone Web Apps result in
     presenting the web content or showing the error page.
@@ -133952,6 +133976,17 @@
   <affected-histogram name="NewTabPage.ContentSuggestions.VisitDuration"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="ContentSuggestionUndoableActions" separator=".">
+  <suffix name="Commit" label="Action was committed"/>
+  <suffix name="Undo" label="Action was undone"/>
+  <affected-histogram
+      name="ContentSuggestions.Feed.InterestHeader.NotInterestedInSource"/>
+  <affected-histogram
+      name="ContentSuggestions.Feed.InterestHeader.NotInterestedInTopic"/>
+  <affected-histogram name="NewTabPage.ContentSuggestions.DismissedUnvisited"/>
+  <affected-histogram name="NewTabPage.ContentSuggestions.DismissedVisited"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="ContextMenuFromApp" separator=".">
   <suffix name="FromApp" label="The source of the context menu was an app."/>
   <suffix name="NotFromApp"
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc
index f1b8e81..36e69d7 100644
--- a/ui/accessibility/ax_node_position_unittest.cc
+++ b/ui/accessibility/ax_node_position_unittest.cc
@@ -1681,7 +1681,7 @@
 // Instantiations of parameterized tests.
 //
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextWordStartPositionWithBoundaryBehaviorCrossBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -1746,7 +1746,7 @@
                    "affinity=downstream annotated_text=Line <2>",
                    "NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextWordStartPositionWithBoundaryBehaviorStopAtAnchorBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -1812,7 +1812,7 @@
                    "TextPosition anchor_id=9 text_offset=6 "
                    "affinity=downstream annotated_text=Line 2<>"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextWordStartPositionWithBoundaryBehaviorStopIfAlreadyAtBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -1859,7 +1859,7 @@
                    "TextPosition anchor_id=9 text_offset=5 "
                    "affinity=downstream annotated_text=Line <2>"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousWordStartPositionWithBoundaryBehaviorCrossBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -1947,7 +1947,7 @@
                    "affinity=downstream annotated_text=<B>utton",
                    "NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousWordStartPositionWithBoundaryBehaviorStopAtAnchorBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2018,7 +2018,7 @@
                    "TextPosition anchor_id=9 text_offset=0 "
                    "affinity=downstream annotated_text=<L>ine 2"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousWordStartPositionWithBoundaryBehaviorStopIfAlreadyAtBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2063,7 +2063,7 @@
                    "TextPosition anchor_id=9 text_offset=0 "
                    "affinity=downstream annotated_text=<L>ine 2"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextWordEndPositionWithBoundaryBehaviorCrossBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2135,7 +2135,7 @@
                    "affinity=downstream annotated_text=Line 2<>",
                    "NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextWordEndPositionWithBoundaryBehaviorStopAtAnchorBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2208,7 +2208,7 @@
                    "TextPosition anchor_id=9 text_offset=6 "
                    "affinity=downstream annotated_text=Line 2<>"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextWordEndPositionWithBoundaryBehaviorStopIfAlreadyAtBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2253,7 +2253,7 @@
                   {"TextPosition anchor_id=9 text_offset=4 "
                    "affinity=downstream annotated_text=Line< >2"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousWordEndPositionWithBoundaryBehaviorCrossBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2334,7 +2334,7 @@
                    "affinity=downstream annotated_text=Button<>",
                    "NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousWordEndPositionWithBoundaryBehaviorStopAtAnchorBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2398,7 +2398,7 @@
                   {"TextPosition anchor_id=9 text_offset=0 "
                    "affinity=downstream annotated_text=<L>ine 2"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousWordEndPositionWithBoundaryBehaviorStopIfAlreadyAtBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2438,7 +2438,7 @@
                   {"TextPosition anchor_id=9 text_offset=4 "
                    "affinity=downstream annotated_text=Line< >2"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextLineStartPositionWithBoundaryBehaviorCrossBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2481,7 +2481,7 @@
                   4 /* text_offset */,
                   {"NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextLineStartPositionWithBoundaryBehaviorStopAtAnchorBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2527,7 +2527,7 @@
                   {"TextPosition anchor_id=9 text_offset=6 "
                    "affinity=downstream annotated_text=Line 2<>"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextLineStartPositionWithBoundaryBehaviorStopIfAlreadyAtBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2566,7 +2566,7 @@
                   4 /* text_offset */,
                   {"NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousLineStartPositionWithBoundaryBehaviorCrossBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2624,7 +2624,7 @@
                    "affinity=downstream annotated_text=<B>utton",
                    "NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousLineStartPositionWithBoundaryBehaviorStopAtAnchorBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2679,7 +2679,7 @@
                    "TextPosition anchor_id=9 text_offset=0 "
                    "affinity=downstream annotated_text=<L>ine 2"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousLineStartPositionWithBoundaryBehaviorStopIfAlreadyAtBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2726,7 +2726,7 @@
                    "TextPosition anchor_id=9 text_offset=0 "
                    "affinity=downstream annotated_text=<L>ine 2"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextLineEndPositionWithBoundaryBehaviorCrossBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2778,7 +2778,7 @@
                    "affinity=downstream annotated_text=Line 2<>",
                    "NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextLineEndPositionWithBoundaryBehaviorStopAtAnchorBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2833,7 +2833,7 @@
                    "TextPosition anchor_id=9 text_offset=6 "
                    "affinity=downstream annotated_text=Line 2<>"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreateNextLineEndPositionWithBoundaryBehaviorStopIfAlreadyAtBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2880,7 +2880,7 @@
                    "TextPosition anchor_id=9 text_offset=6 "
                    "affinity=downstream annotated_text=Line 2<>"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousLineEndPositionWithBoundaryBehaviorCrossBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -2956,7 +2956,7 @@
                    "affinity=downstream annotated_text=Check box<>",
                    "NullPosition"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousLineEndPositionWithBoundaryBehaviorStopAtAnchorBoundary,
     AXPositionTestWithParam,
     testing::Values(
@@ -3025,7 +3025,7 @@
                   {"TextPosition anchor_id=9 text_offset=0 "
                    "affinity=downstream annotated_text=<L>ine 2"}}));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     CreatePreviousLineEndPositionWithBoundaryBehaviorStopIfAlreadyAtBoundary,
     AXPositionTestWithParam,
     testing::Values(
diff --git a/ui/aura/mus/client_side_window_move_handler_unittest.cc b/ui/aura/mus/client_side_window_move_handler_unittest.cc
index 91aa3df..b27353f 100644
--- a/ui/aura/mus/client_side_window_move_handler_unittest.cc
+++ b/ui/aura/mus/client_side_window_move_handler_unittest.cc
@@ -291,7 +291,7 @@
   EXPECT_FALSE(observer.in_window_move());
 }
 
-INSTANTIATE_TEST_CASE_P(,
-                        ClientSideWindowMoveHandlerTest,
-                        ::testing::Values("mouse", "touch"));
+INSTANTIATE_TEST_SUITE_P(,
+                         ClientSideWindowMoveHandlerTest,
+                         ::testing::Values("mouse", "touch"));
 }  // namespace aura
diff --git a/ui/aura_extra/window_occlusion_impl_unittest_win.cc b/ui/aura_extra/window_occlusion_impl_unittest_win.cc
index c492eed..50bb76e 100644
--- a/ui/aura_extra/window_occlusion_impl_unittest_win.cc
+++ b/ui/aura_extra/window_occlusion_impl_unittest_win.cc
@@ -255,35 +255,39 @@
   EXPECT_EQ(result[window], aura::Window::OcclusionState::VISIBLE);
 }
 
-INSTANTIATE_TEST_CASE_P(/* no prefix */
-                        ,
-                        WindowOcclusionWinTest,
-                        ::testing::Values(
-                            OffsetAndBoundsPair(5, gfx::Rect(0, 0, 100, 100)),
-                            OffsetAndBoundsPair(10, gfx::Rect(0, 0, 100, 200)),
-                            OffsetAndBoundsPair(15, gfx::Rect(0, 0, 200, 100)),
-                            OffsetAndBoundsPair(20, gfx::Rect(0, 0, 200, 200)),
-                            OffsetAndBoundsPair(25, gfx::Rect(0, 50, 100, 100)),
-                            OffsetAndBoundsPair(50, gfx::Rect(0, 50, 100, 200)),
-                            OffsetAndBoundsPair(75, gfx::Rect(0, 50, 200, 100)),
-                            OffsetAndBoundsPair(100,
-                                                gfx::Rect(0, 50, 200, 200)),
-                            OffsetAndBoundsPair(125,
-                                                gfx::Rect(100, 0, 100, 100)),
-                            OffsetAndBoundsPair(150,
-                                                gfx::Rect(100, 0, 100, 200)),
-                            OffsetAndBoundsPair(200,
-                                                gfx::Rect(100, 0, 200, 100)),
-                            OffsetAndBoundsPair(250,
-                                                gfx::Rect(100, 0, 200, 200)),
-                            OffsetAndBoundsPair(300,
-                                                gfx::Rect(100, 50, 100, 100)),
-                            OffsetAndBoundsPair(400,
-                                                gfx::Rect(100, 50, 100, 200)),
-                            OffsetAndBoundsPair(500,
-                                                gfx::Rect(100, 50, 200, 100)),
-                            OffsetAndBoundsPair(750,
-                                                gfx::Rect(100, 50, 200, 200))));
+INSTANTIATE_TEST_SUITE_P(/* no prefix */
+                         ,
+                         WindowOcclusionWinTest,
+                         ::testing::Values(
+                             OffsetAndBoundsPair(5, gfx::Rect(0, 0, 100, 100)),
+                             OffsetAndBoundsPair(10, gfx::Rect(0, 0, 100, 200)),
+                             OffsetAndBoundsPair(15, gfx::Rect(0, 0, 200, 100)),
+                             OffsetAndBoundsPair(20, gfx::Rect(0, 0, 200, 200)),
+                             OffsetAndBoundsPair(25,
+                                                 gfx::Rect(0, 50, 100, 100)),
+                             OffsetAndBoundsPair(50,
+                                                 gfx::Rect(0, 50, 100, 200)),
+                             OffsetAndBoundsPair(75,
+                                                 gfx::Rect(0, 50, 200, 100)),
+                             OffsetAndBoundsPair(100,
+                                                 gfx::Rect(0, 50, 200, 200)),
+                             OffsetAndBoundsPair(125,
+                                                 gfx::Rect(100, 0, 100, 100)),
+                             OffsetAndBoundsPair(150,
+                                                 gfx::Rect(100, 0, 100, 200)),
+                             OffsetAndBoundsPair(200,
+                                                 gfx::Rect(100, 0, 200, 100)),
+                             OffsetAndBoundsPair(250,
+                                                 gfx::Rect(100, 0, 200, 200)),
+                             OffsetAndBoundsPair(300,
+                                                 gfx::Rect(100, 50, 100, 100)),
+                             OffsetAndBoundsPair(400,
+                                                 gfx::Rect(100, 50, 100, 200)),
+                             OffsetAndBoundsPair(500,
+                                                 gfx::Rect(100, 50, 200, 100)),
+                             OffsetAndBoundsPair(
+                                 750,
+                                 gfx::Rect(100, 50, 200, 200))));
 
 class WindowFitnessFunctionTest : public testing::Test {
  public:
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h
index ce83df2c..e75b936 100644
--- a/ui/base/clipboard/clipboard_test_template.h
+++ b/ui/base/clipboard/clipboard_test_template.h
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Note: This header doesn't use REGISTER_TYPED_TEST_CASE_P like most
+// Note: This header doesn't use REGISTER_TYPED_TEST_SUITE_P like most
 // type-parameterized gtests. There are lot of test cases in here that are only
 // enabled on certain platforms. However, preprocessor directives in macro
 // arguments result in undefined behavior (and don't work on MSVC). Instead,
diff --git a/ui/base/cursor/cursor_util_unittest.cc b/ui/base/cursor/cursor_util_unittest.cc
index 360f7fa..d9265c0 100644
--- a/ui/base/cursor/cursor_util_unittest.cc
+++ b/ui/base/cursor/cursor_util_unittest.cc
@@ -64,7 +64,7 @@
   EXPECT_EQ(pixel_color, bitmap.pixmap().getColor(0, 0));
 }
 
-INSTANTIATE_TEST_CASE_P(, CursorUtilTest, testing::Bool());
+INSTANTIATE_TEST_SUITE_P(, CursorUtilTest, testing::Bool());
 
 }  // namespace
 }  // namespace ui
diff --git a/ui/base/dragdrop/os_exchange_data_provider_builder_mac.mm b/ui/base/dragdrop/os_exchange_data_provider_builder_mac.mm
index a115b31..e8d108a 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_builder_mac.mm
+++ b/ui/base/dragdrop/os_exchange_data_provider_builder_mac.mm
@@ -9,7 +9,7 @@
 namespace ui {
 
 std::unique_ptr<OSExchangeData::Provider> BuildOSExchangeDataProviderMac() {
-  return OSExchangeDataProviderMac::CreateProvider();
+  return std::make_unique<OSExchangeDataProviderMac>();
 }
 
 }  // namespace ui
diff --git a/ui/base/dragdrop/os_exchange_data_provider_mac.h b/ui/base/dragdrop/os_exchange_data_provider_mac.h
index 0b61404..5ba2a69 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_mac.h
+++ b/ui/base/dragdrop/os_exchange_data_provider_mac.h
@@ -5,9 +5,6 @@
 #ifndef UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_MAC_H_
 #define UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_MAC_H_
 
-#include <memory>
-
-#include "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #import "ui/base/clipboard/clipboard_util_mac.h"
@@ -17,27 +14,21 @@
 
 @class NSArray;
 @class NSData;
-@class NSDraggingItem;
 @class NSPasteboard;
 @class NSString;
 
 namespace ui {
+class UniquePasteboard;
 
 // OSExchangeData::Provider implementation for Mac.
 class UI_BASE_EXPORT OSExchangeDataProviderMac
     : public OSExchangeData::Provider {
  public:
+  OSExchangeDataProviderMac();
   ~OSExchangeDataProviderMac() override;
 
-  // Creates a stand-alone OSExchangeDataProviderMac.
-  static std::unique_ptr<OSExchangeDataProviderMac> CreateProvider();
-
-  // Creates an OSExchangeDataProviderMac object wrapping the given NSPasteboard
-  // object.
-  static std::unique_ptr<OSExchangeDataProviderMac>
-  CreateProviderWrappingPasteboard(NSPasteboard* pasteboard);
-
   // Overridden from OSExchangeData::Provider:
+  std::unique_ptr<Provider> Clone() const override;
   void MarkOriginatedFromRenderer() override;
   bool DidOriginateFromRenderer() const override;
   void SetString(const base::string16& data) override;
@@ -63,26 +54,33 @@
   gfx::ImageSkia GetDragImage() const override;
   gfx::Vector2d GetDragImageOffset() const override;
 
-  // Gets the underlying pasteboard.
-  virtual NSPasteboard* GetPasteboard() const = 0;
+  // Returns the data for the specified type in the pasteboard.
+  NSData* GetNSDataForType(NSString* type) const;
 
-  // Returns an NSDraggingItem useful for initiating a drag. (Currently
-  // OSExchangeDataProviderMac can only have one item.)
-  NSDraggingItem* GetDraggingItem() const;
+  // Gets the underlying pasteboard.
+  NSPasteboard* GetPasteboard() const;
+
+  // Returns the union of SupportedPasteboardTypes() and the types in the
+  // current pasteboard.
+  NSArray* GetAvailableTypes() const;
+
+  // Creates an OSExchangeData object from the given NSPasteboard object.
+  static std::unique_ptr<OSExchangeData> CreateDataFromPasteboard(
+      NSPasteboard* pasteboard);
 
   // Returns an array of pasteboard types that can be supported by
   // OSExchangeData.
   static NSArray* SupportedPasteboardTypes();
 
- protected:
-  OSExchangeDataProviderMac();
-  OSExchangeDataProviderMac(const OSExchangeDataProviderMac&);
-  OSExchangeDataProviderMac& operator=(const OSExchangeDataProviderMac&);
-
  private:
+  explicit OSExchangeDataProviderMac(scoped_refptr<ui::UniquePasteboard>);
+  scoped_refptr<ui::UniquePasteboard> pasteboard_;
+
   // Drag image and offset data.
   gfx::ImageSkia drag_image_;
   gfx::Vector2d cursor_offset_;
+
+  DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderMac);
 };
 
 }  // namespace ui
diff --git a/ui/base/dragdrop/os_exchange_data_provider_mac.mm b/ui/base/dragdrop/os_exchange_data_provider_mac.mm
index 3e5f603..68e89f0 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_mac.mm
+++ b/ui/base/dragdrop/os_exchange_data_provider_mac.mm
@@ -20,108 +20,22 @@
 #include "ui/base/dragdrop/file_info.h"
 #include "url/gurl.h"
 
-@interface CrPasteboardItemWrapper : NSObject <NSPasteboardWriting>
-- (instancetype)initWithPasteboardItem:(NSPasteboardItem*)pasteboardItem;
-@end
-
-@implementation CrPasteboardItemWrapper {
-  base::scoped_nsobject<NSPasteboardItem> pasteboardItem_;
-}
-
-- (instancetype)initWithPasteboardItem:(NSPasteboardItem*)pasteboardItem {
-  if ((self = [super init])) {
-    pasteboardItem_.reset([pasteboardItem retain]);
-  }
-
-  return self;
-}
-
-- (NSArray<NSString*>*)writableTypesForPasteboard:(NSPasteboard*)pasteboard {
-  // If the NSPasteboardItem hasn't been added to an NSPasteboard, then the
-  // -[NSPasteboardItem writableTypesForPasteboard:] will return -types. But if
-  // it has been added to a pasteboard, it will return nil.
-  //
-  // This pasteboard item was added implicitly by adding flavors to the owned
-  // pasteboard of OwningProvider, so call -types to actually get data.
-  return [pasteboardItem_ types];
-}
-- (NSPasteboardWritingOptions)writingOptionsForType:(NSString*)type
-                                         pasteboard:(NSPasteboard*)pasteboard {
-  // It is critical to return 0 here. If any flavors are promised, then when the
-  // app quits, AppKit will call in the promises, and the backing pasteboard
-  // will likely be long-deallocated. Yes, AppKit will call in promises for
-  // *all* promised flavors on *all* pasteboards, not just those pasteboards
-  // used for copy/paste.
-  return 0;
-}
-- (id)pasteboardPropertyListForType:(NSString*)type {
-  // Like above, an NSPasteboardItem added to a pasteboard will return nil from
-  // -pasteboardPropertyListForType:, so call -dataForType: instead.
-  return [pasteboardItem_ dataForType:type];
-}
-
-@end
-
 namespace ui {
 
-namespace {
+OSExchangeDataProviderMac::OSExchangeDataProviderMac()
+    : pasteboard_(new ui::UniquePasteboard) {}
 
-class OwningProvider : public OSExchangeDataProviderMac {
- public:
-  OwningProvider()
-      : OSExchangeDataProviderMac(),
-        owned_pasteboard_(new ui::UniquePasteboard) {}
-  OwningProvider(const OwningProvider& provider) = default;
-
-  std::unique_ptr<OSExchangeData::Provider> Clone() const override {
-    return std::make_unique<OwningProvider>(*this);
-  }
-
-  NSPasteboard* GetPasteboard() const override {
-    return owned_pasteboard_->get();
-  }
-
- private:
-  scoped_refptr<ui::UniquePasteboard> owned_pasteboard_;
-};
-
-class WrappingProvider : public OSExchangeDataProviderMac {
- public:
-  WrappingProvider(NSPasteboard* pasteboard)
-      : OSExchangeDataProviderMac(), wrapped_pasteboard_([pasteboard retain]) {}
-  WrappingProvider(const WrappingProvider& provider) = default;
-
-  std::unique_ptr<OSExchangeData::Provider> Clone() const override {
-    return std::make_unique<WrappingProvider>(*this);
-  }
-
-  NSPasteboard* GetPasteboard() const override { return wrapped_pasteboard_; }
-
- private:
-  base::scoped_nsobject<NSPasteboard> wrapped_pasteboard_;
-};
-
-}  // namespace
-
-OSExchangeDataProviderMac::OSExchangeDataProviderMac() = default;
 OSExchangeDataProviderMac::OSExchangeDataProviderMac(
-    const OSExchangeDataProviderMac&) = default;
-OSExchangeDataProviderMac& OSExchangeDataProviderMac::operator=(
-    const OSExchangeDataProviderMac&) = default;
+    scoped_refptr<ui::UniquePasteboard> pb)
+    : pasteboard_(pb) {}
 
-OSExchangeDataProviderMac::~OSExchangeDataProviderMac() = default;
-
-// static
-std::unique_ptr<OSExchangeDataProviderMac>
-OSExchangeDataProviderMac::CreateProvider() {
-  return std::make_unique<OwningProvider>();
+OSExchangeDataProviderMac::~OSExchangeDataProviderMac() {
 }
 
-// static
-std::unique_ptr<OSExchangeDataProviderMac>
-OSExchangeDataProviderMac::CreateProviderWrappingPasteboard(
-    NSPasteboard* pasteboard) {
-  return std::make_unique<WrappingProvider>(pasteboard);
+std::unique_ptr<OSExchangeData::Provider>
+OSExchangeDataProviderMac::Clone() const {
+  return std::unique_ptr<OSExchangeData::Provider>(
+      new OSExchangeDataProviderMac(pasteboard_));
 }
 
 void OSExchangeDataProviderMac::MarkOriginatedFromRenderer() {
@@ -134,8 +48,8 @@
 }
 
 void OSExchangeDataProviderMac::SetString(const base::string16& string) {
-  [GetPasteboard() setString:base::SysUTF16ToNSString(string)
-                     forType:NSPasteboardTypeString];
+  [pasteboard_->get() setString:base::SysUTF16ToNSString(string)
+                        forType:NSPasteboardTypeString];
 }
 
 void OSExchangeDataProviderMac::SetURL(const GURL& url,
@@ -143,12 +57,12 @@
   base::scoped_nsobject<NSPasteboardItem> item =
       ClipboardUtil::PasteboardItemFromUrl(base::SysUTF8ToNSString(url.spec()),
                                            base::SysUTF16ToNSString(title));
-  ui::ClipboardUtil::AddDataToPasteboard(GetPasteboard(), item);
+  ui::ClipboardUtil::AddDataToPasteboard(pasteboard_->get(), item);
 }
 
 void OSExchangeDataProviderMac::SetFilename(const base::FilePath& path) {
-  [GetPasteboard() setPropertyList:@[ base::SysUTF8ToNSString(path.value()) ]
-                           forType:NSFilenamesPboardType];
+  [pasteboard_->get() setPropertyList:@[ base::SysUTF8ToNSString(path.value()) ]
+                              forType:NSFilenamesPboardType];
 }
 
 void OSExchangeDataProviderMac::SetFilenames(
@@ -162,19 +76,19 @@
     NSString* path = base::SysUTF8ToNSString(filename.path.value());
     [paths addObject:path];
   }
-  [GetPasteboard() setPropertyList:paths forType:NSFilenamesPboardType];
+  [pasteboard_->get() setPropertyList:paths forType:NSFilenamesPboardType];
 }
 
 void OSExchangeDataProviderMac::SetPickledData(
     const ClipboardFormatType& format,
     const base::Pickle& data) {
   NSData* ns_data = [NSData dataWithBytes:data.data() length:data.size()];
-  [GetPasteboard() setData:ns_data forType:format.ToNSString()];
+  [pasteboard_->get() setData:ns_data forType:format.ToNSString()];
 }
 
 bool OSExchangeDataProviderMac::GetString(base::string16* data) const {
   DCHECK(data);
-  NSString* item = [GetPasteboard() stringForType:NSPasteboardTypeString];
+  NSString* item = [pasteboard_->get() stringForType:NSPasteboardTypeString];
   if (item) {
     *data = base::SysNSStringToUTF16(item);
     return true;
@@ -198,7 +112,7 @@
   DCHECK(url);
   DCHECK(title);
 
-  if (ui::PopulateURLAndTitleFromPasteboard(url, title, GetPasteboard(),
+  if (ui::PopulateURLAndTitleFromPasteboard(url, title, pasteboard_->get(),
                                             false)) {
     return true;
   }
@@ -224,7 +138,8 @@
 }
 
 bool OSExchangeDataProviderMac::GetFilename(base::FilePath* path) const {
-  NSArray* paths = [GetPasteboard() propertyListForType:NSFilenamesPboardType];
+  NSArray* paths =
+      [pasteboard_->get() propertyListForType:NSFilenamesPboardType];
   if ([paths count] == 0)
     return false;
 
@@ -234,7 +149,8 @@
 
 bool OSExchangeDataProviderMac::GetFilenames(
     std::vector<FileInfo>* filenames) const {
-  NSArray* paths = [GetPasteboard() propertyListForType:NSFilenamesPboardType];
+  NSArray* paths =
+      [pasteboard_->get() propertyListForType:NSFilenamesPboardType];
   if ([paths count] == 0)
     return false;
 
@@ -249,7 +165,7 @@
     const ClipboardFormatType& format,
     base::Pickle* data) const {
   DCHECK(data);
-  NSData* ns_data = [GetPasteboard() dataForType:format.ToNSString()];
+  NSData* ns_data = [pasteboard_->get() dataForType:format.ToNSString()];
   if (!ns_data)
     return false;
 
@@ -271,12 +187,12 @@
 }
 
 bool OSExchangeDataProviderMac::HasFile() const {
-  return [[GetPasteboard() types] containsObject:NSFilenamesPboardType];
+  return [[pasteboard_->get() types] containsObject:NSFilenamesPboardType];
 }
 
 bool OSExchangeDataProviderMac::HasCustomFormat(
     const ClipboardFormatType& format) const {
-  return [[GetPasteboard() types] containsObject:format.ToNSString()];
+  return [[pasteboard_->get() types] containsObject:format.ToNSString()];
 }
 
 void OSExchangeDataProviderMac::SetDragImage(
@@ -294,30 +210,32 @@
   return cursor_offset_;
 }
 
-NSDraggingItem* OSExchangeDataProviderMac::GetDraggingItem() const {
-  // What's going on here is that initiating a drag (-[NSView
-  // beginDraggingSessionWithItems...]) requires a dragging item. Even though
-  // pasteboard items are NSPasteboardWriters, they are locked to their
-  // pasteboard and cannot be used to initiate a drag with another pasteboard
-  // (hello https://crbug.com/928684). Therefore, wrap them.
-  //
-  // OSExchangeDataProviderMac was written to the old NSPasteboard APIs that
-  // didn't account for more than one item. This kinda matches Views which also
-  // assumes that only one drag item can exist at a time. TODO(avi): Fix all of
-  // Views to be able to handle drags of more than one item. Then rewrite
-  // OSExchangeDataProviderMac to the new NSPasteboard item API.
+NSData* OSExchangeDataProviderMac::GetNSDataForType(NSString* type) const {
+  return [pasteboard_->get() dataForType:type];
+}
 
-  NSArray* pasteboardItems = [GetPasteboard() pasteboardItems];
-  DCHECK(pasteboardItems);
-  DCHECK_EQ(1u, [pasteboardItems count]);
+NSPasteboard* OSExchangeDataProviderMac::GetPasteboard() const {
+  return pasteboard_->get();
+}
 
-  CrPasteboardItemWrapper* wrapper = [[[CrPasteboardItemWrapper alloc]
-      initWithPasteboardItem:[pasteboardItems firstObject]] autorelease];
+NSArray* OSExchangeDataProviderMac::GetAvailableTypes() const {
+  NSSet* supportedTypes = [NSSet setWithArray:SupportedPasteboardTypes()];
+  NSMutableSet* availableTypes =
+      [NSMutableSet setWithArray:[pasteboard_->get() types]];
+  [availableTypes unionSet:supportedTypes];
+  return [availableTypes allObjects];
+}
 
-  NSDraggingItem* drag_item =
-      [[[NSDraggingItem alloc] initWithPasteboardWriter:wrapper] autorelease];
+// static
+std::unique_ptr<OSExchangeData>
+OSExchangeDataProviderMac::CreateDataFromPasteboard(NSPasteboard* pasteboard) {
+  OSExchangeDataProviderMac* provider = new OSExchangeDataProviderMac();
 
-  return drag_item;
+  for (NSPasteboardItem* item in [pasteboard pasteboardItems])
+    ClipboardUtil::AddDataToPasteboard(provider->pasteboard_->get(), item);
+
+  return std::make_unique<OSExchangeData>(
+      base::WrapUnique<OSExchangeData::Provider>(provider));
 }
 
 // static
diff --git a/ui/base/ime/win/imm32_manager_unittest.cc b/ui/base/ime/win/imm32_manager_unittest.cc
index 07353be..65663a9 100644
--- a/ui/base/ime/win/imm32_manager_unittest.cc
+++ b/ui/base/ime/win/imm32_manager_unittest.cc
@@ -61,9 +61,9 @@
   EXPECT_EQ(test_case.expected_conversion_mode, conversion_mode);
 }
 
-INSTANTIATE_TEST_CASE_P(,
-                        IMM32ManagerTest,
-                        ::testing::ValuesIn(kInputModeTestCases));
+INSTANTIATE_TEST_SUITE_P(,
+                         IMM32ManagerTest,
+                         ::testing::ValuesIn(kInputModeTestCases));
 
 }  // namespace
 }  // namespace ui
diff --git a/ui/base/ime/win/tsf_input_scope_unittest.cc b/ui/base/ime/win/tsf_input_scope_unittest.cc
index 237e4e49a..9c10d47 100644
--- a/ui/base/ime/win/tsf_input_scope_unittest.cc
+++ b/ui/base/ime/win/tsf_input_scope_unittest.cc
@@ -99,9 +99,9 @@
     EXPECT_EQ(test_case.expected_input_scopes[i], input_scopes[i]);
 }
 
-INSTANTIATE_TEST_CASE_P(,
-                        TSFInputScopeTest,
-                        ::testing::ValuesIn(kGetInputScopesTestCases));
+INSTANTIATE_TEST_SUITE_P(,
+                         TSFInputScopeTest,
+                         ::testing::ValuesIn(kGetInputScopesTestCases));
 
 }  // namespace
 }  // namespace ui
diff --git a/ui/base/resource/data_pack_unittest.cc b/ui/base/resource/data_pack_unittest.cc
index 407ba59..9ddeee9a 100644
--- a/ui/base/resource/data_pack_unittest.cc
+++ b/ui/base/resource/data_pack_unittest.cc
@@ -188,12 +188,15 @@
   ASSERT_FALSE(pack.GetStringPiece(140, &data));
 }
 
-INSTANTIATE_TEST_CASE_P(WriteBINARY, DataPackTest, ::testing::Values(
-    DataPack::BINARY));
-INSTANTIATE_TEST_CASE_P(WriteUTF8, DataPackTest, ::testing::Values(
-    DataPack::UTF8));
-INSTANTIATE_TEST_CASE_P(WriteUTF16, DataPackTest, ::testing::Values(
-    DataPack::UTF16));
+INSTANTIATE_TEST_SUITE_P(WriteBINARY,
+                         DataPackTest,
+                         ::testing::Values(DataPack::BINARY));
+INSTANTIATE_TEST_SUITE_P(WriteUTF8,
+                         DataPackTest,
+                         ::testing::Values(DataPack::UTF8));
+INSTANTIATE_TEST_SUITE_P(WriteUTF16,
+                         DataPackTest,
+                         ::testing::Values(DataPack::UTF16));
 
 TEST(DataPackTest, LoadFileWithTruncatedHeader) {
   base::FilePath data_path;
diff --git a/ui/display/display_layout_unittest.cc b/ui/display/display_layout_unittest.cc
index a367c00..5b59d7d 100644
--- a/ui/display/display_layout_unittest.cc
+++ b/ui/display/display_layout_unittest.cc
@@ -202,156 +202,261 @@
   EXPECT_EQ(expected_secondary_display_bounds, display_list[1].bounds());
 }
 
-INSTANTIATE_TEST_CASE_P(DisplayLayoutTestZero, TwoDisplays, testing::Values(
-    std::make_tuple(
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-        DisplayPlacement::Position::LEFT, 0, 0,
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(-1024, 0, 1024, 768)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-        DisplayPlacement::Position::TOP, 0, 0,
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, -768, 1024, 768)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-        DisplayPlacement::Position::RIGHT, 0, 0,
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(800, 0, 1024, 768)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-        DisplayPlacement::Position::BOTTOM, 0, 0,
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 600, 1024, 768))));
+INSTANTIATE_TEST_SUITE_P(
+    DisplayLayoutTestZero,
+    TwoDisplays,
+    testing::Values(std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::LEFT,
+                                    0,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-1024, 0, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::TOP,
+                                    0,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, -768, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::RIGHT,
+                                    0,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(800, 0, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::BOTTOM,
+                                    0,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 600, 1024, 768))));
 
-INSTANTIATE_TEST_CASE_P(DisplayLayoutTestOffset, TwoDisplays, testing::Values(
-    std::make_tuple(
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-        DisplayPlacement::Position::LEFT, 37, 0,
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(-1024, 37, 1024, 768)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-        DisplayPlacement::Position::TOP, 37, 0,
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(37, -768, 1024, 768)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-        DisplayPlacement::Position::RIGHT, 37, 0,
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(800, 37, 1024, 768)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-        DisplayPlacement::Position::BOTTOM, 37, 0,
-        gfx::Rect(0, 0, 800, 600), gfx::Rect(37, 600, 1024, 768))));
+INSTANTIATE_TEST_SUITE_P(
+    DisplayLayoutTestOffset,
+    TwoDisplays,
+    testing::Values(std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::LEFT,
+                                    37,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-1024, 37, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::TOP,
+                                    37,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(37, -768, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::RIGHT,
+                                    37,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(800, 37, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::BOTTOM,
+                                    37,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(37, 600, 1024, 768))));
 
-INSTANTIATE_TEST_CASE_P(DisplayLayoutTestCorner, TwoDisplays, testing::Values(
-    // Top-Left
-    std::make_tuple(
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-        DisplayPlacement::Position::LEFT, -60, 0,
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(-30, -60, 30, 60)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-        DisplayPlacement::Position::TOP, -30, 0,
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(-30, -60, 30, 60)),
-    // Top-Right
-    std::make_tuple(
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-        DisplayPlacement::Position::RIGHT, -60, 0,
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(20, -60, 30, 60)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-        DisplayPlacement::Position::TOP, 20, 0,
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(20, -60, 30, 60)),
-    // Bottom-Right
-    std::make_tuple(
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-        DisplayPlacement::Position::RIGHT, 40, 0,
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(20, 40, 30, 60)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-        DisplayPlacement::Position::BOTTOM, 20, 0,
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(20, 40, 30, 60)),
-    // Bottom-Left
-    std::make_tuple(
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-        DisplayPlacement::Position::LEFT, 40, 0,
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(-30, 40, 30, 60)),
-    std::make_tuple(
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-        DisplayPlacement::Position::BOTTOM, -30, 0,
-        gfx::Rect(0, 0, 20, 40), gfx::Rect(-30, 40, 30, 60))));
+INSTANTIATE_TEST_SUITE_P(DisplayLayoutTestCorner,
+                         TwoDisplays,
+                         testing::Values(
+                             // Top-Left
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::LEFT,
+                                             -60,
+                                             0,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(-30, -60, 30, 60)),
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::TOP,
+                                             -30,
+                                             0,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(-30, -60, 30, 60)),
+                             // Top-Right
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::RIGHT,
+                                             -60,
+                                             0,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(20, -60, 30, 60)),
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::TOP,
+                                             20,
+                                             0,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(20, -60, 30, 60)),
+                             // Bottom-Right
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::RIGHT,
+                                             40,
+                                             0,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(20, 40, 30, 60)),
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::BOTTOM,
+                                             20,
+                                             0,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(20, 40, 30, 60)),
+                             // Bottom-Left
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::LEFT,
+                                             40,
+                                             0,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(-30, 40, 30, 60)),
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::BOTTOM,
+                                             -30,
+                                             0,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(-30, 40, 30, 60))));
 
-INSTANTIATE_TEST_CASE_P(DisplayLayoutTestZeroMinimumOverlap, TwoDisplays,
-    testing::Values(
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::LEFT, 0, 14,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(-1024, 0, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::TOP, 0, 14,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, -768, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::RIGHT, 0, 14,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(800, 0, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::BOTTOM, 0, 14,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 600, 1024, 768))));
+INSTANTIATE_TEST_SUITE_P(
+    DisplayLayoutTestZeroMinimumOverlap,
+    TwoDisplays,
+    testing::Values(std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::LEFT,
+                                    0,
+                                    14,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-1024, 0, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::TOP,
+                                    0,
+                                    14,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, -768, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::RIGHT,
+                                    0,
+                                    14,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(800, 0, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::BOTTOM,
+                                    0,
+                                    14,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 600, 1024, 768))));
 
-INSTANTIATE_TEST_CASE_P(DisplayLayoutTestOffsetMinimumOverlap, TwoDisplays,
-    testing::Values(
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::LEFT, 37, 14,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(-1024, 37, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::TOP, 37, 14,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(37, -768, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::RIGHT, 37, 14,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(800, 37, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::BOTTOM, 37, 14,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(37, 600, 1024, 768))));
+INSTANTIATE_TEST_SUITE_P(
+    DisplayLayoutTestOffsetMinimumOverlap,
+    TwoDisplays,
+    testing::Values(std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::LEFT,
+                                    37,
+                                    14,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-1024, 37, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::TOP,
+                                    37,
+                                    14,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(37, -768, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::RIGHT,
+                                    37,
+                                    14,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(800, 37, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::BOTTOM,
+                                    37,
+                                    14,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(37, 600, 1024, 768))));
 
-INSTANTIATE_TEST_CASE_P(DisplayLayoutTestMinimumOverlap, TwoDisplays,
-    testing::Values(
-        // Top-Left
-        std::make_tuple(
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-            DisplayPlacement::Position::LEFT, -60, 14,
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(-30, -46, 30, 60)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-            DisplayPlacement::Position::TOP, -30, 14,
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(-16, -60, 30, 60)),
-        // Top-Right
-        std::make_tuple(
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-            DisplayPlacement::Position::RIGHT, -60, 14,
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(20, -46, 30, 60)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-            DisplayPlacement::Position::TOP, 20, 14,
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(6, -60, 30, 60)),
-        // Bottom-Right
-        std::make_tuple(
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-            DisplayPlacement::Position::RIGHT, 40, 14,
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(20, 26, 30, 60)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-            DisplayPlacement::Position::BOTTOM, 20, 14,
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(6, 40, 30, 60)),
-        // Bottom-Left
-        std::make_tuple(
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-            DisplayPlacement::Position::LEFT, 40, 14,
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(-30, 26, 30, 60)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(0, 0, 30, 60),
-            DisplayPlacement::Position::BOTTOM, -30, 14,
-            gfx::Rect(0, 0, 20, 40), gfx::Rect(-16, 40, 30, 60))));
+INSTANTIATE_TEST_SUITE_P(DisplayLayoutTestMinimumOverlap,
+                         TwoDisplays,
+                         testing::Values(
+                             // Top-Left
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::LEFT,
+                                             -60,
+                                             14,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(-30, -46, 30, 60)),
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::TOP,
+                                             -30,
+                                             14,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(-16, -60, 30, 60)),
+                             // Top-Right
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::RIGHT,
+                                             -60,
+                                             14,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(20, -46, 30, 60)),
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::TOP,
+                                             20,
+                                             14,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(6, -60, 30, 60)),
+                             // Bottom-Right
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::RIGHT,
+                                             40,
+                                             14,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(20, 26, 30, 60)),
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::BOTTOM,
+                                             20,
+                                             14,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(6, 40, 30, 60)),
+                             // Bottom-Left
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::LEFT,
+                                             40,
+                                             14,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(-30, 26, 30, 60)),
+                             std::make_tuple(gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(0, 0, 30, 60),
+                                             DisplayPlacement::Position::BOTTOM,
+                                             -30,
+                                             14,
+                                             gfx::Rect(0, 0, 20, 40),
+                                             gfx::Rect(-16, 40, 30, 60))));
 
 // Display Layout
 //     [1]  [4]
@@ -455,42 +560,68 @@
   EXPECT_EQ(expected_secondary_display_bounds, display_list[1].bounds());
 }
 
-INSTANTIATE_TEST_CASE_P(DisplayLayoutTestZero, TwoDisplaysBottomRightReference,
-    testing::Values(
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::LEFT, 0, 0,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(-1024, -168, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::TOP, 0, 0,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(-224, -768, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::RIGHT, 0, 0,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(800, -168, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::BOTTOM, 0, 0,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(-224, 600, 1024, 768))));
+INSTANTIATE_TEST_SUITE_P(
+    DisplayLayoutTestZero,
+    TwoDisplaysBottomRightReference,
+    testing::Values(std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::LEFT,
+                                    0,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-1024, -168, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::TOP,
+                                    0,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-224, -768, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::RIGHT,
+                                    0,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(800, -168, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::BOTTOM,
+                                    0,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-224, 600, 1024, 768))));
 
-INSTANTIATE_TEST_CASE_P(DisplayLayoutTestOffset,
-    TwoDisplaysBottomRightReference, testing::Values(
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::LEFT, 7, 0,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(-1024, -175, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::TOP, 7, 0,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(-231, -768, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::RIGHT, 7, 0,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(800, -175, 1024, 768)),
-        std::make_tuple(
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(0, 0, 1024, 768),
-            DisplayPlacement::Position::BOTTOM, 7, 0,
-            gfx::Rect(0, 0, 800, 600), gfx::Rect(-231, 600, 1024, 768))));
+INSTANTIATE_TEST_SUITE_P(
+    DisplayLayoutTestOffset,
+    TwoDisplaysBottomRightReference,
+    testing::Values(std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::LEFT,
+                                    7,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-1024, -175, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::TOP,
+                                    7,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-231, -768, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::RIGHT,
+                                    7,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(800, -175, 1024, 768)),
+                    std::make_tuple(gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(0, 0, 1024, 768),
+                                    DisplayPlacement::Position::BOTTOM,
+                                    7,
+                                    0,
+                                    gfx::Rect(0, 0, 800, 600),
+                                    gfx::Rect(-231, 600, 1024, 768))));
 
 }  // namespace display
diff --git a/ui/events/event_unittest.cc b/ui/events/event_unittest.cc
index 15c49e7e..f12d19f 100644
--- a/ui/events/event_unittest.cc
+++ b/ui/events/event_unittest.cc
@@ -984,12 +984,12 @@
   }
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     WM_KEY,
     AltGraphEventTest,
     ::testing::Combine(::testing::Values(WM_KEYDOWN, WM_KEYUP),
                        ::testing::ValuesIn(kAltGraphEventTestCases)));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     WM_CHAR,
     AltGraphEventTest,
     ::testing::Combine(::testing::Values(WM_CHAR),
diff --git a/ui/gfx/bidi_line_iterator_unittest.cc b/ui/gfx/bidi_line_iterator_unittest.cc
index ee9802a..b4c4e02 100644
--- a/ui/gfx/bidi_line_iterator_unittest.cc
+++ b/ui/gfx/bidi_line_iterator_unittest.cc
@@ -141,7 +141,7 @@
   EXPECT_EQ(1, level);
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     ,
     BiDiLineIteratorTest,
     ::testing::Values(base::i18n::TextDirection::LEFT_TO_RIGHT,
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc
index 3c27ab8..8ea3e21 100644
--- a/ui/gfx/color_transform_unittest.cc
+++ b/ui/gfx/color_transform_unittest.cc
@@ -531,9 +531,9 @@
   }
 }
 
-INSTANTIATE_TEST_CASE_P(ColorSpace,
-                        TransferTest,
-                        testing::ValuesIn(simple_transfers));
+INSTANTIATE_TEST_SUITE_P(ColorSpace,
+                         TransferTest,
+                         testing::ValuesIn(simple_transfers));
 
 class NonInvertibleTransferTest
     : public testing::TestWithParam<ColorSpace::TransferID> {};
@@ -561,9 +561,9 @@
   from_linear->Transform(&tristim, 1);
 }
 
-INSTANTIATE_TEST_CASE_P(ColorSpace,
-                        NonInvertibleTransferTest,
-                        testing::ValuesIn(noninvertible_transfers));
+INSTANTIATE_TEST_SUITE_P(ColorSpace,
+                         NonInvertibleTransferTest,
+                         testing::ValuesIn(noninvertible_transfers));
 
 class ExtendedTransferTest
     : public testing::TestWithParam<ColorSpace::TransferID> {};
@@ -592,9 +592,9 @@
   }
 }
 
-INSTANTIATE_TEST_CASE_P(ColorSpace,
-                        ExtendedTransferTest,
-                        testing::ValuesIn(extended_transfers));
+INSTANTIATE_TEST_SUITE_P(ColorSpace,
+                         ExtendedTransferTest,
+                         testing::ValuesIn(extended_transfers));
 
 typedef std::tuple<ColorSpace::PrimaryID,
                    ColorSpace::TransferID,
@@ -640,7 +640,7 @@
   EXPECT_NEAR(tristim.z(), 0.6f, 0.001f);
 }
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     A,
     ColorSpaceTest,
     testing::Combine(testing::ValuesIn(all_primaries),
@@ -649,7 +649,7 @@
                      testing::Values(ColorSpace::RangeID::LIMITED),
                      testing::ValuesIn(intents)));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     B,
     ColorSpaceTest,
     testing::Combine(testing::Values(ColorSpace::PrimaryID::BT709),
@@ -658,7 +658,7 @@
                      testing::ValuesIn(all_ranges),
                      testing::ValuesIn(intents)));
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     C,
     ColorSpaceTest,
     testing::Combine(testing::ValuesIn(all_primaries),
diff --git a/ui/gfx/linux/native_pixmap_dmabuf_unittest.cc b/ui/gfx/linux/native_pixmap_dmabuf_unittest.cc
index a22ab64..5272b4f 100644
--- a/ui/gfx/linux/native_pixmap_dmabuf_unittest.cc
+++ b/ui/gfx/linux/native_pixmap_dmabuf_unittest.cc
@@ -34,10 +34,10 @@
   }
 };
 
-INSTANTIATE_TEST_CASE_P(ConvertTest,
-                        NativePixmapDmaBufTest,
-                        ::testing::Values(gfx::BufferFormat::RGBX_8888,
-                                          gfx::BufferFormat::YVU_420));
+INSTANTIATE_TEST_SUITE_P(ConvertTest,
+                         NativePixmapDmaBufTest,
+                         ::testing::Values(gfx::BufferFormat::RGBX_8888,
+                                           gfx::BufferFormat::YVU_420));
 
 // Verifies NativePixmapDmaBuf conversion from and to NativePixmapHandle.
 TEST_P(NativePixmapDmaBufTest, Convert) {
diff --git a/ui/gfx/text_utils_unittest.cc b/ui/gfx/text_utils_unittest.cc
index e3babfd..a87cc8b 100644
--- a/ui/gfx/text_utils_unittest.cc
+++ b/ui/gfx/text_utils_unittest.cc
@@ -76,7 +76,7 @@
      "MultibyteAccelerator_AfterMultibyteAccelerator"},
 };
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     ,
     RemoveAcceleratorCharTest,
     testing::ValuesIn(RemoveAcceleratorCharTest::kCases),
@@ -157,7 +157,7 @@
      "MiddleOfString_AfterCombiningSurrogate"},
 };
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     ,
     FindValidBoundaryBeforeTest,
     testing::ValuesIn(FindValidBoundaryBeforeTest::kCases),
@@ -230,7 +230,7 @@
      "MiddleOfString_AfterCombiningSurrogate"},
 };
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     ,
     FindValidBoundaryAfterTest,
     testing::ValuesIn(FindValidBoundaryAfterTest::kCases),
diff --git a/ui/gl/gl_image_ahardwarebuffer_unittest.cc b/ui/gl/gl_image_ahardwarebuffer_unittest.cc
index f762fed..fa92ef5 100644
--- a/ui/gl/gl_image_ahardwarebuffer_unittest.cc
+++ b/ui/gl/gl_image_ahardwarebuffer_unittest.cc
@@ -102,21 +102,21 @@
 // the test bots don't generally have that yet. For manual testing,
 // add: --gtest_also_run_disabled_tests -f 'GLImageAHardwareBuffer/*'
 
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GLImageAHardwareBuffer,
-                              GLImageTest,
-                              GLImageTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageAHardwareBuffer,
+                               GLImageTest,
+                               GLImageTestTypes);
 
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GLImageAHardwareBuffer,
-                              GLImageOddSizeTest,
-                              GLImageTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageAHardwareBuffer,
+                               GLImageOddSizeTest,
+                               GLImageTestTypes);
 
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GLImageAHardwareBuffer,
-                              GLImageBindTest,
-                              GLImageTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageAHardwareBuffer,
+                               GLImageBindTest,
+                               GLImageTestTypes);
 
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GLImageAHardwareBuffer,
-                              GLImageZeroInitializeTest,
-                              GLImageRGBTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageAHardwareBuffer,
+                               GLImageZeroInitializeTest,
+                               GLImageRGBTestTypes);
 
 }  // namespace
 }  // namespace gl
diff --git a/ui/gl/gl_image_ref_counted_memory_unittest.cc b/ui/gl/gl_image_ref_counted_memory_unittest.cc
index 791480b0..27fafbf 100644
--- a/ui/gl/gl_image_ref_counted_memory_unittest.cc
+++ b/ui/gl/gl_image_ref_counted_memory_unittest.cc
@@ -45,13 +45,13 @@
     GLImageRefCountedMemoryTestDelegate<gfx::BufferFormat::BGRX_8888>,
     GLImageRefCountedMemoryTestDelegate<gfx::BufferFormat::BGRA_8888>>;
 
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageRefCountedMemory,
-                              GLImageTest,
-                              GLImageTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(GLImageRefCountedMemory,
+                               GLImageTest,
+                               GLImageTestTypes);
 
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageRefCountedMemory,
-                              GLImageCopyTest,
-                              GLImageTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(GLImageRefCountedMemory,
+                               GLImageCopyTest,
+                               GLImageTestTypes);
 
 }  // namespace
 }  // namespace gl
diff --git a/ui/gl/gl_image_shared_memory_unittest.cc b/ui/gl/gl_image_shared_memory_unittest.cc
index 02c1367..a7c4a7d 100644
--- a/ui/gl/gl_image_shared_memory_unittest.cc
+++ b/ui/gl/gl_image_shared_memory_unittest.cc
@@ -60,20 +60,20 @@
 #endif
     GLImageSharedMemoryTestDelegate<gfx::BufferFormat::BGRA_8888>>;
 
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageSharedMemory,
-                              GLImageTest,
-                              GLImageTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(GLImageSharedMemory,
+                               GLImageTest,
+                               GLImageTestTypes);
 
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageSharedMemory,
-                              GLImageOddSizeTest,
-                              GLImageTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(GLImageSharedMemory,
+                               GLImageOddSizeTest,
+                               GLImageTestTypes);
 
 // https://crbug.com/830653
 #if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
     !defined(THREAD_SANITIZER)
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageSharedMemory,
-                              GLImageCopyTest,
-                              GLImageTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(GLImageSharedMemory,
+                               GLImageCopyTest,
+                               GLImageTestTypes);
 #endif
 
 class GLImageSharedMemoryPoolTestDelegate : public GLImageTestDelegateBase {
@@ -116,9 +116,9 @@
 // https://crbug.com/830653
 #if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
     !defined(THREAD_SANITIZER)
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageSharedMemoryPool,
-                              GLImageCopyTest,
-                              GLImageSharedMemoryPoolTestDelegate);
+INSTANTIATE_TYPED_TEST_SUITE_P(GLImageSharedMemoryPool,
+                               GLImageCopyTest,
+                               GLImageSharedMemoryPoolTestDelegate);
 #endif
 
 }  // namespace
diff --git a/ui/gl/test/gl_image_test_template.h b/ui/gl/test/gl_image_test_template.h
index edc0f1d..a6070e3b 100644
--- a/ui/gl/test/gl_image_test_template.h
+++ b/ui/gl/test/gl_image_test_template.h
@@ -73,7 +73,7 @@
   GLImageTestDelegate delegate_;
 };
 
-TYPED_TEST_CASE_P(GLImageTest);
+TYPED_TEST_SUITE_P(GLImageTest);
 
 TYPED_TEST_P(GLImageTest, Create) {
   if (this->delegate_.SkipTest())
@@ -104,13 +104,13 @@
 
 // The GLImageTest test case verifies the behaviour that is expected from a
 // GLImage in order to be conformant.
-REGISTER_TYPED_TEST_CASE_P(GLImageTest, Create);
+REGISTER_TYPED_TEST_SUITE_P(GLImageTest, Create);
 
 template <typename GLImageTestDelegate>
 class GLImageOddSizeTest : public GLImageTest<GLImageTestDelegate> {};
 
 // This test verifies that odd-sized GLImages can be created and destroyed.
-TYPED_TEST_CASE_P(GLImageOddSizeTest);
+TYPED_TEST_SUITE_P(GLImageOddSizeTest);
 
 TYPED_TEST_P(GLImageOddSizeTest, Create) {
   if (this->delegate_.SkipTest())
@@ -131,14 +131,14 @@
 
 // The GLImageTest test case verifies the behaviour that is expected from a
 // GLImage in order to be conformant.
-REGISTER_TYPED_TEST_CASE_P(GLImageOddSizeTest, Create);
+REGISTER_TYPED_TEST_SUITE_P(GLImageOddSizeTest, Create);
 
 template <typename GLImageTestDelegate>
 class GLImageZeroInitializeTest : public GLImageTest<GLImageTestDelegate> {};
 
 // This test verifies that if an uninitialized image is bound to a texture, the
 // result is zero-initialized.
-TYPED_TEST_CASE_P(GLImageZeroInitializeTest);
+TYPED_TEST_SUITE_P(GLImageZeroInitializeTest);
 
 TYPED_TEST_P(GLImageZeroInitializeTest, ZeroInitialize) {
   if (this->delegate_.SkipTest())
@@ -187,12 +187,12 @@
   glDeleteFramebuffersEXT(1, &framebuffer);
 }
 
-REGISTER_TYPED_TEST_CASE_P(GLImageZeroInitializeTest, ZeroInitialize);
+REGISTER_TYPED_TEST_SUITE_P(GLImageZeroInitializeTest, ZeroInitialize);
 
 template <typename GLImageTestDelegate>
 class GLImageBindTest : public GLImageTest<GLImageTestDelegate> {};
 
-TYPED_TEST_CASE_P(GLImageBindTest);
+TYPED_TEST_SUITE_P(GLImageBindTest);
 
 TYPED_TEST_P(GLImageBindTest, BindTexImage) {
   if (this->delegate_.SkipTest())
@@ -237,12 +237,12 @@
   glDeleteFramebuffersEXT(1, &framebuffer);
 }
 
-REGISTER_TYPED_TEST_CASE_P(GLImageBindTest, BindTexImage);
+REGISTER_TYPED_TEST_SUITE_P(GLImageBindTest, BindTexImage);
 
 template <typename GLImageTestDelegate>
 class GLImageCopyTest : public GLImageTest<GLImageTestDelegate> {};
 
-TYPED_TEST_CASE_P(GLImageCopyTest);
+TYPED_TEST_SUITE_P(GLImageCopyTest);
 
 TYPED_TEST_P(GLImageCopyTest, CopyTexImage) {
   if (this->delegate_.SkipTest())
@@ -307,7 +307,7 @@
 
 // The GLImageCopyTest test case verifies that the GLImage implementation
 // handles CopyTexImage correctly.
-REGISTER_TYPED_TEST_CASE_P(GLImageCopyTest, CopyTexImage);
+REGISTER_TYPED_TEST_SUITE_P(GLImageCopyTest, CopyTexImage);
 
 }  // namespace gl
 
diff --git a/ui/latency/latency_info.cc b/ui/latency/latency_info.cc
index 11b2321..fd7e1fd 100644
--- a/ui/latency/latency_info.cc
+++ b/ui/latency/latency_info.cc
@@ -38,6 +38,7 @@
     CASE_TYPE(INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT);
     CASE_TYPE(INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT);
     CASE_TYPE(INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT);
+    CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT_COMPONENT);
     CASE_TYPE(INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT);
     CASE_TYPE(INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT);
     CASE_TYPE(INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT);
@@ -45,11 +46,10 @@
     CASE_TYPE(INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT);
     CASE_TYPE(INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT);
     default:
-      DLOG(WARNING) << "Unhandled LatencyComponentType.\n";
-      break;
+      NOTREACHED() << "Unhandled LatencyComponentType: " << type;
+      return "unknown";
   }
 #undef CASE_TYPE
-  return "unknown";
 }
 
 bool IsInputLatencyBeginComponent(ui::LatencyComponentType type) {
diff --git a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
index 5335857..532b040 100644
--- a/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
+++ b/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
@@ -83,9 +83,9 @@
     GLImageNativePixmapTestDelegate<gfx::BufferUsage::SCANOUT,
                                     gfx::BufferFormat::BGRA_8888>>;
 
-INSTANTIATE_TYPED_TEST_CASE_P(GLImageNativePixmapScanout,
-                              GLImageTest,
-                              GLImageScanoutType);
+INSTANTIATE_TYPED_TEST_SUITE_P(GLImageNativePixmapScanout,
+                               GLImageTest,
+                               GLImageScanoutType);
 
 using GLImageScanoutTypeDisabled = testing::Types<
     GLImageNativePixmapTestDelegate<gfx::BufferUsage::SCANOUT,
@@ -93,9 +93,9 @@
 
 // This test is disabled since we need mesa support for XR30/XB30 that is not
 // available on many boards yet.
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GLImageNativePixmapScanout,
-                              GLImageTest,
-                              GLImageScanoutTypeDisabled);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageNativePixmapScanout,
+                               GLImageTest,
+                               GLImageScanoutTypeDisabled);
 
 using GLImageReadWriteType = testing::Types<
     GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
@@ -120,13 +120,13 @@
 // These tests are disabled since the trybots are running with Ozone X11
 // implementation that doesn't support creating ClientNativePixmap.
 // TODO(dcastagna): Implement ClientNativePixmapFactory on Ozone X11.
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GLImageNativePixmapReadWrite,
-                              GLImageTest,
-                              GLImageReadWriteType);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageNativePixmapReadWrite,
+                               GLImageTest,
+                               GLImageReadWriteType);
 
-INSTANTIATE_TYPED_TEST_CASE_P(DISABLED_GLImageNativePixmap,
-                              GLImageBindTest,
-                              GLImageBindTestTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageNativePixmap,
+                               GLImageBindTest,
+                               GLImageBindTestTypes);
 
 }  // namespace
 }  // namespace gl
diff --git a/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc b/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
index 79e3785..189fe806 100644
--- a/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
+++ b/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
@@ -141,11 +141,11 @@
   EXPECT_FALSE(manager->DestroyBuffer(kBufferId2));
 }
 
-INSTANTIATE_TEST_CASE_P(XdgVersionV5Test,
-                        WaylandBufferManagerTest,
-                        ::testing::Values(kXdgShellV5));
-INSTANTIATE_TEST_CASE_P(XdgVersionV6Test,
-                        WaylandBufferManagerTest,
-                        ::testing::Values(kXdgShellV6));
+INSTANTIATE_TEST_SUITE_P(XdgVersionV5Test,
+                         WaylandBufferManagerTest,
+                         ::testing::Values(kXdgShellV5));
+INSTANTIATE_TEST_SUITE_P(XdgVersionV6Test,
+                         WaylandBufferManagerTest,
+                         ::testing::Values(kXdgShellV6));
 
 }  // namespace ui
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_win.cc b/ui/views/accessibility/view_ax_platform_node_delegate_win.cc
index ab33289..a1e7b940 100644
--- a/ui/views/accessibility/view_ax_platform_node_delegate_win.cc
+++ b/ui/views/accessibility/view_ax_platform_node_delegate_win.cc
@@ -89,7 +89,7 @@
   if (!hwnd)
     return nullptr;
 
-  if (switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
+  if (::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
     ui::AXFragmentRootWin* ax_fragment_root =
         ui::AXFragmentRootWin::GetForAcceleratedWidget(hwnd);
     if (ax_fragment_root)
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_win_unittest.cc b/ui/views/accessibility/view_ax_platform_node_delegate_win_unittest.cc
index 6a24418..549b19c1 100644
--- a/ui/views/accessibility/view_ax_platform_node_delegate_win_unittest.cc
+++ b/ui/views/accessibility/view_ax_platform_node_delegate_win_unittest.cc
@@ -165,9 +165,9 @@
   DISALLOW_COPY_AND_ASSIGN(ViewAXPlatformNodeDelegateWinTestWithBoolChildFlag);
 };
 
-INSTANTIATE_TEST_CASE_P(,
-                        ViewAXPlatformNodeDelegateWinTestWithBoolChildFlag,
-                        testing::Bool());
+INSTANTIATE_TEST_SUITE_P(,
+                         ViewAXPlatformNodeDelegateWinTestWithBoolChildFlag,
+                         testing::Bool());
 
 TEST_P(ViewAXPlatformNodeDelegateWinTestWithBoolChildFlag, AuraChildWidgets) {
   // Create the parent widget.
diff --git a/ui/views/animation/ink_drop_ripple_unittest.cc b/ui/views/animation/ink_drop_ripple_unittest.cc
index 0184bc4c..d7bc837 100644
--- a/ui/views/animation/ink_drop_ripple_unittest.cc
+++ b/ui/views/animation/ink_drop_ripple_unittest.cc
@@ -40,7 +40,7 @@
 //    2. Implement set up and tear down code for the new enum value in
 //       InkDropRippleTest() and
 //      ~InkDropRippleTest().
-//    3. Add the new enum value to the INSTANTIATE_TEST_CASE_P) Values list.
+//    3. Add the new enum value to the INSTANTIATE_TEST_SUITE_P) Values list.
 class InkDropRippleTest
     : public testing::TestWithParam<InkDropRippleTestTypes> {
  public:
@@ -92,10 +92,10 @@
 
 // Note: First argument is optional and intentionally left blank.
 // (it's a prefix for the generated test cases)
-INSTANTIATE_TEST_CASE_P(,
-                        InkDropRippleTest,
-                        testing::Values(SQUARE_INK_DROP_RIPPLE,
-                                        FLOOD_FILL_INK_DROP_RIPPLE));
+INSTANTIATE_TEST_SUITE_P(,
+                         InkDropRippleTest,
+                         testing::Values(SQUARE_INK_DROP_RIPPLE,
+                                         FLOOD_FILL_INK_DROP_RIPPLE));
 
 TEST_P(InkDropRippleTest, InitialStateAfterConstruction) {
   EXPECT_EQ(views::InkDropState::HIDDEN,
diff --git a/ui/views/animation/ink_drop_unittest.cc b/ui/views/animation/ink_drop_unittest.cc
index 903eef9..64e461ae 100644
--- a/ui/views/animation/ink_drop_unittest.cc
+++ b/ui/views/animation/ink_drop_unittest.cc
@@ -76,9 +76,9 @@
 
 // Note: First argument is optional and intentionally left blank.
 // (it's a prefix for the generated test cases)
-INSTANTIATE_TEST_CASE_P(,
-                        InkDropTest,
-                        testing::Values(INK_DROP_STUB, INK_DROP_IMPL));
+INSTANTIATE_TEST_SUITE_P(,
+                         InkDropTest,
+                         testing::Values(INK_DROP_STUB, INK_DROP_IMPL));
 
 TEST_P(InkDropTest,
        VerifyInkDropLayersRemovedAfterDestructionWhenRippleIsActive) {
diff --git a/ui/views/cocoa/drag_drop_client_mac.h b/ui/views/cocoa/drag_drop_client_mac.h
index 065e730..1cfc235f 100644
--- a/ui/views/cocoa/drag_drop_client_mac.h
+++ b/ui/views/cocoa/drag_drop_client_mac.h
@@ -7,9 +7,8 @@
 
 #import <Cocoa/Cocoa.h>
 
-#include <memory>
-
 #include "base/callback.h"
+#import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "ui/base/dragdrop/drag_drop_types.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
@@ -17,6 +16,14 @@
 #include "ui/views/widget/drop_helper.h"
 #include "ui/views_bridge_mac/drag_drop_client.h"
 
+// This class acts as a bridge between NSPasteboardItem and OSExchangeData by
+// implementing NSPasteboardItemDataProvider and writing data from
+// OSExchangeData into the pasteboard.
+VIEWS_EXPORT
+@interface CocoaDragDropDataProvider : NSObject<NSPasteboardItemDataProvider>
+- (instancetype)initWithData:(const ui::OSExchangeData&)data;
+@end
+
 namespace gfx {
 class Point;
 }
@@ -59,7 +66,7 @@
   gfx::Point LocationInView(NSPoint point) const;
 
   // Provides the data for the drag and drop session.
-  std::unique_ptr<ui::OSExchangeData> exchange_data_;
+  base::scoped_nsobject<CocoaDragDropDataProvider> data_source_;
 
   // Used to handle drag and drop with Views.
   DropHelper drop_helper_;
diff --git a/ui/views/cocoa/drag_drop_client_mac.mm b/ui/views/cocoa/drag_drop_client_mac.mm
index 60475b3..b2275340 100644
--- a/ui/views/cocoa/drag_drop_client_mac.mm
+++ b/ui/views/cocoa/drag_drop_client_mac.mm
@@ -14,6 +14,47 @@
 #import "ui/views_bridge_mac/bridged_content_view.h"
 #import "ui/views_bridge_mac/bridged_native_widget_impl.h"
 
+@interface CocoaDragDropDataProvider ()
+- (instancetype)initWithData:(const ui::OSExchangeData&)data;
+- (instancetype)initWithPasteboard:(NSPasteboard*)pasteboard;
+@end
+
+@implementation CocoaDragDropDataProvider {
+  std::unique_ptr<ui::OSExchangeData> data_;
+}
+
+- (instancetype)initWithData:(const ui::OSExchangeData&)data {
+  if ((self = [super init])) {
+    data_.reset(new OSExchangeData(
+        std::unique_ptr<OSExchangeData::Provider>(data.provider().Clone())));
+  }
+  return self;
+}
+
+- (instancetype)initWithPasteboard:(NSPasteboard*)pasteboard {
+  if ((self = [super init])) {
+    data_ = ui::OSExchangeDataProviderMac::CreateDataFromPasteboard(pasteboard);
+  }
+  return self;
+}
+
+- (ui::OSExchangeData*)data {
+  return data_.get();
+}
+
+// NSPasteboardItemDataProvider protocol implementation.
+
+- (void)pasteboard:(NSPasteboard*)sender
+                  item:(NSPasteboardItem*)item
+    provideDataForType:(NSString*)type {
+  const ui::OSExchangeDataProviderMac& provider =
+      static_cast<const ui::OSExchangeDataProviderMac&>(data_->provider());
+  NSData* ns_data = provider.GetNSDataForType(type);
+  [sender setData:ns_data forType:type];
+}
+
+@end
+
 namespace views {
 
 DragDropClientMac::DragDropClientMac(BridgedNativeWidgetImpl* bridge,
@@ -33,15 +74,12 @@
     const ui::OSExchangeData& data,
     int operation,
     ui::DragDropTypes::DragEventSource source) {
-  // TODO(avi): Why must this data be cloned?
-  exchange_data_ =
-      std::make_unique<ui::OSExchangeData>(data.provider().Clone());
+  data_source_.reset([[CocoaDragDropDataProvider alloc] initWithData:data]);
   operation_ = operation;
   is_drag_source_ = true;
 
-  const ui::OSExchangeDataProviderMac& provider_mac =
-      static_cast<const ui::OSExchangeDataProviderMac&>(
-          exchange_data_->provider());
+  const ui::OSExchangeDataProviderMac& provider =
+      static_cast<const ui::OSExchangeDataProviderMac&>(data.provider());
 
   // Release capture before beginning the dragging session. Capture may have
   // been acquired on the mouseDown, but capture is not required during the
@@ -64,7 +102,7 @@
                                       pressure:1.0];
 
   NSImage* image = gfx::NSImageFromImageSkiaWithColorSpace(
-      provider_mac.GetDragImage(), base::mac::GetSRGBColorSpace());
+      provider.GetDragImage(), base::mac::GetSRGBColorSpace());
 
   // TODO(crbug/876201): This shouldn't happen. When a repro for this
   // is identified and the bug is fixed, change the early return to
@@ -72,7 +110,12 @@
   if (!image || NSEqualSizes([image size], NSZeroSize))
     return;
 
-  NSDraggingItem* drag_item = provider_mac.GetDraggingItem();
+  base::scoped_nsobject<NSPasteboardItem> item([[NSPasteboardItem alloc] init]);
+  [item setDataProvider:data_source_.get()
+               forTypes:provider.GetAvailableTypes()];
+
+  base::scoped_nsobject<NSDraggingItem> drag_item(
+      [[NSDraggingItem alloc] initWithPasteboardWriter:item.get()]);
 
   // Subtract the image's height from the y location so that the mouse will be
   // at the upper left corner of the image.
@@ -82,7 +125,7 @@
                  [image size].width, [image size].height);
   [drag_item setDraggingFrame:dragging_frame contents:image];
 
-  [bridge_->ns_view() beginDraggingSessionWithItems:@[ drag_item ]
+  [bridge_->ns_view() beginDraggingSessionWithItems:@[ drag_item.get() ]
                                               event:event
                                              source:bridge_->ns_view()];
 
@@ -94,30 +137,32 @@
 }
 
 NSDragOperation DragDropClientMac::DragUpdate(id<NSDraggingInfo> sender) {
-  if (!exchange_data_) {
-    exchange_data_ = std::make_unique<OSExchangeData>(
-        ui::OSExchangeDataProviderMac::CreateProviderWrappingPasteboard(
-            [sender draggingPasteboard]));
+  if (!data_source_.get()) {
+    data_source_.reset([[CocoaDragDropDataProvider alloc]
+        initWithPasteboard:[sender draggingPasteboard]]);
     operation_ = ui::DragDropTypes::NSDragOperationToDragOperation(
         [sender draggingSourceOperationMask]);
   }
 
   int drag_operation = drop_helper_.OnDragOver(
-      *exchange_data_, LocationInView([sender draggingLocation]), operation_);
+      *[data_source_ data], LocationInView([sender draggingLocation]),
+      operation_);
   return ui::DragDropTypes::DragOperationToNSDragOperation(drag_operation);
 }
 
 NSDragOperation DragDropClientMac::Drop(id<NSDraggingInfo> sender) {
-  // OnDrop may delete |this|, so clear |exchange_data_| first.
-  std::unique_ptr<ui::OSExchangeData> exchange_data = std::move(exchange_data_);
+  // OnDrop may delete |this|, so clear |data_source_| first.
+  base::scoped_nsobject<CocoaDragDropDataProvider> data_source(
+      std::move(data_source_));
 
   int drag_operation = drop_helper_.OnDrop(
-      *exchange_data, LocationInView([sender draggingLocation]), operation_);
+      *[data_source data], LocationInView([sender draggingLocation]),
+      operation_);
   return ui::DragDropTypes::DragOperationToNSDragOperation(drag_operation);
 }
 
 void DragDropClientMac::EndDrag() {
-  exchange_data_.reset();
+  data_source_.reset();
   is_drag_source_ = false;
 
   // Allow a test to invoke EndDrag() without spinning the nested run loop.
@@ -130,7 +175,7 @@
 void DragDropClientMac::DragExit() {
   drop_helper_.OnDragExit();
   if (!is_drag_source_)
-    exchange_data_.reset();
+    data_source_.reset();
 }
 
 gfx::Point DragDropClientMac::LocationInView(NSPoint point) const {
diff --git a/ui/views/cocoa/drag_drop_client_mac_unittest.mm b/ui/views/cocoa/drag_drop_client_mac_unittest.mm
index 80160422..7e47378 100644
--- a/ui/views/cocoa/drag_drop_client_mac_unittest.mm
+++ b/ui/views/cocoa/drag_drop_client_mac_unittest.mm
@@ -177,8 +177,8 @@
   }
 
   void SetData(OSExchangeData& data) {
-    drag_drop_client()->exchange_data_ =
-        std::make_unique<ui::OSExchangeData>(data.provider().Clone());
+    drag_drop_client()->data_source_.reset(
+        [[CocoaDragDropDataProvider alloc] initWithData:data]);
   }
 
   // testing::Test:
diff --git a/ui/views/controls/menu/menu_runner_cocoa_unittest.mm b/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
index a971335..89c0fc28 100644
--- a/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
+++ b/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
@@ -427,10 +427,10 @@
   EXPECT_EQ(combobox_rect.right(), last_anchor_frame_.origin.x);
 }
 
-INSTANTIATE_TEST_CASE_P(,
-                        MenuRunnerCocoaTest,
-                        ::testing::Values(MenuType::NATIVE, MenuType::VIEWS),
-                        &MenuTypeToString);
+INSTANTIATE_TEST_SUITE_P(,
+                         MenuRunnerCocoaTest,
+                         ::testing::Values(MenuType::NATIVE, MenuType::VIEWS),
+                         &MenuTypeToString);
 
 }  // namespace test
 }  // namespace views
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 22aef75..211bb0a2 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -272,7 +272,7 @@
 }
 
 gfx::Insets View::GetInsets() const {
-  return border_.get() ? border_->GetInsets() : gfx::Insets();
+  return border_ ? border_->GetInsets() : gfx::Insets();
 }
 
 gfx::Rect View::GetVisibleBounds() const {
@@ -526,7 +526,7 @@
   // the call can take appropriate action.
   internal::ScopedChildrenLock lock(this);
   for (auto* child : children_) {
-    if (child->needs_layout_ || !layout_manager_.get()) {
+    if (child->needs_layout_ || !layout_manager_) {
       TRACE_EVENT1("views", "View::Layout", "class", child->GetClassName());
       child->needs_layout_ = false;
       child->Layout();
@@ -1109,17 +1109,17 @@
 // Accelerators ----------------------------------------------------------------
 
 void View::AddAccelerator(const ui::Accelerator& accelerator) {
-  if (!accelerators_.get())
+  if (!accelerators_)
     accelerators_.reset(new std::vector<ui::Accelerator>());
 
-  if (!base::ContainsValue(*accelerators_.get(), accelerator))
+  if (!base::ContainsValue(*accelerators_, accelerator))
     accelerators_->push_back(accelerator);
 
   RegisterPendingAccelerators();
 }
 
 void View::RemoveAccelerator(const ui::Accelerator& accelerator) {
-  if (!accelerators_.get()) {
+  if (!accelerators_) {
     NOTREACHED() << "Removing non-existing accelerator";
     return;
   }
@@ -1145,7 +1145,7 @@
 }
 
 void View::ResetAccelerators() {
-  if (accelerators_.get())
+  if (accelerators_)
     UnregisterAccelerators(false);
 }
 
@@ -1965,7 +1965,7 @@
       view->SchedulePaint();
   }
 
-  if (layout_manager_.get())
+  if (layout_manager_)
     layout_manager_->ViewAdded(this, view);
 
   for (ViewObserver& observer : observers_)
@@ -2189,7 +2189,7 @@
 
   // Notify interested Views that visible bounds within the root view may have
   // changed.
-  if (descendants_to_notify_.get()) {
+  if (descendants_to_notify_) {
     for (auto i(descendants_to_notify_->begin());
          i != descendants_to_notify_->end(); ++i) {
       (*i)->OnVisibleBoundsChanged();
@@ -2233,13 +2233,13 @@
 
 void View::AddDescendantToNotify(View* view) {
   DCHECK(view);
-  if (!descendants_to_notify_.get())
+  if (!descendants_to_notify_)
     descendants_to_notify_.reset(new Views);
   descendants_to_notify_->push_back(view);
 }
 
 void View::RemoveDescendantToNotify(View* view) {
-  DCHECK(view && descendants_to_notify_.get());
+  DCHECK(view && descendants_to_notify_);
   auto i(std::find(descendants_to_notify_->begin(),
                    descendants_to_notify_->end(), view));
   DCHECK(i != descendants_to_notify_->end());
@@ -2253,7 +2253,7 @@
   // derived-class-specific-functions. It's an easy mistake to create a new
   // unique_ptr and re-set the layout manager with a new unique_ptr, which
   // will cause a crash. Re-setting to nullptr is OK.
-  CHECK(!layout_manager.get() || layout_manager_.get() != layout_manager.get());
+  CHECK(!layout_manager || layout_manager_ != layout_manager);
 
   layout_manager_ = std::move(layout_manager);
   if (layout_manager_)
@@ -2487,7 +2487,7 @@
 // Accelerators ----------------------------------------------------------------
 
 void View::RegisterPendingAccelerators() {
-  if (!accelerators_.get() ||
+  if (!accelerators_ ||
       registered_accelerator_count_ == accelerators_->size()) {
     // No accelerators are waiting for registration.
     return;
@@ -2516,7 +2516,7 @@
 }
 
 void View::UnregisterAccelerators(bool leave_data_intact) {
-  if (!accelerators_.get())
+  if (!accelerators_)
     return;
 
   if (GetWidget()) {
diff --git a/ui/views/widget/native_widget_mac_interactive_uitest.mm b/ui/views/widget/native_widget_mac_interactive_uitest.mm
index d7688f0..aa1c1e4 100644
--- a/ui/views/widget/native_widget_mac_interactive_uitest.mm
+++ b/ui/views/widget/native_widget_mac_interactive_uitest.mm
@@ -322,9 +322,9 @@
   base::RunLoop().RunUntilIdle();
 }
 
-INSTANTIATE_TEST_CASE_P(NativeWidgetMacInteractiveUITestInstance,
-                        NativeWidgetMacInteractiveUITest,
-                        ::testing::Bool());
+INSTANTIATE_TEST_SUITE_P(NativeWidgetMacInteractiveUITestInstance,
+                         NativeWidgetMacInteractiveUITest,
+                         ::testing::Bool());
 
 }  // namespace test
 }  // namespace views