diff --git a/DEPS b/DEPS
index 1821c2a..52bb16c3 100644
--- a/DEPS
+++ b/DEPS
@@ -133,7 +133,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '4c1ea43a79b5be7522adeac2e1e0d9ae21f26193',
+  'skia_revision': '5e398c2b5eef4f200a2b9a0d73840aae062db4fe',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -149,7 +149,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '3ed33cee5e61f854c36fb44b7253dda3052ff5ce',
+  'swiftshader_revision': 'd2b1d2f936eec56edf753735dc8d6d024ce841d6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -196,7 +196,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': 'dc658bb37c70d3153cda3e9993a3874ccd8871a9',
+  'catapult_revision': '5869dbeaf2c48db11c3defef123774bd43fbd5a5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -264,7 +264,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': 'b6880f79b56f38c05be91191f9630e9aa66ecc2d',
+  'quiche_revision': 'ded03513eb39ded284ec430a55ad4bdc86daec38',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling clang format
   # and whatever else without interference from each other.
@@ -752,7 +752,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '28dfd94b57ae4aca22c40a3521fb6480d1c155be',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '672bd1907c69863bd90422071b7e9f09b4dddc48',
       'condition': 'checkout_linux',
   },
 
@@ -1119,7 +1119,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '282b28c1234c109a45003a5470512982177e77c1',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '28c23b46037ca515143ec79421b1a5b1c438133e',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1334,7 +1334,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@7e53cb9263b40dd836a58e0ae548e8a24d98905f',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ba87d2a4daccda427eaf6913cef9e61cd45a050c',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index d1c8ebaa..4654c60 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -212,21 +212,6 @@
     autofill::mojom::PasswordManagerDriverRequest request,
     content::RenderFrameHost* render_frame_host) {}
 
-// TODO(timvolodine): consider refactoring this into common utility method.
-void OnReceivedErrorOnUIThread(
-    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
-    const AwWebResourceRequest& request) {
-  AwContentsClientBridge* client =
-      AwContentsClientBridge::FromWebContentsGetter(web_contents_getter);
-  if (!client) {
-    DLOG(WARNING) << "client is null, onReceivedError dropped for "
-                  << request.url;
-    return;
-  }
-  client->OnReceivedError(request, net::ERR_UNKNOWN_URL_SCHEME,
-                          false /*safebrowsing_hit*/);
-}
-
 void PassCookieManagerToCookieManagerWrapper(
     const network::mojom::NetworkContextPtr& network_context) {
   // Get the CookieManager from the NetworkContext.
@@ -924,17 +909,17 @@
     ui::PageTransition page_transition,
     bool has_user_gesture,
     const std::string& method,
-    const net::HttpRequestHeaders& headers) {
+    const net::HttpRequestHeaders& headers,
+    network::mojom::URLLoaderFactoryRequest* factory_request,
+    network::mojom::URLLoaderFactory*& out_factory) {
   if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
-    AwWebResourceRequest aw_resource_request(url.spec(), method, is_main_frame,
-                                             has_user_gesture, headers);
-    aw_resource_request.is_renderer_initiated =
-        ui::PageTransitionIsWebTriggerable(
-            static_cast<ui::PageTransition>(page_transition));
-    base::PostTaskWithTraits(
-        FROM_HERE, {BrowserThread::UI},
-        base::BindOnce(&OnReceivedErrorOnUIThread, web_contents_getter,
-                       std::move(aw_resource_request)));
+    auto proxied_request = std::move(*factory_request);
+    network::mojom::URLLoaderFactoryPtrInfo target_factory_info;
+    *factory_request = mojo::MakeRequest(&target_factory_info);
+
+    out_factory = new android_webview::AwProxyingURLLoaderFactory(
+        0 /* process_id */, std::move(proxied_request),
+        std::move(target_factory_info), nullptr, true /* intercept_only */);
   } else {
     // The AwURLRequestJobFactory implementation should ensure this method never
     // gets called when Network Service is not enabled.
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index b40c010..c2afa81a 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -211,7 +211,9 @@
       ui::PageTransition page_transition,
       bool has_user_gesture,
       const std::string& method,
-      const net::HttpRequestHeaders& headers) override;
+      const net::HttpRequestHeaders& headers,
+      network::mojom::URLLoaderFactoryRequest* factory_request,
+      network::mojom::URLLoaderFactory*& out_factory) override;
   void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
   bool ShouldIsolateErrorPage(bool in_main_frame) override;
   bool ShouldEnableStrictSiteIsolation() override;
diff --git a/android_webview/browser/aw_proxying_url_loader_factory.cc b/android_webview/browser/aw_proxying_url_loader_factory.cc
index 8024bdf..5153a2ad 100644
--- a/android_webview/browser/aw_proxying_url_loader_factory.cc
+++ b/android_webview/browser/aw_proxying_url_loader_factory.cc
@@ -36,52 +36,6 @@
 const char kAutoLoginHeaderName[] = "X-Auto-Login";
 const char kRequestedWithHeaderName[] = "X-Requested-With";
 
-class InterceptResponseDelegate
-    : public AndroidStreamReaderURLLoader::ResponseDelegate {
- public:
-  explicit InterceptResponseDelegate(
-      std::unique_ptr<AwWebResourceResponse> response)
-      : response_(std::move(response)) {}
-
-  std::unique_ptr<android_webview::InputStream> OpenInputStream(
-      JNIEnv* env) override {
-    return response_->GetInputStream(env);
-  }
-
-  void OnInputStreamOpenFailed(bool* restarted) override { *restarted = false; }
-
-  bool GetMimeType(JNIEnv* env,
-                   const GURL& url,
-                   android_webview::InputStream* stream,
-                   std::string* mime_type) override {
-    return response_->GetMimeType(env, mime_type);
-  }
-
-  bool GetCharset(JNIEnv* env,
-                  const GURL& url,
-                  android_webview::InputStream* stream,
-                  std::string* charset) override {
-    return response_->GetCharset(env, charset);
-  }
-
-  void AppendResponseHeaders(JNIEnv* env,
-                             net::HttpResponseHeaders* headers) override {
-    int status_code;
-    std::string reason_phrase;
-    if (response_->GetStatusInfo(env, &status_code, &reason_phrase)) {
-      std::string status_line("HTTP/1.1 ");
-      status_line.append(base::NumberToString(status_code));
-      status_line.append(" ");
-      status_line.append(reason_phrase);
-      headers->ReplaceStatusLine(status_line);
-    }
-    response_->GetResponseHeaders(env, headers);
-  }
-
- private:
-  std::unique_ptr<AwWebResourceResponse> response_;
-};
-
 // Handles intercepted, in-progress requests/responses, so that they can be
 // controlled and modified accordingly.
 class InterceptedRequest : public network::mojom::URLLoader,
@@ -96,7 +50,8 @@
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
       network::mojom::URLLoaderRequest loader_request,
       network::mojom::URLLoaderClientPtr client,
-      network::mojom::URLLoaderFactoryPtr target_factory);
+      network::mojom::URLLoaderFactoryPtr target_factory,
+      bool intercept_only);
   ~InterceptedRequest() override;
 
   void Restart();
@@ -131,7 +86,7 @@
   void InterceptResponseReceived(
       std::unique_ptr<AwWebResourceResponse> response);
 
-  void InputStreamFailed();
+  void InputStreamFailed(bool restart_needed);
 
  private:
   std::unique_ptr<AwContentsIoThreadClient> GetIoThreadClient();
@@ -148,6 +103,8 @@
   void CallOnComplete(const network::URLLoaderCompletionStatus& status,
                       bool wait_for_loader_error);
 
+  void SendErrorAndCompleteImmediately(int error_code);
+
   // TODO(timvolodine): consider factoring this out of this class.
   bool ShouldNotInterceptRequest();
 
@@ -165,6 +122,10 @@
   // To avoid sending multiple OnReceivedError callbacks.
   bool sent_error_callback_ = false;
 
+  // When true, the loader will not not proceed unless the
+  // shouldInterceptRequest callback provided a non-null response.
+  bool intercept_only_ = false;
+
   // If the |target_loader_| called OnComplete with an error this stores it.
   // That way the destructor can send it to OnReceivedError if safe browsing
   // error didn't occur.
@@ -185,6 +146,57 @@
   DISALLOW_COPY_AND_ASSIGN(InterceptedRequest);
 };
 
+class InterceptResponseDelegate
+    : public AndroidStreamReaderURLLoader::ResponseDelegate {
+ public:
+  explicit InterceptResponseDelegate(
+      std::unique_ptr<AwWebResourceResponse> response,
+      base::WeakPtr<InterceptedRequest> request)
+      : response_(std::move(response)), request_(request) {}
+
+  std::unique_ptr<android_webview::InputStream> OpenInputStream(
+      JNIEnv* env) override {
+    return response_->GetInputStream(env);
+  }
+
+  void OnInputStreamOpenFailed(bool* restarted) override {
+    request_->InputStreamFailed(false /* restart_needed */);
+    *restarted = false;
+  }
+
+  bool GetMimeType(JNIEnv* env,
+                   const GURL& url,
+                   android_webview::InputStream* stream,
+                   std::string* mime_type) override {
+    return response_->GetMimeType(env, mime_type);
+  }
+
+  bool GetCharset(JNIEnv* env,
+                  const GURL& url,
+                  android_webview::InputStream* stream,
+                  std::string* charset) override {
+    return response_->GetCharset(env, charset);
+  }
+
+  void AppendResponseHeaders(JNIEnv* env,
+                             net::HttpResponseHeaders* headers) override {
+    int status_code;
+    std::string reason_phrase;
+    if (response_->GetStatusInfo(env, &status_code, &reason_phrase)) {
+      std::string status_line("HTTP/1.1 ");
+      status_line.append(base::NumberToString(status_code));
+      status_line.append(" ");
+      status_line.append(reason_phrase);
+      headers->ReplaceStatusLine(status_line);
+    }
+    response_->GetResponseHeaders(env, headers);
+  }
+
+ private:
+  std::unique_ptr<AwWebResourceResponse> response_;
+  base::WeakPtr<InterceptedRequest> request_;
+};
+
 class ProtocolResponseDelegate
     : public AndroidStreamReaderURLLoader::ResponseDelegate {
  public:
@@ -198,7 +210,7 @@
   }
 
   void OnInputStreamOpenFailed(bool* restarted) override {
-    request_->InputStreamFailed();
+    request_->InputStreamFailed(true /* restart_needed */);
     *restarted = true;
   }
 
@@ -236,11 +248,13 @@
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
     network::mojom::URLLoaderRequest loader_request,
     network::mojom::URLLoaderClientPtr client,
-    network::mojom::URLLoaderFactoryPtr target_factory)
+    network::mojom::URLLoaderFactoryPtr target_factory,
+    bool intercept_only)
     : process_id_(process_id),
       request_id_(request_id),
       routing_id_(routing_id),
       options_(options),
+      intercept_only_(intercept_only),
       request_(request),
       traffic_annotation_(traffic_annotation),
       proxied_loader_binding_(this, std::move(loader_request)),
@@ -262,18 +276,13 @@
 }
 
 void InterceptedRequest::Restart() {
-  // TODO(timvolodine): add async check shouldOverrideUrlLoading and
-  // shouldInterceptRequest.
 
   std::unique_ptr<AwContentsIoThreadClient> io_thread_client =
       GetIoThreadClient();
   DCHECK(io_thread_client);
 
   if (ShouldBlockURL(request_.url, io_thread_client.get())) {
-    auto status = network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED);
-    SendErrorCallback(status.error_code, false);
-    target_client_->OnComplete(status);
-    delete this;
+    SendErrorAndCompleteImmediately(net::ERR_ACCESS_DENIED);
     return;
   }
 
@@ -332,12 +341,33 @@
     // normal network data.
     ContinueAfterInterceptWithOverride(std::move(response));
   } else {
+    // Request was not intercepted/overridden. Proceed with loading
+    // from network, unless this is a special |intercept_only_| loader,
+    // which happens for external schemes: e.g. unsupported schemes and
+    // cid: schemes.
+    if (intercept_only_) {
+      SendErrorAndCompleteImmediately(net::ERR_UNKNOWN_URL_SCHEME);
+      return;
+    }
     ContinueAfterIntercept();
   }
 }
 
-void InterceptedRequest::InputStreamFailed() {
+void InterceptedRequest::InputStreamFailed(bool restart_needed) {
   DCHECK(!input_stream_previously_failed_);
+
+  if (intercept_only_) {
+    // This can happen for unsupported schemes, when no proper
+    // response from shouldInterceptRequest() is received, i.e.
+    // the provided input stream in response failed to load. In
+    // this case we send and error and stop loading.
+    SendErrorAndCompleteImmediately(net::ERR_UNKNOWN_URL_SCHEME);
+    return;
+  }
+
+  if (!restart_needed)
+    return;
+
   input_stream_previously_failed_ = true;
   proxied_client_binding_.Unbind();
   Restart();
@@ -382,7 +412,8 @@
   proxied_client_binding_.Bind(mojo::MakeRequest(&proxied_client));
   AndroidStreamReaderURLLoader* loader = new AndroidStreamReaderURLLoader(
       request_, std::move(proxied_client), traffic_annotation_,
-      std::make_unique<InterceptResponseDelegate>(std::move(response)));
+      std::make_unique<InterceptResponseDelegate>(std::move(response),
+                                                  weak_factory_.GetWeakPtr()));
   loader->Start();
 }
 
@@ -630,6 +661,13 @@
   }
 }
 
+void InterceptedRequest::SendErrorAndCompleteImmediately(int error_code) {
+  auto status = network::URLLoaderCompletionStatus(error_code);
+  SendErrorCallback(status.error_code, false);
+  target_client_->OnComplete(status);
+  delete this;
+}
+
 void InterceptedRequest::SendErrorCallback(int error_code,
                                            bool safebrowsing_hit) {
   // Ensure we only send one error callback, e.g. to avoid sending two if
@@ -655,9 +693,11 @@
     int process_id,
     network::mojom::URLLoaderFactoryRequest loader_request,
     network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
-    std::unique_ptr<AwInterceptedRequestHandler> request_handler)
+    std::unique_ptr<AwInterceptedRequestHandler> request_handler,
+    bool intercept_only)
     : process_id_(process_id),
       request_handler_(std::move(request_handler)),
+      intercept_only_(intercept_only),
       weak_factory_(this) {
   // actual creation of the factory
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -684,7 +724,7 @@
   // will manage its own lifetime
   new AwProxyingURLLoaderFactory(process_id, std::move(loader_request),
                                  std::move(target_factory_info),
-                                 std::move(request_handler));
+                                 std::move(request_handler), false);
 }
 
 void AwProxyingURLLoaderFactory::CreateLoaderAndStart(
@@ -714,7 +754,8 @@
   // TODO(timvolodine): consider keeping track of requests.
   InterceptedRequest* req = new InterceptedRequest(
       process_id_, request_id, routing_id, options, request, traffic_annotation,
-      std::move(loader), std::move(client), std::move(target_factory_clone));
+      std::move(loader), std::move(client), std::move(target_factory_clone),
+      intercept_only_);
   req->Restart();
 }
 
diff --git a/android_webview/browser/aw_proxying_url_loader_factory.h b/android_webview/browser/aw_proxying_url_loader_factory.h
index 5a673ff..2585ff3 100644
--- a/android_webview/browser/aw_proxying_url_loader_factory.h
+++ b/android_webview/browser/aw_proxying_url_loader_factory.h
@@ -30,11 +30,17 @@
 // pass-through implementation.
 class AwProxyingURLLoaderFactory : public network::mojom::URLLoaderFactory {
  public:
+  // Create a factory that will create specialized URLLoaders for Android
+  // WebView. If |intercept_only| parameter is true the loader created by
+  // this factory will only execute the intercept callback
+  // (shouldInterceptRequest), it will not propagate the request to the
+  // target factory.
   AwProxyingURLLoaderFactory(
       int process_id,
       network::mojom::URLLoaderFactoryRequest loader_request,
       network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
-      std::unique_ptr<AwInterceptedRequestHandler> request_handler);
+      std::unique_ptr<AwInterceptedRequestHandler> request_handler,
+      bool intercept_only);
 
   ~AwProxyingURLLoaderFactory() override;
 
@@ -67,6 +73,12 @@
   // TODO(timvolodine): consider functionality to have multiple interception
   // handlers operating in sequence.
   std::unique_ptr<AwInterceptedRequestHandler> request_handler_;
+
+  // When true the loader resulting from this factory will only execute
+  // intercept callback (shouldInterceptRequest). If that returns without
+  // a response, the loader will abort loading.
+  bool intercept_only_;
+
   base::WeakPtrFactory<AwProxyingURLLoaderFactory> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(AwProxyingURLLoaderFactory);
diff --git a/android_webview/browser/net/aw_http_user_agent_settings.h b/android_webview/browser/net/aw_http_user_agent_settings.h
index bdbfe3e..50c3a25 100644
--- a/android_webview/browser/net/aw_http_user_agent_settings.h
+++ b/android_webview/browser/net/aw_http_user_agent_settings.h
@@ -9,7 +9,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "net/url_request/http_user_agent_settings.h"
+#include "net/base/http_user_agent_settings.h"
 
 namespace android_webview {
 
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index fb6f60d5..76f4df3 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -100,6 +100,7 @@
 import org.chromium.net.NetworkChangeNotifier;
 import org.chromium.network.mojom.ReferrerPolicy;
 import org.chromium.ui.base.ActivityWindowAndroid;
+import org.chromium.ui.base.Clipboard;
 import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.base.ViewAndroidDelegate;
 import org.chromium.ui.base.WindowAndroid;
@@ -3726,6 +3727,7 @@
             if (isDestroyedOrNoOperation(NO_WARN)) return;
             mWindowFocused = hasWindowFocus;
             mViewEventSink.onWindowFocusChanged(hasWindowFocus);
+            Clipboard.getInstance().onWindowFocusChanged(hasWindowFocus);
         }
 
         @Override
diff --git a/ash/app_list/views/assistant/assistant_page_view.cc b/ash/app_list/views/assistant/assistant_page_view.cc
index dbd85ba..13002cf7 100644
--- a/ash/app_list/views/assistant/assistant_page_view.cc
+++ b/ash/app_list/views/assistant/assistant_page_view.cc
@@ -11,7 +11,9 @@
 #include "ash/app_list/views/assistant/assistant_main_view.h"
 #include "ash/app_list/views/contents_view.h"
 #include "ash/assistant/model/assistant_ui_model.h"
+#include "ash/assistant/ui/assistant_ui_constants.h"
 #include "ash/assistant/ui/assistant_view_delegate.h"
+#include "ash/assistant/ui/assistant_web_view.h"
 #include "ash/assistant/util/assistant_util.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "base/strings/utf_string_conversions.h"
@@ -25,9 +27,6 @@
 
 namespace {
 
-constexpr int kHeightDip = 440;
-constexpr int kWidthDip = 640;
-
 // The height of the search box in |search_result_page_view_|. It is only for
 // animation.
 constexpr int kSearchBoxHeightDip = 56;
@@ -66,6 +65,13 @@
   if (assistant_view_delegate_) {
     assistant_main_view_ = new AssistantMainView(assistant_view_delegate_);
     AddChildView(assistant_main_view_);
+
+    // Web view.
+    assistant_web_view_ = new ash::AssistantWebView(assistant_view_delegate_);
+    AddChildView(assistant_web_view_);
+
+    // Update the view state based on the current UI mode.
+    OnUiModeChanged(assistant_view_delegate_->GetUiModel()->ui_mode());
   }
 }
 
@@ -74,13 +80,27 @@
 }
 
 gfx::Size AssistantPageView::CalculatePreferredSize() const {
-  return gfx::Size(kWidthDip, kHeightDip);
+  return gfx::Size(ash::kPreferredWidthDip, ash::kMaxHeightEmbeddedDip);
 }
 
 void AssistantPageView::RequestFocus() {
-  // |assistant_main_view_| could be nullptr in test.
-  if (assistant_main_view_)
-    assistant_main_view_->RequestFocus();
+  if (!assistant_view_delegate_)
+    return;
+
+  switch (assistant_view_delegate_->GetUiModel()->ui_mode()) {
+    case ash::AssistantUiMode::kLauncherEmbeddedUi:
+      if (assistant_main_view_)
+        assistant_main_view_->RequestFocus();
+      break;
+    case ash::AssistantUiMode::kWebUi:
+      if (assistant_web_view_)
+        assistant_web_view_->RequestFocus();
+      break;
+    case ash::AssistantUiMode::kMainUi:
+    case ash::AssistantUiMode::kMiniUi:
+      NOTREACHED();
+      break;
+  }
 }
 
 void AssistantPageView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
@@ -128,7 +148,8 @@
         AppListPage::contents_view()->GetSearchBoxBoundsForState(state);
   } else {
     onscreen_bounds = AppListPage::GetSearchBoxBounds();
-    onscreen_bounds.Offset((onscreen_bounds.width() - kWidthDip) / 2, 0);
+    onscreen_bounds.Offset(
+        (onscreen_bounds.width() - ash::kPreferredWidthDip) / 2, 0);
     onscreen_bounds.set_size(GetPreferredSize());
   }
 
@@ -138,8 +159,8 @@
 gfx::Rect AssistantPageView::GetSearchBoxBounds() const {
   gfx::Rect rect(AppListPage::GetSearchBoxBounds());
 
-  rect.Offset((rect.width() - kWidthDip) / 2, 0);
-  rect.set_size(gfx::Size(kWidthDip, kSearchBoxHeightDip));
+  rect.Offset((rect.width() - ash::kPreferredWidthDip) / 2, 0);
+  rect.set_size(gfx::Size(ash::kPreferredWidthDip, kSearchBoxHeightDip));
 
   return rect;
 }
@@ -154,6 +175,29 @@
       this, GetWidget(), /*reverse=*/true, /*dont_loop=*/false);
 }
 
+void AssistantPageView::OnUiModeChanged(ash::AssistantUiMode ui_mode) {
+  for (int i = 0; i < child_count(); ++i)
+    child_at(i)->SetVisible(false);
+
+  switch (ui_mode) {
+    case ash::AssistantUiMode::kLauncherEmbeddedUi:
+      if (assistant_main_view_)
+        assistant_main_view_->SetVisible(true);
+      break;
+    case ash::AssistantUiMode::kWebUi:
+      if (assistant_web_view_)
+        assistant_web_view_->SetVisible(true);
+      break;
+    case ash::AssistantUiMode::kMainUi:
+    case ash::AssistantUiMode::kMiniUi:
+      NOTREACHED();
+      break;
+  }
+
+  PreferredSizeChanged();
+  RequestFocus();
+}
+
 void AssistantPageView::OnUiVisibilityChanged(
     ash::AssistantVisibility new_visibility,
     ash::AssistantVisibility old_visibility,
diff --git a/ash/app_list/views/assistant/assistant_page_view.h b/ash/app_list/views/assistant/assistant_page_view.h
index 399a9e1..66bb00cc 100644
--- a/ash/app_list/views/assistant/assistant_page_view.h
+++ b/ash/app_list/views/assistant/assistant_page_view.h
@@ -14,6 +14,7 @@
 
 namespace ash {
 class AssistantViewDelegate;
+class AssistantWebView;
 }  // namespace ash
 
 namespace ui {
@@ -33,7 +34,6 @@
   ~AssistantPageView() override;
 
   void InitLayout();
-  void Back();
 
   // views::View:
   const char* GetClassName() const override;
@@ -53,6 +53,7 @@
   views::View* GetLastFocusableView() override;
 
   // AssistantUiModelObserver:
+  void OnUiModeChanged(ash::AssistantUiMode ui_mode) override;
   void OnUiVisibilityChanged(
       ash::AssistantVisibility new_visibility,
       ash::AssistantVisibility old_visibility,
@@ -64,6 +65,7 @@
 
   // Owned by the views hierarchy.
   AssistantMainView* assistant_main_view_ = nullptr;
+  ash::AssistantWebView* assistant_web_view_ = nullptr;
 
   // Used to enforce round corners on the Assistant view hierarchy.
   std::unique_ptr<ui::LayerOwner> mask_;
diff --git a/ash/assistant/assistant_ui_controller.cc b/ash/assistant/assistant_ui_controller.cc
index 5ded0031..b12d0ba 100644
--- a/ash/assistant/assistant_ui_controller.cc
+++ b/ash/assistant/assistant_ui_controller.cc
@@ -141,17 +141,18 @@
   if (model_.ui_mode() == AssistantUiMode::kLauncherEmbeddedUi)
     return;
 
-  DCHECK(container_view_);
   // Once screen context request state has become idle, it is safe to activate
   // the Assistant widget without causing complications.
-  if (request_state == ScreenContextRequestState::kIdle)
+  if (container_view_ && request_state == ScreenContextRequestState::kIdle)
     container_view_->GetWidget()->Activate();
 }
 
 bool AssistantUiController::OnCaptionButtonPressed(AssistantButtonId id) {
   switch (id) {
     case AssistantButtonId::kBack:
-      UpdateUiMode(AssistantUiMode::kMainUi);
+      UpdateUiMode(app_list_features::IsEmbeddedAssistantUIEnabled()
+                       ? AssistantUiMode::kLauncherEmbeddedUi
+                       : AssistantUiMode::kMainUi);
       return true;
     case AssistantButtonId::kClose:
       CloseUi(AssistantExitPoint::kCloseButton);
@@ -238,10 +239,6 @@
   if (!assistant::util::IsWebDeepLinkType(type))
     return;
 
-  // TODO(wutao): Behavior is not defined.
-  if (app_list_features::IsEmbeddedAssistantUIEnabled())
-    return;
-
   ShowUi(AssistantEntryPoint::kDeepLink);
   UpdateUiMode(AssistantUiMode::kWebUi);
 }
@@ -254,11 +251,11 @@
   // navigation was initiated by a server response. Otherwise the navigation
   // was user initiated so we only hide the UI to retain session state. That way
   // the user can choose to resume their session if they are so inclined.
-  // However, we close the UI if it is in the |kLauncherEmbeddedUi| mode, where
-  // we only maintain |kVisible| and |kClosed| two states.
+  // However, we close the UI if the feature |IsEmbeddedAssistantUIEnabled| is
+  // enabled, where we only maintain |kVisible| and |kClosed| two states.
   if (from_server)
     CloseUi(AssistantExitPoint::kNewBrowserTabFromServer);
-  else if (model_.ui_mode() == AssistantUiMode::kLauncherEmbeddedUi)
+  else if (app_list_features::IsEmbeddedAssistantUIEnabled())
     CloseUi(AssistantExitPoint::kNewBrowserTabFromUser);
   else
     HideUi(AssistantExitPoint::kNewBrowserTabFromUser);
@@ -407,9 +404,6 @@
     container_view_->GetWidget()->CloseNow();
     DCHECK_EQ(nullptr, container_view_);
   }
-
-  // Reset to default state.
-  model_.SetUiMode(AssistantUiMode::kMainUi);
 }
 
 void AssistantUiController::ToggleUi(
@@ -440,10 +434,8 @@
   if (ui_mode.has_value()) {
     AssistantUiMode mode = ui_mode.value();
     // TODO(wutao): Behavior is not defined.
-    if (model_.ui_mode() == AssistantUiMode::kLauncherEmbeddedUi) {
+    if (model_.ui_mode() == AssistantUiMode::kLauncherEmbeddedUi)
       DCHECK_NE(AssistantUiMode::kMiniUi, mode);
-      DCHECK_NE(AssistantUiMode::kWebUi, mode);
-    }
     model_.SetUiMode(mode);
     return;
   }
diff --git a/ash/assistant/model/BUILD.gn b/ash/assistant/model/BUILD.gn
index 64ae790..767e5ef 100644
--- a/ash/assistant/model/BUILD.gn
+++ b/ash/assistant/model/BUILD.gn
@@ -40,6 +40,7 @@
 
   deps = [
     "//ash/assistant/ui:constants",
+    "//ash/public/cpp",
     "//chromeos/services/assistant/public/mojom",
     "//services/content/public/cpp",
     "//ui/gfx/geometry",
diff --git a/ash/assistant/model/DEPS b/ash/assistant/model/DEPS
index 606c206..071c1e0 100644
--- a/ash/assistant/model/DEPS
+++ b/ash/assistant/model/DEPS
@@ -2,6 +2,7 @@
   "-ash",
   "+ash/assistant/ui/assistant_ui_constants.h",
   "+ash/assistant/model",
+  "+ash/public/cpp/app_list",
   "+chromeos/services/assistant/public" ,
   "+services/content/public",
   "+ui/gfx/geometry",
diff --git a/ash/assistant/model/assistant_ui_model.cc b/ash/assistant/model/assistant_ui_model.cc
index d9c67e6..960c25e5 100644
--- a/ash/assistant/model/assistant_ui_model.cc
+++ b/ash/assistant/model/assistant_ui_model.cc
@@ -5,10 +5,14 @@
 #include "ash/assistant/model/assistant_ui_model.h"
 
 #include "ash/assistant/model/assistant_ui_model_observer.h"
+#include "ash/public/cpp/app_list/app_list_features.h"
 
 namespace ash {
 
-AssistantUiModel::AssistantUiModel() = default;
+AssistantUiModel::AssistantUiModel()
+    : ui_mode_(app_list_features::IsEmbeddedAssistantUIEnabled()
+                   ? AssistantUiMode::kLauncherEmbeddedUi
+                   : AssistantUiMode::kMainUi) {}
 
 AssistantUiModel::~AssistantUiModel() = default;
 
diff --git a/ash/assistant/model/assistant_ui_model.h b/ash/assistant/model/assistant_ui_model.h
index a4974aa..638d497 100644
--- a/ash/assistant/model/assistant_ui_model.h
+++ b/ash/assistant/model/assistant_ui_model.h
@@ -126,7 +126,7 @@
       base::Optional<AssistantExitPoint> exit_point);
   void NotifyUsableWorkAreaChanged();
 
-  AssistantUiMode ui_mode_ = AssistantUiMode::kMainUi;
+  AssistantUiMode ui_mode_;
 
   AssistantVisibility visibility_ = AssistantVisibility::kClosed;
 
diff --git a/ash/assistant/ui/assistant_ui_constants.h b/ash/assistant/ui/assistant_ui_constants.h
index 58c51383..757f555 100644
--- a/ash/assistant/ui/assistant_ui_constants.h
+++ b/ash/assistant/ui/assistant_ui_constants.h
@@ -20,6 +20,7 @@
 constexpr int kCornerRadiusDip = 20;
 constexpr int kMiniUiCornerRadiusDip = 24;
 constexpr int kMaxHeightDip = 640;
+constexpr int kMaxHeightEmbeddedDip = 440;
 constexpr int kPaddingDip = 14;
 constexpr int kPreferredWidthDip = 640;
 constexpr int kSpacingDip = 8;
diff --git a/ash/assistant/ui/assistant_web_view.cc b/ash/assistant/ui/assistant_web_view.cc
index 0e08cbef..ad3aa565 100644
--- a/ash/assistant/ui/assistant_web_view.cc
+++ b/ash/assistant/ui/assistant_web_view.cc
@@ -11,6 +11,7 @@
 #include "ash/assistant/ui/assistant_ui_constants.h"
 #include "ash/assistant/ui/assistant_view_delegate.h"
 #include "ash/assistant/util/deep_link_util.h"
+#include "ash/public/cpp/app_list/app_list_features.h"
 #include "base/bind.h"
 #include "base/callback.h"
 #include "services/content/public/cpp/navigable_contents_view.h"
@@ -28,6 +29,12 @@
 
 namespace {
 
+int GetMaxHeight() {
+  return app_list_features::IsEmbeddedAssistantUIEnabled()
+             ? kMaxHeightEmbeddedDip
+             : kMaxHeightDip;
+}
+
 // ContentsMaskPainter ---------------------------------------------------------
 
 class ContentsMaskPainter : public views::Painter {
@@ -68,12 +75,12 @@
   InitLayout();
 
   delegate_->AddObserver(this);
+  delegate_->AddUiModelObserver(this);
 }
 
 AssistantWebView::~AssistantWebView() {
+  delegate_->RemoveUiModelObserver(this);
   delegate_->RemoveObserver(this);
-
-  RemoveContents();
 }
 
 const char* AssistantWebView::GetClassName() const {
@@ -85,11 +92,14 @@
 }
 
 int AssistantWebView::GetHeightForWidth(int width) const {
-  // |height| <= |kMaxHeightDip|.
+  if (app_list_features::IsEmbeddedAssistantUIEnabled())
+    return GetMaxHeight();
+
+  // |height| <= |GetMaxHeight()|.
   // |height| should not exceed the height of the usable work area.
   gfx::Rect usable_work_area = delegate_->GetUiModel()->usable_work_area();
 
-  return std::min(kMaxHeightDip, usable_work_area.height());
+  return std::min(GetMaxHeight(), usable_work_area.height());
 }
 
 void AssistantWebView::ChildPreferredSizeChanged(views::View* child) {
@@ -133,6 +143,8 @@
   caption_bar_ = new CaptionBar();
   caption_bar_->set_delegate(this);
   caption_bar_->SetButtonVisible(AssistantButtonId::kMinimize, false);
+  if (app_list_features::IsEmbeddedAssistantUIEnabled())
+    caption_bar_->SetButtonVisible(AssistantButtonId::kClose, false);
   AddChildView(caption_bar_);
 
   // Contents mask.
@@ -177,7 +189,7 @@
 
   const gfx::Size preferred_size =
       gfx::Size(kPreferredWidthDip,
-                kMaxHeightDip - caption_bar_->GetPreferredSize().height());
+                GetMaxHeight() - caption_bar_->GetPreferredSize().height());
 
   auto contents_params = content::mojom::NavigableContentsParams::New();
   contents_params->enable_view_auto_resize = true;
@@ -246,6 +258,17 @@
   contents_->Navigate(url);
 }
 
+void AssistantWebView::OnUiVisibilityChanged(
+    AssistantVisibility new_visibility,
+    AssistantVisibility old_visibility,
+    base::Optional<AssistantEntryPoint> entry_point,
+    base::Optional<AssistantExitPoint> exit_point) {
+  // When the Assistant UI is closed we need to clear the |contents_| in order
+  // to free the memory.
+  if (new_visibility == AssistantVisibility::kClosed)
+    RemoveContents();
+}
+
 void AssistantWebView::RemoveContents() {
   if (!contents_)
     return;
diff --git a/ash/assistant/ui/assistant_web_view.h b/ash/assistant/ui/assistant_web_view.h
index 105595c..abb1acf 100644
--- a/ash/assistant/ui/assistant_web_view.h
+++ b/ash/assistant/ui/assistant_web_view.h
@@ -9,6 +9,7 @@
 #include <memory>
 #include <string>
 
+#include "ash/assistant/model/assistant_ui_model_observer.h"
 #include "ash/assistant/ui/assistant_view_delegate.h"
 #include "ash/assistant/ui/caption_bar.h"
 #include "base/component_export.h"
@@ -33,7 +34,8 @@
       public aura::WindowObserver,
       public AssistantViewDelegateObserver,
       public CaptionBarDelegate,
-      public content::NavigableContentsObserver {
+      public content::NavigableContentsObserver,
+      public AssistantUiModelObserver {
  public:
   explicit AssistantWebView(AssistantViewDelegate* delegate);
   ~AssistantWebView() override;
@@ -68,6 +70,13 @@
                              WindowOpenDisposition disposition,
                              bool from_user_gesture) override;
 
+  // AssistantUiModelObserver:
+  void OnUiVisibilityChanged(
+      AssistantVisibility new_visibility,
+      AssistantVisibility old_visibility,
+      base::Optional<AssistantEntryPoint> entry_point,
+      base::Optional<AssistantExitPoint> exit_point) override;
+
  private:
   void InitLayout();
   void RemoveContents();
diff --git a/base/mac/scoped_mach_port.cc b/base/mac/scoped_mach_port.cc
index 13307f2c..5697a07f 100644
--- a/base/mac/scoped_mach_port.cc
+++ b/base/mac/scoped_mach_port.cc
@@ -34,5 +34,34 @@
 }
 
 }  // namespace internal
+
+bool CreateMachPort(ScopedMachReceiveRight* receive,
+                    ScopedMachSendRight* send,
+                    Optional<mach_port_msgcount_t> queue_limit) {
+  mach_port_options_t options{};
+  options.flags = (send != nullptr ? MPO_INSERT_SEND_RIGHT : 0);
+
+  if (queue_limit.has_value()) {
+    options.flags |= MPO_QLIMIT;
+    options.mpl.mpl_qlimit = *queue_limit;
+  }
+
+  kern_return_t kr =
+      mach_port_construct(mach_task_self(), &options, 0,
+                          ScopedMachReceiveRight::Receiver(*receive).get());
+  if (kr != KERN_SUCCESS) {
+    MACH_LOG(ERROR, kr) << "mach_port_construct";
+    return false;
+  }
+
+  // Multiple rights are coalesced to the same name in a task, so assign the
+  // send rights to the same name.
+  if (send) {
+    send->reset(receive->get());
+  }
+
+  return true;
+}
+
 }  // namespace mac
 }  // namespace base
diff --git a/base/mac/scoped_mach_port.h b/base/mac/scoped_mach_port.h
index 67fed6b..bff5846 100644
--- a/base/mac/scoped_mach_port.h
+++ b/base/mac/scoped_mach_port.h
@@ -8,6 +8,7 @@
 #include <mach/mach.h>
 
 #include "base/base_export.h"
+#include "base/optional.h"
 #include "base/scoped_generic.h"
 
 namespace base {
@@ -61,6 +62,15 @@
 // the receive rights that are members of the port set.
 using ScopedMachPortSet = ScopedGeneric<mach_port_t, internal::PortSetTraits>;
 
+// Constructs a Mach port receive right and places the result in |receive|.
+// If |send| is non-null, a send right will be created as well and stored
+// there. If |queue_limit| is specified, the receive right will be constructed
+// with the specified mpo_qlmit. Returns true on success and false on failure.
+BASE_EXPORT bool CreateMachPort(
+    ScopedMachReceiveRight* receive,
+    ScopedMachSendRight* send,
+    Optional<mach_port_msgcount_t> queue_limit = nullopt);
+
 }  // namespace mac
 }  // namespace base
 
diff --git a/base/task/sequence_manager/sequence_manager.h b/base/task/sequence_manager/sequence_manager.h
index 1525911f..b6f08c1 100644
--- a/base/task/sequence_manager/sequence_manager.h
+++ b/base/task/sequence_manager/sequence_manager.h
@@ -198,6 +198,12 @@
 BASE_EXPORT std::unique_ptr<SequenceManager> CreateUnboundSequenceManager(
     SequenceManager::Settings settings = SequenceManager::Settings());
 
+// Create a SequenceManager that runs on top of |task_runner|.
+// TODO(alexclarke): Change |task_runner| to a SequencedTaskRunner.
+BASE_EXPORT std::unique_ptr<SequenceManager> CreateFunneledSequenceManager(
+    scoped_refptr<SingleThreadTaskRunner> task_runner,
+    SequenceManager::Settings settings = SequenceManager::Settings());
+
 }  // namespace sequence_manager
 }  // namespace base
 
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc
index ea7c599..07bcdbd 100644
--- a/base/task/sequence_manager/sequence_manager_impl.cc
+++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -58,6 +58,16 @@
   return internal::SequenceManagerImpl::CreateUnbound(std::move(settings));
 }
 
+BASE_EXPORT std::unique_ptr<SequenceManager> CreateFunneledSequenceManager(
+    scoped_refptr<SingleThreadTaskRunner> task_runner,
+    SequenceManager::Settings settings) {
+  std::unique_ptr<SequenceManager> sequence_manager =
+      internal::SequenceManagerImpl::CreateSequenceFunneled(
+          std::move(task_runner), std::move(settings));
+  sequence_manager->BindToCurrentThread();
+  return sequence_manager;
+}
+
 namespace internal {
 
 namespace {
@@ -195,6 +205,17 @@
       std::move(settings)));
 }
 
+// static
+std::unique_ptr<SequenceManagerImpl>
+SequenceManagerImpl::CreateSequenceFunneled(
+    scoped_refptr<SingleThreadTaskRunner> task_runner,
+    SequenceManager::Settings settings) {
+  return WrapUnique(
+      new SequenceManagerImpl(ThreadControllerImpl::CreateSequenceFunneled(
+                                  std::move(task_runner), settings.clock),
+                              std::move(settings)));
+}
+
 void SequenceManagerImpl::BindToMessageLoop(
     MessageLoopBase* message_loop_base) {
   controller_->BindToCurrentThread(message_loop_base);
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h
index f780a67..88e05d19 100644
--- a/base/task/sequence_manager/sequence_manager_impl.h
+++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -96,6 +96,11 @@
   static std::unique_ptr<SequenceManagerImpl> CreateUnbound(
       SequenceManager::Settings settings);
 
+  // Create a SequenceManager that funnels it's tasks down onto |task_runner|.
+  static std::unique_ptr<SequenceManagerImpl> CreateSequenceFunneled(
+      scoped_refptr<SingleThreadTaskRunner> task_runner,
+      SequenceManager::Settings settings);
+
   // SequenceManager implementation:
   void BindToCurrentThread() override;
   void BindToMessageLoop(MessageLoopBase* message_loop_base) override;
diff --git a/base/task/sequence_manager/thread_controller_impl.cc b/base/task/sequence_manager/thread_controller_impl.cc
index 7fc0c9de..f40fd33 100644
--- a/base/task/sequence_manager/thread_controller_impl.cc
+++ b/base/task/sequence_manager/thread_controller_impl.cc
@@ -58,6 +58,14 @@
       time_source));
 }
 
+std::unique_ptr<ThreadControllerImpl>
+ThreadControllerImpl::CreateSequenceFunneled(
+    scoped_refptr<SingleThreadTaskRunner> task_runner,
+    const TickClock* time_source) {
+  return WrapUnique(
+      new ThreadControllerImpl(nullptr, std::move(task_runner), time_source));
+}
+
 void ThreadControllerImpl::SetSequencedTaskSource(
     SequencedTaskSource* sequence) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(associated_thread_->sequence_checker);
diff --git a/base/task/sequence_manager/thread_controller_impl.h b/base/task/sequence_manager/thread_controller_impl.h
index 94c2400..917bc069 100644
--- a/base/task/sequence_manager/thread_controller_impl.h
+++ b/base/task/sequence_manager/thread_controller_impl.h
@@ -40,6 +40,10 @@
       MessageLoopBase* message_loop_base,
       const TickClock* time_source);
 
+  static std::unique_ptr<ThreadControllerImpl> CreateSequenceFunneled(
+      scoped_refptr<SingleThreadTaskRunner> task_runner,
+      const TickClock* time_source);
+
   // ThreadController:
   void SetWorkBatchSize(int work_batch_size) override;
   void WillQueueTask(PendingTask* pending_task) override;
diff --git a/build/android/gyp/java_cpp_strings.py b/build/android/gyp/java_cpp_strings.py
index 59fc04d..acaaf22 100755
--- a/build/android/gyp/java_cpp_strings.py
+++ b/build/android/gyp/java_cpp_strings.py
@@ -121,7 +121,8 @@
 
   def _ParseLine(self, line):
     if not self._in_string:
-      self._ParseComment(line)
+      if not self._ParseString(line):
+        self._ParseComment(line)
       return
 
     if self._in_comment:
diff --git a/build/android/gyp/java_cpp_strings_tests.py b/build/android/gyp/java_cpp_strings_tests.py
index d81b336..acf51e4 100755
--- a/build/android/gyp/java_cpp_strings_tests.py
+++ b/build/android/gyp/java_cpp_strings_tests.py
@@ -49,6 +49,7 @@
     test_data = """
 // Single line string constants.
 const char kAString[] = "a-value";
+const char kNoComment[] = "no-comment";
 
 // Single line switch with a big space.
 const char kAStringWithSpace[]                      = "a-value";
@@ -63,15 +64,17 @@
     "invalid-line-break";
 """.split('\n')
     strings = java_cpp_strings.StringFileParser(test_data).Parse()
-    self.assertEqual(3, len(strings))
+    self.assertEqual(4, len(strings))
     self.assertEqual('A_STRING', strings[0].name)
     self.assertEqual('"a-value"', strings[0].value)
-    self.assertEqual('A_STRING_WITH_SPACE', strings[1].name)
-    self.assertEqual('"a-value"', strings[1].value)
+    self.assertEqual('NO_COMMENT', strings[1].name)
+    self.assertEqual('"no-comment"', strings[1].value)
+    self.assertEqual('A_STRING_WITH_SPACE', strings[2].name)
+    self.assertEqual('"a-value"', strings[2].value)
     self.assertEqual('A_STRING_WITH_A_VERY_LONG_NAME_THAT_WILL_HAVE_TO_WRAP',
-                     strings[2].name)
+                     strings[3].name)
     self.assertEqual('"a-string-with-a-very-long-name-that-will-have-to-wrap"',
-                     strings[2].value)
+                     strings[3].value)
 
   def testTemplateParsing(self):
     test_data = """
diff --git a/build/config/fuchsia/symbol_archive.gni b/build/config/fuchsia/symbol_archive.gni
index cc8b23f..b4e9ec31 100644
--- a/build/config/fuchsia/symbol_archive.gni
+++ b/build/config/fuchsia/symbol_archive.gni
@@ -13,6 +13,8 @@
 #   archive_name: The path to the compressed tarball that will be
 #                   generated.
 template("symbol_archive") {
+  assert(!is_debug)
+
   action(target_name) {
     _ids_txt = invoker.ids_txt
     _build_ids = invoker.archive_name
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index d93fbe46..2f2aa1f 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8d562ec8b8d81d11fa8b6bb199ca07049ab9e074
\ No newline at end of file
+1dc5fa95d6cf9874bb56250199cdf49cbe92b501
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index f5a1ede..acf3cd87 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-6687834853f97abfde3948deff3c7bb37d23ec08
\ No newline at end of file
+5fd7f2fc6f9501d959f3b94d71cd43cc9c663996
\ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java
index ec1d18d9..8e3e091 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java
@@ -25,13 +25,17 @@
 
     static final WritableIntPropertyKey PROGRESS = new WritableIntPropertyKey();
 
+    @VisibleForTesting
+    public static final WritableBooleanPropertyKey PROGRESS_VISIBLE =
+            new WritableBooleanPropertyKey();
+
     static final WritableBooleanPropertyKey PROGRESS_PULSING = new WritableBooleanPropertyKey();
 
     static final WritableObjectPropertyKey<Runnable> FEEDBACK_BUTTON_CALLBACK =
             new WritableObjectPropertyKey<>();
 
     public AssistantHeaderModel() {
-        super(STATUS_MESSAGE, FEEDBACK_VISIBLE, PROGRESS, PROGRESS_PULSING,
+        super(STATUS_MESSAGE, FEEDBACK_VISIBLE, PROGRESS, PROGRESS_VISIBLE, PROGRESS_PULSING,
                 FEEDBACK_BUTTON_CALLBACK);
     }
 
@@ -46,6 +50,11 @@
     }
 
     @CalledByNative
+    private void setProgressVisible(boolean visible) {
+        set(PROGRESS_VISIBLE, visible);
+    }
+
+    @CalledByNative
     private void setProgressPulsingEnabled(boolean enabled) {
         set(PROGRESS_PULSING, enabled);
     }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java
index 812d3a2..fee16812 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java
@@ -48,6 +48,12 @@
                     model.get(AssistantHeaderModel.FEEDBACK_VISIBLE) ? View.VISIBLE : View.GONE);
         } else if (AssistantHeaderModel.PROGRESS == propertyKey) {
             view.mProgressBar.setProgress(model.get(AssistantHeaderModel.PROGRESS));
+        } else if (AssistantHeaderModel.PROGRESS_VISIBLE == propertyKey) {
+            if (model.get(AssistantHeaderModel.PROGRESS_VISIBLE)) {
+                view.mProgressBar.show();
+            } else {
+                view.mProgressBar.hide();
+            }
         } else if (AssistantHeaderModel.PROGRESS_PULSING == propertyKey) {
             if (model.get(AssistantHeaderModel.PROGRESS_PULSING)) {
                 view.mProgressBar.enablePulsing();
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
index 5a124d4..7350345 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java
@@ -176,6 +176,13 @@
 
         // Progress bar must be shown.
         Assert.assertTrue(bottomSheet.findViewById(R.id.progress_bar).isShown());
+
+        // Disable progress bar.
+        ThreadUtils.runOnUiThreadBlocking(
+                ()
+                        -> assistantCoordinator.getModel().getHeaderModel().set(
+                                AssistantHeaderModel.PROGRESS_VISIBLE, false));
+        Assert.assertFalse(bottomSheet.findViewById(R.id.progress_bar).isShown());
     }
 
     private void testChips(InOrder inOrder, AssistantCarouselModel carouselModel,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
index 0d8ebcc..90e71f3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -173,6 +173,7 @@
 import org.chromium.printing.PrintingControllerImpl;
 import org.chromium.ui.UiUtils;
 import org.chromium.ui.base.ActivityWindowAndroid;
+import org.chromium.ui.base.Clipboard;
 import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.base.WindowAndroid;
@@ -911,6 +912,8 @@
                 if (tab != null) tab.onActivityHidden();
             }
         }
+
+        Clipboard.getInstance().onWindowFocusChanged(hasFocus);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java
index 8d01430..9a7efae1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java
@@ -180,7 +180,8 @@
             p.setTitle(ContentSettingsResources.getTitle(contentType));
             p.setOnPreferenceClickListener(this);
 
-            if ((Type.CAMERA == prefCategory || Type.MICROPHONE == prefCategory)
+            if ((Type.CAMERA == prefCategory || Type.MICROPHONE == prefCategory
+                        || Type.NOTIFICATIONS == prefCategory)
                     && SiteSettingsCategory.createFromType(prefCategory)
                                .showPermissionBlockedMessage(getActivity())) {
                 // Show 'disabled' message when permission is not granted in Android.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
index e1a78f9..85453be 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -18,6 +18,7 @@
 import org.chromium.base.Log;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.task.AsyncTask;
+import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.invalidation.InvalidationServiceFactory;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.SigninManager.SignInCallback;
@@ -141,8 +142,10 @@
             return;
         }
 
+        boolean mice_enabled =
+                ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY);
         Account syncAccount = mChromeSigninController.getSignedInUser();
-        if (syncAccount == null) {
+        if (syncAccount == null && !mice_enabled) {
             return;
         }
 
@@ -154,7 +157,7 @@
         }
 
         // Always check for account deleted.
-        if (!accountExists(syncAccount)) {
+        if (syncAccount != null && !accountExists(syncAccount)) {
             // It is possible that Chrome got to this point without account
             // rename notification. Let us signout before doing a rename.
             AsyncTask<Void> task = new AsyncTask<Void>() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilterProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilterProvider.java
index 8dd9ab3..0557973 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilterProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilterProvider.java
@@ -4,6 +4,9 @@
 
 package org.chromium.chrome.browser.tabmodel;
 
+import org.chromium.chrome.browser.tasks.tabgroup.TabGroupModelFilter;
+import org.chromium.chrome.browser.util.FeatureUtilities;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -89,7 +92,9 @@
      * @return a {@link TabModelFilter}.
      */
     private TabModelFilter createTabModelFilter(TabModel model) {
-        // TODO(meiliang): build based on chrome feature.
+        if (FeatureUtilities.isTabGroupsAndroidEnabled()) {
+            return new TabGroupModelFilter(model);
+        }
         return new EmptyTabModelFilter(model);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java
index 24d0539..300b911 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridCoordinator.java
@@ -6,19 +6,22 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.support.annotation.Nullable;
 
 import org.chromium.base.ApplicationStatus;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.dependency_injection.ActivityScope;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
+import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
-import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tasks.tab_groups.TabGroupUtils;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
 import org.chromium.ui.modelutil.PropertyModel;
 
+import java.util.List;
+
 /**
  * A coordinator for BottomTabGrid component. Manages the communication with
  * {@link TabListCoordinator} as well as the life-cycle of shared component
@@ -43,9 +46,9 @@
         mTabGridCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context,
                 tabModelSelector, tabContentManager, bottomSheetController.getBottomSheet(), false);
 
-        mMediator =
-                new BottomTabGridMediator(mContext, bottomSheetController, this::resetWithTabModel,
-                        mToolbarPropertyModel, tabModelSelector, tabCreatorManager);
+        mMediator = new BottomTabGridMediator(mContext, bottomSheetController,
+                this::resetWithListOfTabs, mToolbarPropertyModel, tabModelSelector,
+                tabCreatorManager);
         startObservingForCreationIPH();
     }
 
@@ -67,17 +70,17 @@
     }
 
     /**
-     * Updates tabs list through {@link TabListCoordinator} with given tab model and
-     * calls onReset() on {@link BottomTabGridMediator}
+     * Updates tabs list through {@link TabListCoordinator} with given list of Tabs and
+     * calls onReset() on {@link BottomTabGridMediator}.
      */
-    public void resetWithTabModel(TabModel tabModel) {
-        mTabGridCoordinator.resetWithTabModel(tabModel);
-        updateBottomSheetContent(tabModel);
+    public void resetWithListOfTabs(@Nullable List<Tab> tabs) {
+        mTabGridCoordinator.resetWithListOfTabs(tabs);
+        updateBottomSheetContent(tabs);
         mMediator.onReset(mBottomSheetContent);
     }
 
-    private void updateBottomSheetContent(TabModel tabModel) {
-        if (tabModel != null) {
+    private void updateBottomSheetContent(@Nullable List<Tab> tabs) {
+        if (tabs != null) {
             // create bottom sheet content
             mToolbarCoordinator = new BottomTabGridSheetToolbarCoordinator(
                     mContext, mTabGridCoordinator.getContainerView(), mToolbarPropertyModel);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridMediator.java
index 5e8029f..3d41547 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabGridMediator.java
@@ -5,17 +5,18 @@
 package org.chromium.chrome.browser.tasks.tab_list_ui;
 
 import android.content.Context;
+import android.support.annotation.Nullable;
 import android.view.View.OnClickListener;
 
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
 import org.chromium.chrome.browser.tabmodel.TabLaunchType;
-import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabSelectionType;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.BottomSheetContent;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.StateChangeReason;
@@ -25,6 +26,8 @@
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.ui.modelutil.PropertyModel;
 
+import java.util.List;
+
 /**
  * A mediator for the BottomTabGrid component, respoonsible for communicating
  * with the components' coordinator as well as managing the state of the bottom
@@ -38,9 +41,9 @@
         /**
          * Handles a reset event originated from {@link BottomTabGridMediator}.
          *
-         * @param tabModel current {@link TabModel} instance.
+         * @param tabs List of Tabs to reset.
          */
-        void resetWithTabModel(TabModel tabModel);
+        void resetWithListOfTabs(@Nullable List<Tab> tabs);
     }
 
     private final Context mContext;
@@ -48,7 +51,7 @@
     private final BottomSheetObserver mSheetObserver;
     private final PropertyModel mModel;
     private final TabModelSelector mTabModelSelector;
-    private final TabModelSelectorTabModelObserver mTabModelObserver;
+    private final TabModelObserver mTabModelObserver;
     private final TabCreatorManager mTabCreatorManager;
 
     BottomTabGridMediator(Context context, BottomSheetController bottomSheetController,
@@ -64,12 +67,12 @@
         mSheetObserver = new EmptyBottomSheetObserver() {
             @Override
             public void onSheetClosed(@StateChangeReason int reason) {
-                resetHandler.resetWithTabModel(null);
+                resetHandler.resetWithListOfTabs(null);
             }
         };
 
         // register for tab model
-        mTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) {
+        mTabModelObserver = new EmptyTabModelObserver() {
             @Override
             public void didCloseTab(int tabId, boolean incognito) {
                 updateBottomSheetTitleAndMargin();
@@ -82,9 +85,10 @@
 
             @Override
             public void didSelectTab(Tab tab, int type, int lastId) {
-                if (type == TabSelectionType.FROM_USER) resetHandler.resetWithTabModel(null);
+                if (type == TabSelectionType.FROM_USER) resetHandler.resetWithListOfTabs(null);
             }
         };
+        mTabModelSelector.getTabModelFilterProvider().addTabModelFilterObserver(mTabModelObserver);
 
         // setup toolbar property model
         setupToolbarClickHandlers();
@@ -111,10 +115,14 @@
      */
     @Override
     public void destroy() {
-        mTabModelObserver.destroy();
+        if (mTabModelObserver != null) {
+            mTabModelSelector.getTabModelFilterProvider().removeTabModelFilterObserver(
+                    mTabModelObserver);
+        }
     }
 
     private void showTabGridInBottomSheet(BottomTabGridSheetContent sheetContent) {
+        updateBottomSheetTitleAndMargin();
         mBottomSheetController.getBottomSheet().addObserver(mSheetObserver);
         mBottomSheetController.requestShowContent(sheetContent, true);
         mBottomSheetController.expandSheet();
@@ -132,7 +140,11 @@
     }
 
     private void updateBottomSheetTitleAndMargin() {
-        int tabsCount = mTabModelSelector.getCurrentModel().getCount();
+        Tab currentTab = mTabModelSelector.getCurrentTab();
+        int tabsCount = mTabModelSelector.getTabModelFilterProvider()
+                                .getCurrentTabModelFilter()
+                                .getRelatedTabList(currentTab.getId())
+                                .size();
         mModel.set(BottomTabGridSheetProperties.HEADER_TITLE,
                 mContext.getResources().getQuantityString(
                         R.plurals.bottom_tab_grid_title_placeholder, tabsCount, tabsCount));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherCoordinator.java
index 15d53d5..35f0b63 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/GridTabSwitcherCoordinator.java
@@ -12,12 +12,16 @@
 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
 import org.chromium.chrome.browser.init.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
+import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.toolbar.ToolbarManager;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Parent coordinator that is responsible for showing a grid of tabs for the main TabSwitcher UI.
  */
@@ -61,7 +65,14 @@
      */
     @Override
     public void resetWithTabModel(TabModel tabModel) {
-        mTabGridCoordinator.resetWithTabModel(tabModel);
+        List<Tab> tabs = null;
+        if (tabModel != null) {
+            tabs = new ArrayList<>();
+            for (int i = 0; i < tabModel.getCount(); i++) {
+                tabs.add(tabModel.getTabAt(i));
+            }
+        }
+        mTabGridCoordinator.resetWithListOfTabs(tabs);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListCoordinator.java
index 6083e30..f3f96fc0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListCoordinator.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.LinearLayoutManager;
 import android.view.LayoutInflater;
@@ -17,7 +18,7 @@
 import org.chromium.chrome.browser.favicon.FaviconHelper;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -26,6 +27,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.List;
 
 /**
  * Coordinator for showing UI for a list of tabs. Can be used in GRID or STRIP modes.
@@ -101,11 +103,11 @@
     }
 
     /**
-     * Reset the tab grid with the given {@link TabModel}. Can be null.
-     * @param tabModel The current {@link TabModel} to show the tabs for in the UI.
+     * Reset the tab grid with the given List of Tabs. Can be null.
+     * @param tabs List of Tabs to show for in the UI.
      */
-    public void resetWithTabModel(TabModel tabModel) {
-        mMediator.resetWithTabModel(tabModel);
+    public void resetWithListOfTabs(@Nullable List<Tab> tabs) {
+        mMediator.resetWithListOfTabs(tabs);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListMediator.java
index 9531b34..36eb7d3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListMediator.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.support.annotation.Nullable;
 
 import org.chromium.base.Callback;
 import org.chromium.base.metrics.RecordHistogram;
@@ -18,14 +19,16 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabFavicon;
 import org.chromium.chrome.browser.tab.TabObserver;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
 import org.chromium.chrome.browser.tabmodel.TabSelectionType;
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Mediator for business logic for the tab grid. This class should be initialized with a list of
@@ -108,7 +111,7 @@
         }
     };
 
-    private final TabModelSelectorTabModelObserver mTabModelObserver;
+    private final TabModelObserver mTabModelObserver;
 
     /**
      * Interface for implementing a {@link Runnable} that takes a tabId for a generic action.
@@ -135,7 +138,7 @@
         mFaviconHelper = faviconHelper;
         mProfile = profile;
 
-        mTabModelObserver = new TabModelSelectorTabModelObserver(mTabModelSelector) {
+        mTabModelObserver = new EmptyTabModelObserver() {
             @Override
             public void didSelectTab(Tab tab, int type, int lastId) {
                 if (tab.getId() == lastId) return;
@@ -149,6 +152,7 @@
                 mModel.get(newIndex).set(TabProperties.IS_SELECTED, true);
             }
 
+            // TODO(meiliang): should not use index from tabmodel.
             @Override
             public void tabClosureUndone(Tab tab) {
                 int index = TabModelUtils.getTabIndexById(
@@ -169,19 +173,24 @@
                 mModel.removeAt(mModel.indexFromId(tab.getId()));
             }
         };
+
+        mTabModelSelector.getTabModelFilterProvider().addTabModelFilterObserver(mTabModelObserver);
     }
 
     /**
      * Initialize the component with a list of tabs to show in a grid.
+     * @param tabs
      */
-    public void resetWithTabModel(TabModel tabModel) {
+    public void resetWithListOfTabs(@Nullable List<Tab> tabs) {
         mModel.set(new ArrayList<>());
-        if (tabModel == null) {
+        if (tabs == null) {
             return;
         }
-        int selectedIndex = tabModel.index();
-        for (int i = 0; i < tabModel.getCount(); i++) {
-            addTabInfoToModel(tabModel.getTabAt(i), i, i == selectedIndex);
+        Tab currentTab = mTabModelSelector.getCurrentTab();
+        if (currentTab == null) return;
+
+        for (int i = 0; i < tabs.size(); i++) {
+            addTabInfoToModel(tabs.get(i), i, tabs.get(i).getId() == currentTab.getId());
         }
     }
 
@@ -195,7 +204,10 @@
                 tabModel.getTabAt(i).removeObserver(mTabObserver);
             }
         }
-        mTabModelObserver.destroy();
+        if (mTabModelObserver != null) {
+            mTabModelSelector.getTabModelFilterProvider().removeTabModelFilterObserver(
+                    mTabModelObserver);
+        }
     }
 
     private void addTabInfoToModel(final Tab tab, int index, boolean isSelected) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripBottomToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripBottomToolbarCoordinator.java
index 16231f95..a0e856b5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripBottomToolbarCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripBottomToolbarCoordinator.java
@@ -9,12 +9,14 @@
 
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
+import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
-import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
 import org.chromium.ui.modelutil.PropertyModel;
 
+import java.util.List;
+
 /**
  * A coordinator for TabStripBottomToolbar component. Manages the communication with
  * {@link TabListCoordinator}, {@link BottomTabGridCoordinator}, and
@@ -61,22 +63,22 @@
      * Handles a reset event originated from {@link TabStripBottomToolbarMediator}
      * when the bottom sheet is collapsed.
      *
-     * @param tabModel current {@link TabModel} instance.
+     * @param tabs List of Tabs to reset.
      */
     @Override
-    public void resetStripWithTabModel(TabModel tabModel) {
-        mTabStripCoordinator.resetWithTabModel(tabModel);
+    public void resetStripWithListOfTabs(List<Tab> tabs) {
+        mTabStripCoordinator.resetWithListOfTabs(tabs);
     }
 
     /**
      * Handles a reset event originated from {@link TabStripBottomToolbarMediator}
      * when the bottom sheet is expanded.
      *
-     * @param tabModel current {@link TabModel} instance.
+     * @param tabs List of Tabs to reset.
      */
     @Override
-    public void resetSheetWithTabModel(TabModel tabModel) {
-        mBottomTabGridCoordinator.resetWithTabModel(tabModel);
+    public void resetSheetWithListOfTabs(List<Tab> tabs) {
+        mBottomTabGridCoordinator.resetWithListOfTabs(tabs);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripBottomToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripBottomToolbarMediator.java
index 5925ad2..79602bd1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripBottomToolbarMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripBottomToolbarMediator.java
@@ -7,16 +7,17 @@
 import org.chromium.chrome.browser.UrlConstants;
 import org.chromium.chrome.browser.lifecycle.Destroyable;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
 import org.chromium.chrome.browser.tabmodel.TabLaunchType;
-import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
-import org.chromium.chrome.browser.tabmodel.TabModelUtils;
 import org.chromium.chrome.browser.tabmodel.TabSelectionType;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.ui.modelutil.PropertyModel;
 
+import java.util.List;
+
 /**
  * A mediator for the TabStripBottomToolbar. Responsible for managing the
  * internal state of the component.
@@ -31,21 +32,21 @@
          * Handles a reset event originated from {@link TabStripBottomToolbarMediator}
          * when the bottom sheet is collapsed.
          *
-         * @param tabModel current {@link TabModel} instance.
+         * @param tabs List of Tabs to reset.
          */
-        void resetStripWithTabModel(TabModel tabModel);
+        void resetStripWithListOfTabs(List<Tab> tabs);
 
         /**
          * Handles a reset event originated from {@link TabStripBottomToolbarMediator}
          * when the bottom sheet is expanded.
          *
-         * @param tabModel current {@link TabModel} instance.
+         * @param tabs List of Tabs to reset.
          */
-        void resetSheetWithTabModel(TabModel tabModel);
+        void resetSheetWithListOfTabs(List<Tab> tabs);
     }
 
     private final PropertyModel mToolbarPropertyModel;
-    private final TabModelSelectorTabModelObserver mTabModelObserver;
+    private final TabModelObserver mTabModelObserver;
     private final ResetHandler mResetHandler;
     private final TabModelSelector mTabModelSelector;
     private final TabCreatorManager mTabCreatorManager;
@@ -58,24 +59,26 @@
         mTabCreatorManager = tabCreatorManager;
 
         // register for tab model
-        mTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) {
+        mTabModelObserver = new EmptyTabModelObserver() {
             @Override
             public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) {
-                if (TabModelUtils.getTabById(tabModelSelector.getCurrentModel(), lastId) != null)
-                    return;
-
-                mResetHandler.resetStripWithTabModel(tabModelSelector.getCurrentModel());
+                if (getRelatedTabsForId(lastId).contains(tab)) return;
+                mResetHandler.resetStripWithListOfTabs(getRelatedTabsForId(tab.getId()));
             }
         };
 
+        mTabModelSelector.getTabModelFilterProvider().addTabModelFilterObserver(mTabModelObserver);
         setupToolbarClickHandlers();
         mToolbarPropertyModel.set(TabStripToolbarViewProperties.IS_MAIN_CONTENT_VISIBLE, true);
-        mResetHandler.resetStripWithTabModel(tabModelSelector.getCurrentModel());
+        mResetHandler.resetStripWithListOfTabs(
+                getRelatedTabsForId(tabModelSelector.getCurrentTab().getId()));
     }
 
     private void setupToolbarClickHandlers() {
         mToolbarPropertyModel.set(TabStripToolbarViewProperties.EXPAND_CLICK_LISTENER, view -> {
-            mResetHandler.resetSheetWithTabModel(mTabModelSelector.getCurrentModel());
+            Tab currentTab = mTabModelSelector.getCurrentTab();
+            if (currentTab == null) return;
+            mResetHandler.resetSheetWithListOfTabs(getRelatedTabsForId(currentTab.getId()));
         });
         mToolbarPropertyModel.set(TabStripToolbarViewProperties.ADD_CLICK_LISTENER, view -> {
             Tab currentTab = mTabModelSelector.getCurrentTab();
@@ -85,8 +88,17 @@
         });
     }
 
+    private List<Tab> getRelatedTabsForId(int id) {
+        return mTabModelSelector.getTabModelFilterProvider()
+                .getCurrentTabModelFilter()
+                .getRelatedTabList(id);
+    }
+
     @Override
     public void destroy() {
-        mTabModelObserver.destroy();
+        if (mTabModelObserver != null && mTabModelSelector != null) {
+            mTabModelSelector.getTabModelFilterProvider().removeTabModelFilterObserver(
+                    mTabModelObserver);
+        }
     }
 }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 5207b6a..231f24b 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1558,6 +1558,7 @@
   "java/src/org/chromium/chrome/browser/tabmodel/document/StorageDelegate.java",
   "java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java",
   "java/src/org/chromium/chrome/browser/tasks/TasksUma.java",
+  "java/src/org/chromium/chrome/browser/tasks/tabgroup/TabGroupModelFilter.java",
   "java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java",
   "java/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabStripToolbarViewProperties.java",
   "java/src/org/chromium/chrome/browser/tasks/tab_list_ui/BottomTabListToolbarView.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
index bc7e60b6..db1c944 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java
@@ -144,6 +144,7 @@
         features.put(ChromeFeatureList.DOWNLOADS_LOCATION_CHANGE, false);
         features.put(ChromeFeatureList.DOWNLOAD_HOME_SHOW_STORAGE_INFO, false);
         features.put(ChromeFeatureList.DOWNLOAD_HOME_V2, false);
+        features.put(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY, false);
         features.put(ChromeFeatureList.OVERSCROLL_HISTORY_NAVIGATION, false);
         features.put(ChromeFeatureList.DOWNLOAD_OFFLINE_CONTENT_PROVIDER, false);
         ChromeFeatureList.setTestFeatures(features);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListMediatorUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListMediatorUnitTest.java
index eabd91c..bdb7c69 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListMediatorUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/tab_list_ui/TabListMediatorUnitTest.java
@@ -43,6 +43,7 @@
 import org.chromium.chrome.browser.tab.TabObserver;
 import org.chromium.chrome.browser.tabmodel.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider;
 import org.chromium.chrome.browser.tabmodel.TabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
 import org.chromium.testing.local.LocalRobolectricTestRunner;
@@ -70,6 +71,8 @@
     @Mock
     TabModelSelectorImpl mTabModelSelector;
     @Mock
+    TabModelFilterProvider mTabModelFilterProvider;
+    @Mock
     TabModel mTabModel;
     @Mock
     Context mContext;
@@ -113,7 +116,11 @@
                         any(), any(), anyInt(), mFaviconCallbackCaptor.capture());
         doReturn(mTabModel).when(mTabModelSelector).getCurrentModel();
         doReturn(tabModelList).when(mTabModelSelector).getModels();
-        doNothing().when(mTabModel).addObserver(mTabModelObserverCaptor.capture());
+        doReturn(mTabModelFilterProvider).when(mTabModelSelector).getTabModelFilterProvider();
+        doReturn(mTab1).when(mTabModelSelector).getCurrentTab();
+        doNothing()
+                .when(mTabModelFilterProvider)
+                .addTabModelFilterObserver(mTabModelObserverCaptor.capture());
         doReturn(mTab1).when(mTabModel).getTabAt(0);
         doReturn(mTab2).when(mTabModel).getTabAt(1);
         doNothing().when(mTab1).addObserver(mTabObserverCaptor.capture());
@@ -245,7 +252,11 @@
     }
 
     private void initAndAssertAllProperties() {
-        mMediator.resetWithTabModel(mTabModel);
+        List<Tab> tabs = new ArrayList<>();
+        for (int i = 0; i < mTabModel.getCount(); i++) {
+            tabs.add(mTabModel.getTabAt(i));
+        }
+        mMediator.resetWithListOfTabs(tabs);
         for (FaviconHelper.FaviconImageCallback callback : mFaviconCallbackCaptor.getAllValues()) {
             callback.onFaviconAvailable(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888), null);
         }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ef530460..edc54fd 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -8035,9 +8035,6 @@
         <message name="IDS_PLEASE_RELAUNCH_BROWSER" desc="Title of the alert when Chrome needs to be relaunched for a change/update to take effect.">
           Please Relaunch <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>
         </message>
-        <message name="IDS_SAVE_PAGE_FILE_FORMAT_PROMPT_MAC" desc="The title of the File Format label for saving a page.">
-          Format:
-        </message>
 
         <!-- Install from disk image -->
         <message name="IDS_INSTALL_FROM_DMG_TITLE" desc="Title of the dialog asking whether to install from the disk image.  Mac-only.">
diff --git a/chrome/app/nibs/BUILD.gn b/chrome/app/nibs/BUILD.gn
index 84880c6..87629b2 100644
--- a/chrome/app/nibs/BUILD.gn
+++ b/chrome/app/nibs/BUILD.gn
@@ -7,10 +7,7 @@
 
 assert(is_mac)
 
-translated_xibs = [
-  "SaveAccessoryView.xib",
-  "TaskManager.xib",
-]
+translated_xibs = [ "TaskManager.xib" ]
 
 mac_xib_bundle_data("chrome_xibs") {
   sources = translated_xibs
diff --git a/chrome/app/nibs/SaveAccessoryView.xib b/chrome/app/nibs/SaveAccessoryView.xib
deleted file mode 100644
index f7c28e39..0000000
--- a/chrome/app/nibs/SaveAccessoryView.xib
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13F1077" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
-    <dependencies>
-        <deployment version="1090" identifier="macosx"/>
-        <development version="5100" identifier="xcode"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner"/>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application"/>
-        <customView id="1">
-            <rect key="frame" x="0.0" y="0.0" width="352" height="57"/>
-            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
-            <subviews>
-                <customView id="10" customClass="GTMWidthBasedTweaker">
-                    <rect key="frame" x="0.0" y="0.0" width="99" height="57"/>
-                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-                    <subviews>
-                        <textField verticalHuggingPriority="750" id="2">
-                            <rect key="frame" x="17" y="20" width="79" height="17"/>
-                            <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
-                            <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="^IDS_SAVE_PAGE_FILE_FORMAT_PROMPT_MAC" id="3">
-                                <font key="font" metaFont="system"/>
-                                <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
-                                <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
-                            </textFieldCell>
-                        </textField>
-                    </subviews>
-                    <connections>
-                        <outlet property="viewToResize_" destination="1" id="13"/>
-                        <outlet property="viewToSlide_" destination="4" id="12"/>
-                    </connections>
-                </customView>
-                <popUpButton verticalHuggingPriority="750" tag="1234" id="4">
-                    <rect key="frame" x="98" y="13" width="237" height="26"/>
-                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
-                    <popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="5">
-                        <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
-                        <font key="font" metaFont="system"/>
-                        <menu key="menu" title="OtherViews" id="6"/>
-                    </popUpButtonCell>
-                </popUpButton>
-            </subviews>
-        </customView>
-        <customObject id="14" customClass="ChromeUILocalizer"/>
-        <customObject id="15" customClass="GTMUILocalizerAndLayoutTweaker">
-            <connections>
-                <outlet property="localizer_" destination="14" id="16"/>
-                <outlet property="uiObject_" destination="1" id="17"/>
-            </connections>
-        </customObject>
-    </objects>
-</document>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 880d2fdc..5df8deb 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1123,6 +1123,8 @@
     "performance_monitor/process_monitor.h",
     "performance_monitor/system_monitor.cc",
     "performance_monitor/system_monitor.h",
+    "performance_monitor/system_monitor_metrics_logger.cc",
+    "performance_monitor/system_monitor_metrics_logger.h",
     "permissions/chooser_context_base.cc",
     "permissions/chooser_context_base.h",
     "permissions/permission_context_base.cc",
@@ -2945,6 +2947,8 @@
       "media_galleries/win/portable_device_map_service.h",
       "media_galleries/win/snapshot_file_details.cc",
       "media_galleries/win/snapshot_file_details.h",
+      "memory/memory_pressure_monitor_utils.h",
+      "memory/memory_pressure_monitor_utils_impl.h",
       "memory/oom_memory_details.cc",
       "memory/oom_memory_details.h",
       "memory/swap_thrashing_monitor.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 1c354ac..3b36f7e5 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -99,6 +99,7 @@
 #include "components/unified_consent/feature.h"
 #include "components/version_info/version_info.h"
 #include "components/viz/common/features.h"
+#include "components/viz/common/switches.h"
 #include "content/public/common/buildflags.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
index a9685ea..c9eeadc9 100644
--- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc
+++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -121,6 +121,7 @@
     // The UI was created for an existing Controller.
     OnStatusMessageChanged(ui_delegate->GetStatusMessage());
     OnProgressChanged(ui_delegate->GetProgress());
+    OnProgressVisibilityChanged(ui_delegate->GetProgressVisible());
     OnDetailsChanged(ui_delegate->GetDetails());
     OnSuggestionsChanged(ui_delegate->GetSuggestions());
     UpdateActions();
@@ -230,6 +231,11 @@
                                         progress);
 }
 
+void UiControllerAndroid::OnProgressVisibilityChanged(bool visible) {
+  Java_AssistantHeaderModel_setProgressVisible(AttachCurrentThread(),
+                                               GetHeaderModel(), visible);
+}
+
 void UiControllerAndroid::AllowShowingSoftKeyboard(bool enabled) {
   Java_AssistantModel_setAllowSoftKeyboard(AttachCurrentThread(), GetModel(),
                                            enabled);
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h
index 5b60599..4a098de9 100644
--- a/chrome/browser/android/autofill_assistant/ui_controller_android.h
+++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h
@@ -64,6 +64,7 @@
   void OnPaymentRequestChanged(const PaymentRequestOptions* options) override;
   void OnDetailsChanged(const Details* details) override;
   void OnProgressChanged(int progress) override;
+  void OnProgressVisibilityChanged(bool visible) override;
   void OnTouchableAreaChanged(const std::vector<RectF>& areas) override;
 
   // Called by AssistantOverlayDelegate:
diff --git a/chrome/browser/android/signin/signin_manager_android.cc b/chrome/browser/android/signin/signin_manager_android.cc
index a2b68e3..dcca4a7 100644
--- a/chrome/browser/android/signin/signin_manager_android.cc
+++ b/chrome/browser/android/signin/signin_manager_android.cc
@@ -25,7 +25,6 @@
 #include "chrome/browser/policy/cloud/user_policy_signin_service_mobile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/common/pref_names.h"
 #include "components/google/core/common/google_util.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
@@ -206,8 +205,10 @@
 
   // TODO(crbug.com/889902): Migrate to IdentityManager once there's an
   // API mapping for SigninManager::OnExternalSigninCompleted().
-  SigninManagerFactory::GetForProfile(profile_)->OnExternalSigninCompleted(
-      base::android::ConvertJavaStringToUTF8(env, username));
+  SigninManager::FromSigninManagerBase(
+      IdentityManagerFactory::GetForProfile(profile_)->GetSigninManager())
+      ->OnExternalSigninCompleted(
+          base::android::ConvertJavaStringToUTF8(env, username));
 }
 
 void SigninManagerAndroid::SignOut(JNIEnv* env,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 4a65579..17bc2cf 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -5066,7 +5066,9 @@
     ui::PageTransition page_transition,
     bool has_user_gesture,
     const std::string& method,
-    const net::HttpRequestHeaders& headers) {
+    const net::HttpRequestHeaders& headers,
+    network::mojom::URLLoaderFactoryRequest* factory_request,
+    network::mojom::URLLoaderFactory*& out_factory) {
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   // External protocols are disabled for guests. An exception is made for the
   // "mailto" protocol, so that pages that utilize it work properly in a
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 2ccae9b..c8966ee 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -530,7 +530,9 @@
       ui::PageTransition page_transition,
       bool has_user_gesture,
       const std::string& method,
-      const net::HttpRequestHeaders& headers) override;
+      const net::HttpRequestHeaders& headers,
+      network::mojom::URLLoaderFactoryRequest* factory_request,
+      network::mojom::URLLoaderFactory*& out_factory) override;
   std::unique_ptr<content::OverlayWindow> CreateWindowForPictureInPicture(
       content::PictureInPictureWindowController* controller) override;
   bool IsSafeRedirectTarget(const GURL& url,
diff --git a/chrome/browser/chromeos/arc/arc_support_host_unittest.cc b/chrome/browser/chromeos/arc/arc_support_host_unittest.cc
index 1fc6df5..2f14ac6 100644
--- a/chrome/browser/chromeos/arc/arc_support_host_unittest.cc
+++ b/chrome/browser/chromeos/arc/arc_support_host_unittest.cc
@@ -18,6 +18,7 @@
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "services/identity/public/cpp/identity_manager.h"
+#include "services/identity/public/cpp/identity_test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -74,9 +75,9 @@
     BrowserWithTestWindowTest::SetUp();
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         std::make_unique<chromeos::FakeChromeUserManager>());
-    IdentityManagerFactory::GetForProfile(profile())
-        ->SetPrimaryAccountSynchronously("gaia_id", "testing@account.com",
-                                         /*refresh_token=*/std::string());
+    identity::MakePrimaryAccountAvailable(
+        IdentityManagerFactory::GetForProfile(profile()),
+        "testing@account.com");
 
     support_host_ = std::make_unique<ArcSupportHost>(profile());
     fake_arc_support_ = std::make_unique<FakeArcSupport>(support_host_.get());
diff --git a/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc b/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc
index 2957982..ce2583e 100644
--- a/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc
+++ b/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc
@@ -31,6 +31,7 @@
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "services/identity/public/cpp/identity_manager.h"
+#include "services/identity/public/cpp/identity_test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -62,9 +63,9 @@
     BrowserWithTestWindowTest::SetUp();
     user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
         std::make_unique<chromeos::FakeChromeUserManager>());
-    IdentityManagerFactory::GetForProfile(profile())
-        ->SetPrimaryAccountSynchronously("gaia_id", "testing@account.com",
-                                         /*refresh_token=*/std::string());
+    identity::MakePrimaryAccountAvailable(
+        IdentityManagerFactory::GetForProfile(profile()),
+        "testing@account.com");
 
     chromeos::StatsReportingController::RegisterLocalStatePrefs(
         local_state_.registry());
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index b6e836d..b954a67 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -38,6 +38,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/tracing/common/tracing_switches.h"
 #include "components/user_manager/user_names.h"
+#include "components/viz/common/switches.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_switches.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
@@ -47,7 +48,6 @@
 #include "services/service_manager/sandbox/switches.h"
 #include "third_party/cros_system_api/switches/chrome_switches.h"
 #include "ui/base/ui_base_switches.h"
-#include "ui/compositor/compositor_switches.h"
 #include "ui/display/display_switches.h"
 #include "ui/events/event_switches.h"
 #include "ui/gl/gl_switches.h"
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc
new file mode 100644
index 0000000..5fbf0588
--- /dev/null
+++ b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc
@@ -0,0 +1,189 @@
+// 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 "base/bind.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h"
+#include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h"
+#include "chrome/browser/chromeos/login/startup_utils.h"
+#include "chrome/browser/chromeos/login/test/fake_gaia_mixin.h"
+#include "chrome/browser/chromeos/login/test/js_checker.h"
+#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h"
+#include "chrome/browser/chromeos/login/test/oobe_base_test.h"
+#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
+#include "chrome/browser/chromeos/login/test/test_condition_waiter.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/chromeos/login/wizard_controller.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/policy/test/local_policy_test_server.h"
+#include "chromeos/constants/chromeos_switches.h"
+#include "components/policy/core/common/policy_switches.h"
+
+namespace chromeos {
+
+namespace {
+
+constexpr char kTestDomain[] = "test-domain.com";
+
+void OnScreenExit(base::OnceClosure closure,
+                  EnrollmentScreen::Result expected,
+                  EnrollmentScreen::Result actual) {
+  EXPECT_EQ(expected, actual);
+  std::move(closure).Run();
+}
+
+EnrollmentScreen::ScreenExitCallback UserCannotSkipCallback(
+    base::OnceClosure closure) {
+  return base::AdaptCallbackForRepeating(base::BindOnce(
+      OnScreenExit, std::move(closure), EnrollmentScreen::Result::BACK));
+}
+
+}  // namespace
+
+class EnrollmentLocalPolicyServerBase : public OobeBaseTest {
+ public:
+  EnrollmentLocalPolicyServerBase() = default;
+
+  void SetUpOnMainThread() override {
+    fake_gaia_.SetupFakeGaiaForLogin(FakeGaiaMixin::kFakeUserEmail,
+                                     FakeGaiaMixin::kFakeUserGaiaId,
+                                     FakeGaiaMixin::kFakeRefreshToken);
+    OobeBaseTest::SetUpOnMainThread();
+  }
+
+ protected:
+  LoginDisplayHost* host() {
+    LoginDisplayHost* host = LoginDisplayHost::default_host();
+    EXPECT_NE(host, nullptr);
+    return host;
+  }
+
+  EnrollmentScreen* enrollment_screen() {
+    EXPECT_NE(WizardController::default_controller(), nullptr);
+    EnrollmentScreen* enrollment_screen = EnrollmentScreen::Get(
+        WizardController::default_controller()->screen_manager());
+    EXPECT_NE(enrollment_screen, nullptr);
+    return enrollment_screen;
+  }
+
+  AutoEnrollmentCheckScreen* auto_enrollment_screen() {
+    EXPECT_NE(WizardController::default_controller(), nullptr);
+    AutoEnrollmentCheckScreen* auto_enrollment_screen =
+        AutoEnrollmentCheckScreen::Get(
+            WizardController::default_controller()->screen_manager());
+    EXPECT_NE(auto_enrollment_screen, nullptr);
+    return auto_enrollment_screen;
+  }
+
+  LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
+  FakeGaiaMixin fake_gaia_{&mixin_host_, embedded_test_server()};
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(EnrollmentLocalPolicyServerBase);
+};
+
+class AutoEnrollmentLocalPolicyServer : public EnrollmentLocalPolicyServerBase {
+ public:
+  AutoEnrollmentLocalPolicyServer() = default;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    EnrollmentLocalPolicyServerBase::SetUpCommandLine(command_line);
+
+    command_line->AppendSwitchASCII(
+        switches::kEnterpriseEnableForcedReEnrollment,
+        AutoEnrollmentController::kForcedReEnrollmentAlways);
+    command_line->AppendSwitchASCII(
+        switches::kEnterpriseEnrollmentInitialModulus, "5");
+    command_line->AppendSwitchASCII(switches::kEnterpriseEnrollmentModulusLimit,
+                                    "5");
+  }
+
+  policy::ServerBackedStateKeysBroker* state_keys_broker() {
+    return g_browser_process->platform_part()
+        ->browser_policy_connector_chromeos()
+        ->GetStateKeysBroker();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentLocalPolicyServer);
+};
+
+// Simple manual enrollment.
+IN_PROC_BROWSER_TEST_F(EnrollmentLocalPolicyServerBase, ManualEnrollment) {
+  host()->StartWizard(OobeScreen::SCREEN_OOBE_ENROLLMENT);
+  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait();
+
+  ASSERT_FALSE(StartupUtils::IsDeviceRegistered());
+  enrollment_screen()->OnLoginDone(FakeGaiaMixin::kFakeUserEmail,
+                                   FakeGaiaMixin::kFakeAuthCode);
+
+  test::OobeJS()
+      .CreateWaiter(
+          "document.getElementsByClassName('oauth-enroll-state-attribute-"
+          "prompt').length > 0")
+      ->Wait();
+  // TODO(rsorokin): Interact with attribute prompt step.
+  EXPECT_TRUE(StartupUtils::IsDeviceRegistered());
+}
+
+// No state keys on the server. Auto enrollment check should proceed to login.
+IN_PROC_BROWSER_TEST_F(AutoEnrollmentLocalPolicyServer, AutoEnrollmentCheck) {
+  host()->StartWizard(OobeScreen::SCREEN_AUTO_ENROLLMENT_CHECK);
+  OobeScreenWaiter(OobeScreen::SCREEN_GAIA_SIGNIN).Wait();
+}
+
+// State keys are present but restore mode is not requested.
+IN_PROC_BROWSER_TEST_F(AutoEnrollmentLocalPolicyServer, ReenrollmentNone) {
+  EXPECT_TRUE(local_policy_mixin_.SetDeviceStateRetrievalResponse(
+      state_keys_broker(),
+      enterprise_management::DeviceStateRetrievalResponse::RESTORE_MODE_NONE,
+      kTestDomain));
+  host()->StartWizard(OobeScreen::SCREEN_AUTO_ENROLLMENT_CHECK);
+  OobeScreenWaiter(OobeScreen::SCREEN_GAIA_SIGNIN).Wait();
+}
+
+// Reenrollment requested. User can skip.
+IN_PROC_BROWSER_TEST_F(AutoEnrollmentLocalPolicyServer, ReenrollmentRequested) {
+  EXPECT_TRUE(local_policy_mixin_.SetDeviceStateRetrievalResponse(
+      state_keys_broker(),
+      enterprise_management::DeviceStateRetrievalResponse::
+          RESTORE_MODE_REENROLLMENT_REQUESTED,
+      kTestDomain));
+  host()->StartWizard(OobeScreen::SCREEN_AUTO_ENROLLMENT_CHECK);
+  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait();
+  enrollment_screen()->OnCancel();
+  OobeScreenWaiter(OobeScreen::SCREEN_GAIA_SIGNIN).Wait();
+}
+
+// Reenrollment forced. User can not skip.
+IN_PROC_BROWSER_TEST_F(AutoEnrollmentLocalPolicyServer, ReenrollmentForced) {
+  EXPECT_TRUE(local_policy_mixin_.SetDeviceStateRetrievalResponse(
+      state_keys_broker(),
+      enterprise_management::DeviceStateRetrievalResponse::
+          RESTORE_MODE_REENROLLMENT_ENFORCED,
+      kTestDomain));
+  host()->StartWizard(OobeScreen::SCREEN_AUTO_ENROLLMENT_CHECK);
+  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait();
+  base::RunLoop loop;
+  enrollment_screen()->set_exit_callback_for_testing(
+      UserCannotSkipCallback(loop.QuitClosure()));
+  enrollment_screen()->OnCancel();
+  loop.Run();
+}
+
+// Device is disabled.
+IN_PROC_BROWSER_TEST_F(AutoEnrollmentLocalPolicyServer, DeviceDisabled) {
+  EXPECT_TRUE(local_policy_mixin_.SetDeviceStateRetrievalResponse(
+      state_keys_broker(),
+      enterprise_management::DeviceStateRetrievalResponse::
+          RESTORE_MODE_DISABLED,
+      kTestDomain));
+  host()->StartWizard(OobeScreen::SCREEN_AUTO_ENROLLMENT_CHECK);
+  OobeScreenWaiter(OobeScreen::SCREEN_DEVICE_DISABLED).Wait();
+}
+
+// TODO(rsorokin): Add test for RESTORE_MODE_REENROLLMENT_ZERO_TOUCH.
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index ff4c845..370fb71 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -14,7 +14,6 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -88,7 +87,6 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_observer.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
@@ -354,7 +352,7 @@
         embedded_test_server()->base_url().Resolve("/SAML"));
     fake_gaia_.fake_gaia()->RegisterSamlUser(kDifferentDomainSAMLUserEmail,
                                              saml_idp_url);
-    fake_gaia_.fake_gaia()->RegisterSamlDomainRedirectUrl("corp.example.com",
+    fake_gaia_.fake_gaia()->RegisterSamlDomainRedirectUrl("example.com",
                                                           saml_idp_url);
   }
 
@@ -607,7 +605,12 @@
 // Tests the multiple password scraped flow.
 //
 // Disabled due to flakiness: crbug.com/834703
-IN_PROC_BROWSER_TEST_F(SamlTest, DISABLED_ScrapedMultiple) {
+#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)
+#define MAYBE_ScrapedMultiple DISABLED_ScrapedMultiple
+#else
+#define MAYBE_ScrapedMultiple ScrapedMultiple
+#endif
+IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_ScrapedMultiple) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login_two_passwords.html");
 
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
@@ -848,8 +851,7 @@
             WaitForAndGetFatalErrorMessage());
 }
 
-class SAMLEnrollmentTest : public SamlTest,
-                           public content::WebContentsObserver {
+class SAMLEnrollmentTest : public SamlTest {
  public:
   SAMLEnrollmentTest();
   ~SAMLEnrollmentTest() override;
@@ -858,19 +860,11 @@
   void SetUpOnMainThread() override;
   void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) override;
 
-  // content::WebContentsObserver:
-  void DidFinishLoad(content::RenderFrameHost* render_frame_host,
-                     const GURL& validated_url) override;
-
-  void WaitForEnrollmentSuccess();
   guest_view::TestGuestViewManager* GetGuestViewManager();
   content::WebContents* GetEnrollmentContents();
 
  private:
   LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_};
-  base::ScopedTempDir temp_dir_;
-
-  std::unique_ptr<base::RunLoop> run_loop_;
 
   guest_view::TestGuestViewManagerFactory guest_view_manager_factory_;
 
@@ -881,6 +875,7 @@
   guest_view::GuestViewManager::set_factory_for_testing(
       &guest_view_manager_factory_);
   gaia_frame_parent_ = "oauth-enroll-auth-view";
+  authenticator_id_ = "$('oauth-enrollment').authenticator_";
 }
 
 SAMLEnrollmentTest::~SAMLEnrollmentTest() {}
@@ -900,63 +895,16 @@
 void SAMLEnrollmentTest::StartSamlAndWaitForIdpPageLoad(
     const std::string& gaia_email) {
   WaitForSigninScreen();
-  run_loop_.reset(new base::RunLoop);
   ExistingUserController::current_controller()->OnStartEnterpriseEnrollment();
   while (!GetEnrollmentContents()) {
     GetGuestViewManager()->WaitForNextGuestCreated();
   }
-  Observe(GetEnrollmentContents());
-  run_loop_->Run();
-
+  // Wait for Gaia is ready.
+  OobeBaseTest::WaitForGaiaPageEvent("backButton");
   SetSignFormField("identifier", gaia_email);
 
-  run_loop_.reset(new base::RunLoop);
   ExecuteJsInSigninFrame("document.getElementById('nextButton').click();");
-  run_loop_->Run();
-}
-
-void SAMLEnrollmentTest::DidFinishLoad(
-    content::RenderFrameHost* render_frame_host,
-    const GURL& validated_url) {
-  const GURL origin = validated_url.GetOrigin();
-  if (origin !=
-          fake_gaia_.gaia_https_forwarder()->GetURLForSSLHost(std::string()) &&
-      origin != saml_https_forwarder_.GetURLForSSLHost(std::string())) {
-    return;
-  }
-
-  // The GAIA or SAML IdP login form finished loading.
-  if (run_loop_)
-    run_loop_->Quit();
-}
-
-// Waits until the class |oauth-enroll-state-success| becomes set for the
-// enrollment screen, indicating enrollment success.
-void SAMLEnrollmentTest::WaitForEnrollmentSuccess() {
-  bool done = false;
-  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-      GetLoginUI()->GetWebContents(),
-      "var enrollmentScreen = document.getElementById('oauth-enrollment');"
-      "function SendReplyIfEnrollmentDone() {"
-      "  if (enrollmentScreen.classList.contains("
-      "          'oauth-enroll-state-attribute-prompt')) {"
-      "    $('oauth-enroll-attribute-prompt-card').fire('submit');"
-      "    return false;"
-      "  }"
-      "  if (!enrollmentScreen.classList.contains("
-      "           'oauth-enroll-state-success')) {"
-      "    return false;"
-      "  }"
-      "  domAutomationController.send(true);"
-      "  observer.disconnect();"
-      "  return true;"
-      "}"
-      "var observer = new MutationObserver(SendReplyIfEnrollmentDone);"
-      "if (!SendReplyIfEnrollmentDone()) {"
-      "  var options = { attributes: true, attributeFilter: [ 'class' ] };"
-      "  observer.observe(enrollmentScreen, options);"
-      "}",
-      &done));
+  OobeBaseTest::WaitForGaiaPageEvent("authFlowChange");
 }
 
 guest_view::TestGuestViewManager* SAMLEnrollmentTest::GetGuestViewManager() {
@@ -975,7 +923,7 @@
 }
 
 // Flaky. See crbug.com/766953.
-#if defined(ADDRESS_SANITIZER) || defined(OS_CHROMEOS)
+#if defined(ADDRESS_SANITIZER)
 #define MAYBE_WithoutCredentialsPassingAPI DISABLED_WithoutCredentialsPassingAPI
 #else
 #define MAYBE_WithoutCredentialsPassingAPI WithoutCredentialsPassingAPI
@@ -989,16 +937,16 @@
   SetSignFormField("Password", "fake_password");
   ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
 
-  WaitForEnrollmentSuccess();
+  OobeBaseTest::WaitForEnrollmentSuccess();
 }
 
 // Flaky. See crbug.com/766953.
-#if defined(ADDRESS_SANITIZER) || defined(OS_CHROMEOS)
+#if defined(ADDRESS_SANITIZER)
 #define MAYBE_WithCredentialsPassingAPI DISABLED_WithCredentialsPassingAPI
 #else
 #define MAYBE_WithCredentialsPassingAPI WithCredentialsPassingAPI
 #endif
-IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest, MAYBE_WithCredentialsPassingAPI) {
+IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest, WithCredentialsPassingAPI) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
   fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
@@ -1008,7 +956,7 @@
   SetSignFormField("Password", "fake_password");
   ExecuteJsInSigninFrame("document.getElementById('Submit').click();");
 
-  WaitForEnrollmentSuccess();
+  OobeBaseTest::WaitForEnrollmentSuccess();
 }
 
 class SAMLPolicyTest : public SamlTest {
@@ -1471,8 +1419,7 @@
 // Tests that clicking "Next" in the SAML interstitial page successfully
 // triggers a SAML redirect request, and the SAML IdP authentication page is
 // loaded and authenticaing there is successful.
-// Disabled due to flakiness, see crbug.com/699228
-IN_PROC_BROWSER_TEST_F(SAMLPolicyTest, DISABLED_SAMLInterstitialNext) {
+IN_PROC_BROWSER_TEST_F(SAMLPolicyTest, SAMLInterstitialNext) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
   fake_gaia_.fake_gaia()->SetFakeMergeSessionParams(
       kFirstSAMLUserEmail, kTestAuthSIDCookie1, kTestAuthLSIDCookie1);
diff --git a/chrome/browser/chromeos/login/test/fake_gaia_mixin.cc b/chrome/browser/chromeos/login/test/fake_gaia_mixin.cc
index c38dc0c..6025db7 100644
--- a/chrome/browser/chromeos/login/test/fake_gaia_mixin.cc
+++ b/chrome/browser/chromeos/login/test/fake_gaia_mixin.cc
@@ -22,6 +22,8 @@
 const char FakeGaiaMixin::kFakeUserEmail[] = "fake-email@gmail.com";
 const char FakeGaiaMixin::kFakeUserPassword[] = "fake-password";
 const char FakeGaiaMixin::kFakeUserGaiaId[] = "fake-gaiaId";
+const char FakeGaiaMixin::kFakeAuthCode[] = "fake-auth-code";
+const char FakeGaiaMixin::kFakeRefreshToken[] = "fake-refresh-token";
 const char FakeGaiaMixin::kEmptyUserServices[] = "[]";
 
 const char FakeGaiaMixin::kFakeSIDCookie[] = "fake-SID-cookie";
diff --git a/chrome/browser/chromeos/login/test/fake_gaia_mixin.h b/chrome/browser/chromeos/login/test/fake_gaia_mixin.h
index 3092eddb..7ada5c7 100644
--- a/chrome/browser/chromeos/login/test/fake_gaia_mixin.h
+++ b/chrome/browser/chromeos/login/test/fake_gaia_mixin.h
@@ -25,6 +25,8 @@
   static const char kFakeUserEmail[];
   static const char kFakeUserPassword[];
   static const char kFakeUserGaiaId[];
+  static const char kFakeAuthCode[];
+  static const char kFakeRefreshToken[];
   static const char kEmptyUserServices[];
 
   // FakeGaia is configured to return these cookies for kFakeUserEmail.
diff --git a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc
index 87c1290..1adf162 100644
--- a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc
+++ b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/guid.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/policy/core/common/cloud/policy_builder.h"
 #include "components/policy/core/common/policy_switches.h"
@@ -61,6 +62,36 @@
       std::string() /* entity_id */, policy.SerializeAsString());
 }
 
+bool LocalPolicyTestServerMixin::SetDeviceStateRetrievalResponse(
+    policy::ServerBackedStateKeysBroker* keys_broker,
+    enterprise_management::DeviceStateRetrievalResponse::RestoreMode
+        restore_mode,
+    const std::string& managemement_domain) {
+  std::vector<std::string> keys;
+  base::RunLoop loop;
+  keys_broker->RequestStateKeys(base::BindOnce(
+      [](std::vector<std::string>* keys, base::OnceClosure quit,
+         const std::vector<std::string>& state_keys) {
+        *keys = state_keys;
+        std::move(quit).Run();
+      },
+      &keys, loop.QuitClosure()));
+  loop.Run();
+  if (keys.empty())
+    return false;
+  if (!policy_test_server_->RegisterClient("dm_token", base::GenerateGUID(),
+                                           keys)) {
+    return false;
+  }
+
+  base::Value device_state(base::Value::Type::DICTIONARY);
+  device_state.SetKey("management_domain", base::Value(managemement_domain));
+  device_state.SetKey("restore_mode",
+                      base::Value(static_cast<int>(restore_mode)));
+  server_config_.SetKey("device_state", std::move(device_state));
+  return policy_test_server_->SetConfig(server_config_);
+}
+
 LocalPolicyTestServerMixin::~LocalPolicyTestServerMixin() = default;
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h
index d5085ea..cc65c82c 100644
--- a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h
+++ b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h
@@ -10,8 +10,10 @@
 #include "base/macros.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/login/mixin_based_in_process_browser_test.h"
+#include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
 #include "chrome/browser/policy/test/local_policy_test_server.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
+#include "components/policy/proto/device_management_backend.pb.h"
 
 namespace chromeos {
 
@@ -32,6 +34,15 @@
   bool UpdateDevicePolicy(
       const enterprise_management::ChromeDeviceSettingsProto& policy);
 
+  // Set response for DeviceStateRetrievalRequest. Returns that if finds state
+  // key passed in the request. State keys could be set by RegisterClient call
+  // on policy test server.
+  bool SetDeviceStateRetrievalResponse(
+      policy::ServerBackedStateKeysBroker* keys_broker,
+      enterprise_management::DeviceStateRetrievalResponse::RestoreMode
+          restore_mode,
+      const std::string& managemement_domain);
+
  private:
   std::unique_ptr<policy::LocalPolicyTestServer> policy_test_server_;
   base::Value server_config_;
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc
index 5f435b8..65d8f87 100644
--- a/chrome/browser/chromeos/login/test/oobe_base_test.cc
+++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h"
 #include "chrome/browser/chromeos/login/test/https_forwarder.h"
 #include "chrome/browser/chromeos/login/test/js_checker.h"
+#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h"
 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
@@ -218,13 +219,15 @@
   content::DOMMessageQueue message_queue;
   std::string js =
       R"((function() {
-            var authenticator = $('gaia-signin').gaiaAuthHost_;
+            var authenticator = $AuthenticatorId;
             var f = function() {
               authenticator.removeEventListener('$Event', f);
               window.domAutomationController.send('Done');
             };
             authenticator.addEventListener('$Event', f);
           })();)";
+  base::ReplaceSubstringsAfterOffset(&js, 0, "$AuthenticatorId",
+                                     authenticator_id_);
   base::ReplaceSubstringsAfterOffset(&js, 0, "$Event", event);
   test::OobeJS().Evaluate(js);
 
@@ -234,6 +237,14 @@
   } while (message != "\"Done\"");
 }
 
+void OobeBaseTest::WaitForEnrollmentSuccess() {
+  test::OobeJS()
+      .CreateWaiter(
+          "document.getElementsByClassName('oauth-enroll-state-attribute-"
+          "prompt').length > 0")
+      ->Wait();
+}
+
 void OobeBaseTest::WaitForSigninScreen() {
   WizardController* wizard_controller = WizardController::default_controller();
   if (wizard_controller)
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.h b/chrome/browser/chromeos/login/test/oobe_base_test.h
index 4f5ddb4..a81af4f2 100644
--- a/chrome/browser/chromeos/login/test/oobe_base_test.h
+++ b/chrome/browser/chromeos/login/test/oobe_base_test.h
@@ -65,6 +65,7 @@
   void WaitForGaiaPageBackButtonUpdate();
   void WaitForGaiaPageEvent(const std::string& event);
   void WaitForSigninScreen();
+  void WaitForEnrollmentSuccess();
   void ExecuteJsInSigninFrame(const std::string& js);
   void SetSignFormField(const std::string& field_id,
                         const std::string& field_value);
@@ -80,6 +81,7 @@
   std::unique_ptr<content::WindowedNotificationObserver>
       login_screen_load_observer_;
   std::string gaia_frame_parent_ = "signin-frame";
+  std::string authenticator_id_ = "$('gaia-signin').gaiaAuthHost_";
 
   DISALLOW_COPY_AND_ASSIGN(OobeBaseTest);
 };
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
index 0ca250f0..aace7b26 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -235,15 +235,6 @@
   return &entry->value->GetList();
 }
 
-bool IsPacHttpsUrlStrippingDisabled(
-    policy::DeviceLocalAccountPolicyBroker* broker) {
-  const policy::PolicyMap::Entry* entry =
-      broker->core()->store()->policy_map().Get(
-          policy::key::kPacHttpsUrlStrippingEnabled);
-  // Policy is enabled and it's value is set to 'false'.
-  return entry && entry->value && !entry->value->GetBool();
-}
-
 bool AreRiskyPoliciesUsed(policy::DeviceLocalAccountPolicyBroker* broker) {
   const policy::PolicyMap& policy_map = broker->core()->store()->policy_map();
   for (const auto& it : policy_map) {
@@ -1536,8 +1527,7 @@
 bool ChromeUserManagerImpl::IsFullManagementDisclosureNeeded(
     policy::DeviceLocalAccountPolicyBroker* broker) const {
   return IsManagedSessionEnabled(broker) &&
-         (IsPacHttpsUrlStrippingDisabled(broker) ||
-          AreRiskyPoliciesUsed(broker) ||
+         (AreRiskyPoliciesUsed(broker) ||
           AreRiskyExtensionsForceInstalled(broker) ||
           AreForcedNetworkCertificatesInstalled() ||
           IsProxyUsed(GetLocalState()));
diff --git a/chrome/browser/chromeos/oauth2_token_service_delegate.cc b/chrome/browser/chromeos/oauth2_token_service_delegate.cc
index d7b3e02..e538d61 100644
--- a/chrome/browser/chromeos/oauth2_token_service_delegate.cc
+++ b/chrome/browser/chromeos/oauth2_token_service_delegate.cc
@@ -13,7 +13,6 @@
 #include "base/stl_util.h"
 #include "chromeos/account_manager/account_manager.h"
 #include "components/signin/core/browser/account_tracker_service.h"
-#include "content/public/browser/network_service_instance.h"
 #include "google_apis/gaia/oauth2_access_token_fetcher_immediate_error.h"
 #include "net/base/backoff_entry.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -69,18 +68,20 @@
 
 ChromeOSOAuth2TokenServiceDelegate::ChromeOSOAuth2TokenServiceDelegate(
     AccountTrackerService* account_tracker_service,
+    network::NetworkConnectionTracker* network_connection_tracker,
     chromeos::AccountManager* account_manager)
     : account_tracker_service_(account_tracker_service),
+      network_connection_tracker_(network_connection_tracker),
       account_manager_(account_manager),
       backoff_entry_(&kBackoffPolicy),
       backoff_error_(GoogleServiceAuthError::NONE),
       weak_factory_(this) {
-  content::GetNetworkConnectionTracker()->AddNetworkConnectionObserver(this);
+  network_connection_tracker_->AddNetworkConnectionObserver(this);
 }
 
 ChromeOSOAuth2TokenServiceDelegate::~ChromeOSOAuth2TokenServiceDelegate() {
   account_manager_->RemoveObserver(this);
-  content::GetNetworkConnectionTracker()->RemoveNetworkConnectionObserver(this);
+  network_connection_tracker_->RemoveNetworkConnectionObserver(this);
 }
 
 OAuth2AccessTokenFetcher*
diff --git a/chrome/browser/chromeos/oauth2_token_service_delegate.h b/chrome/browser/chromeos/oauth2_token_service_delegate.h
index b87a2de..aabc6a2 100644
--- a/chrome/browser/chromeos/oauth2_token_service_delegate.h
+++ b/chrome/browser/chromeos/oauth2_token_service_delegate.h
@@ -27,12 +27,12 @@
       public AccountManager::Observer,
       public network::NetworkConnectionTracker::NetworkConnectionObserver {
  public:
-  // Accepts non-owning pointers to |AccountTrackerService| and
-  // |AccountManager|. |AccountTrackerService| is a |KeyedService|.
-  // |AccountManager| transitively belongs to |g_browser_process|. They outlive
-  // (as they must) |this| delegate.
+  // Accepts non-owning pointers to |AccountTrackerService|,
+  // |NetworkConnectorTracker|, and |AccountManager|. These objects must all
+  // outlive |this| delegate.
   ChromeOSOAuth2TokenServiceDelegate(
       AccountTrackerService* account_tracker_service,
+      network::NetworkConnectionTracker* network_connection_tracker,
       AccountManager* account_manager);
   ~ChromeOSOAuth2TokenServiceDelegate() override;
 
@@ -81,6 +81,9 @@
   // A non-owning pointer.
   AccountTrackerService* const account_tracker_service_;
 
+  // A non-owning pointer.
+  network::NetworkConnectionTracker* const network_connection_tracker_;
+
   // A non-owning pointer. |AccountManager| is available
   // throughout the lifetime of a user session.
   AccountManager* const account_manager_;
diff --git a/chrome/browser/chromeos/oauth2_token_service_delegate_unittest.cc b/chrome/browser/chromeos/oauth2_token_service_delegate_unittest.cc
index 7f75bb6..06eea16 100644
--- a/chrome/browser/chromeos/oauth2_token_service_delegate_unittest.cc
+++ b/chrome/browser/chromeos/oauth2_token_service_delegate_unittest.cc
@@ -14,17 +14,18 @@
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/stl_util.h"
+#include "base/test/scoped_task_environment.h"
 #include "chromeos/account_manager/account_manager.h"
 #include "components/signin/core/browser/account_info.h"
 #include "components/signin/core/browser/account_tracker_service.h"
 #include "components/signin/core/browser/signin_pref_names.h"
 #include "components/signin/core/browser/test_signin_client.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
-#include "content/public/test/test_browser_thread_bundle.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "google_apis/gaia/oauth2_access_token_consumer.h"
 #include "google_apis/gaia/oauth2_token_service.h"
 #include "google_apis/gaia/oauth2_token_service_test_util.h"
+#include "services/network/test/test_network_connection_tracker.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
@@ -148,7 +149,7 @@
     account_manager_.Initialize(tmp_dir_.GetPath(),
                                 client_->GetURLLoaderFactory(),
                                 immediate_callback_runner_);
-    thread_bundle_.RunUntilIdle();
+    task_environment_.RunUntilIdle();
 
     account_tracker_service_.Initialize(&pref_service_, base::FilePath());
 
@@ -158,7 +159,9 @@
     ad_account_key_ = {"object-guid", ACCOUNT_TYPE_ACTIVE_DIRECTORY};
 
     delegate_ = std::make_unique<ChromeOSOAuth2TokenServiceDelegate>(
-        &account_tracker_service_, &account_manager_);
+        &account_tracker_service_,
+        network::TestNetworkConnectionTracker::GetInstance(),
+        &account_manager_);
     delegate_->LoadCredentials(
         account_info_.account_id /* primary_account_id */);
   }
@@ -191,11 +194,7 @@
         GetValidTokenResponse("token", 3600));
   }
 
-  // Needed because
-  // |content::GetNetworkConnectionTracker()->AddNetworkConnectionObserver| in
-  // |ChromeOSOAuth2TokenServiceDelegate|'s constructor CHECKs that we are
-  // running on the browser UI thread.
-  content::TestBrowserThreadBundle thread_bundle_;
+  base::test::ScopedTaskEnvironment task_environment_;
 
   base::ScopedTempDir tmp_dir_;
   AccountInfo account_info_;
@@ -352,21 +351,22 @@
   account_manager_.UpsertAccount(
       AccountManager::AccountKey{account2.gaia, ACCOUNT_TYPE_GAIA},
       "user2@example.com", "token2");
-  thread_bundle_.RunUntilIdle();
+  task_environment_.RunUntilIdle();
 
   AccountManager account_manager;
   // AccountManager will not be fully initialized until
-  // |thread_bundle_.RunUntilIdle()| is called.
+  // |task_environment_.RunUntilIdle()| is called.
   account_manager.Initialize(tmp_dir_.GetPath(), client_->GetURLLoaderFactory(),
                              immediate_callback_runner_);
 
   // Register callbacks before AccountManager has been fully initialized.
   auto delegate = std::make_unique<ChromeOSOAuth2TokenServiceDelegate>(
-      &account_tracker_service_, &account_manager);
+      &account_tracker_service_,
+      network::TestNetworkConnectionTracker::GetInstance(), &account_manager);
   delegate->LoadCredentials(account1.account_id /* primary_account_id */);
   TokenServiceObserver observer(delegate.get());
   // Wait until AccountManager is fully initialized.
-  thread_bundle_.RunUntilIdle();
+  task_environment_.RunUntilIdle();
 
   // Tests
 
@@ -515,9 +515,9 @@
       delegate_->CreateAccessTokenFetcher(account_info_.account_id,
                                           delegate_->GetURLLoaderFactory(),
                                           &access_token_consumer));
-  thread_bundle_.RunUntilIdle();
+  task_environment_.RunUntilIdle();
   fetcher->Start("client_id", "client_secret", scopes);
-  thread_bundle_.RunUntilIdle();
+  task_environment_.RunUntilIdle();
   EXPECT_EQ(0, access_token_consumer.num_access_token_fetch_success_);
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_failure_);
   // Expect a positive backoff time.
@@ -529,7 +529,7 @@
       account_info_.account_id, delegate_->GetURLLoaderFactory(),
       &access_token_consumer));
   fetcher->Start("client_id", "client_secret", scopes);
-  thread_bundle_.RunUntilIdle();
+  task_environment_.RunUntilIdle();
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_success_);
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_failure_);
 }
@@ -552,9 +552,9 @@
       delegate_->CreateAccessTokenFetcher(account_info_.account_id,
                                           delegate_->GetURLLoaderFactory(),
                                           &access_token_consumer));
-  thread_bundle_.RunUntilIdle();
+  task_environment_.RunUntilIdle();
   fetcher->Start("client_id", "client_secret", scopes);
-  thread_bundle_.RunUntilIdle();
+  task_environment_.RunUntilIdle();
   EXPECT_EQ(0, access_token_consumer.num_access_token_fetch_success_);
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_failure_);
   // Expect a positive backoff time.
@@ -567,7 +567,7 @@
       account_info_.account_id, delegate_->GetURLLoaderFactory(),
       &access_token_consumer));
   fetcher->Start("client_id", "client_secret", scopes);
-  thread_bundle_.RunUntilIdle();
+  task_environment_.RunUntilIdle();
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_success_);
   EXPECT_EQ(1, access_token_consumer.num_access_token_fetch_failure_);
 }
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index e3f5ec6c..e29e9a40 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -2601,42 +2601,6 @@
           broker));
 }
 
-// TODO(crbug.com/939700): Fix this test.
-#if 0
-IN_PROC_BROWSER_TEST_F(ManagedSessionsTest, PacHttpsUrlStrippingEnabled) {
-  SetManagedSessionsEnabled(/* managed_sessions_enabled */ true);
-
-  device_local_account_policy_.payload()
-      .mutable_pachttpsurlstrippingenabled()
-      ->set_value(false);
-
-  // Install and refresh the device policy now. This will also fetch the initial
-  // user policy for the device-local account now.
-  UploadAndInstallDeviceLocalAccountPolicy();
-  AddPublicSessionToDevicePolicy(kAccountId1);
-  AddNetworkCertificateToDevicePolicy();
-  WaitForPolicy();
-
-  const user_manager::User* user =
-      user_manager::UserManager::Get()->FindUser(account_id_1_);
-  ASSERT_TRUE(user);
-  auto* broker = GetDeviceLocalAccountPolicyBroker();
-  ASSERT_TRUE(broker);
-
-  // Check that 'DeviceLocalAccountManagedSessionEnabled' policy was applied
-  // correctly.
-  ASSERT_TRUE(
-      chromeos::ChromeUserManager::Get()->IsManagedSessionEnabledForUser(
-          *user));
-
-  // Check that disabling 'PacHttpsUrlStrippingEnabled' activates managed
-  // sessions mode.
-  ASSERT_TRUE(
-      chromeos::ChromeUserManager::Get()->IsFullManagementDisclosureNeeded(
-          broker));
-}
-#endif
-
 class TermsOfServiceDownloadTest : public DeviceLocalAccountTest,
                                    public testing::WithParamInterface<bool> {
 };
diff --git a/chrome/browser/extensions/api/device_permissions_manager_unittest.cc b/chrome/browser/extensions/api/device_permissions_manager_unittest.cc
index 1beb223..4b3185b1 100644
--- a/chrome/browser/extensions/api/device_permissions_manager_unittest.cc
+++ b/chrome/browser/extensions/api/device_permissions_manager_unittest.cc
@@ -12,11 +12,11 @@
 #include "base/test/values_test_util.h"
 #include "chrome/browser/extensions/test_extension_environment.h"
 #include "chrome/test/base/testing_profile.h"
-#include "device/base/mock_device_client.h"
-#include "device/usb/public/cpp/fake_usb_device_info.h"
+#include "device/usb/public/cpp/fake_usb_device_manager.h"
 #include "device/usb/public/mojom/device.mojom.h"
 #include "extensions/browser/api/device_permissions_manager.h"
 #include "extensions/browser/api/hid/hid_device_manager.h"
+#include "extensions/browser/api/usb/usb_device_manager.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/common/extension.h"
 #include "services/device/public/mojom/hid.mojom.h"
@@ -65,17 +65,24 @@
         "  \"permissions\": [ \"hid\", \"usb\" ]"
         "}"));
 
+    // Set fake device manager for extensions::UsbDeviceManager.
+    device::mojom::UsbDeviceManagerPtr usb_manager_ptr;
+    fake_usb_manager_.AddBinding(mojo::MakeRequest(&usb_manager_ptr));
+    UsbDeviceManager::Get(env_->profile())
+        ->SetDeviceManagerForTesting(std::move(usb_manager_ptr));
+    base::RunLoop().RunUntilIdle();
+
+    device0_ = fake_usb_manager_.CreateAndAddDevice(0, 0, "Test Manufacturer",
+                                                    "Test Product", "ABCDE");
+    device1_ = fake_usb_manager_.CreateAndAddDevice(0, 0, "Test Manufacturer",
+                                                    "Test Product", "");
+    device2_ = fake_usb_manager_.CreateAndAddDevice(0, 0, "Test Manufacturer",
+                                                    "Test Product", "12345");
+    device3_ = fake_usb_manager_.CreateAndAddDevice(0, 0, "Test Manufacturer",
+                                                    "Test Product", "");
+
     HidDeviceManager::GetFactoryInstance()->SetTestingFactory(
         env_->profile(), base::BindRepeating(&CreateHidDeviceManager));
-    device0_ = base::MakeRefCounted<FakeUsbDeviceInfo>(
-        0, 0, "Test Manufacturer", "Test Product", "ABCDE");
-    device1_ = base::MakeRefCounted<FakeUsbDeviceInfo>(
-        0, 0, "Test Manufacturer", "Test Product", "");
-    device2_ = base::MakeRefCounted<FakeUsbDeviceInfo>(
-        0, 0, "Test Manufacturer", "Test Product", "12345");
-    device3_ = base::MakeRefCounted<FakeUsbDeviceInfo>(
-        0, 0, "Test Manufacturer", "Test Product", "");
-
     device4_ = device::mojom::HidDeviceInfo::New();
     device4_->guid = kTestDeviceGuids[0];
     device4_->product_name = "Test HID Device";
@@ -105,11 +112,12 @@
 
   std::unique_ptr<extensions::TestExtensionEnvironment> env_;
   const extensions::Extension* extension_;
-  device::MockDeviceClient device_client_;
-  scoped_refptr<device::FakeUsbDeviceInfo> device0_;
-  scoped_refptr<device::FakeUsbDeviceInfo> device1_;
-  scoped_refptr<device::FakeUsbDeviceInfo> device2_;
-  scoped_refptr<device::FakeUsbDeviceInfo> device3_;
+  device::FakeUsbDeviceManager fake_usb_manager_;
+  device::mojom::UsbDeviceInfoPtr device0_;
+  device::mojom::UsbDeviceInfoPtr device1_;
+  device::mojom::UsbDeviceInfoPtr device2_;
+  device::mojom::UsbDeviceInfoPtr device3_;
+
   device::mojom::HidDeviceInfoPtr device4_;
   device::mojom::HidDeviceInfoPtr device5_;
   device::mojom::HidDeviceInfoPtr device6_;
@@ -119,23 +127,21 @@
 TEST_F(DevicePermissionsManagerTest, AllowAndClearDevices) {
   DevicePermissionsManager* manager =
       DevicePermissionsManager::Get(env_->profile());
-  manager->AllowUsbDevice(extension_->id(), device0_->GetDeviceInfo());
-  manager->AllowUsbDevice(extension_->id(), device1_->GetDeviceInfo());
+  manager->AllowUsbDevice(extension_->id(), *device0_);
+  manager->AllowUsbDevice(extension_->id(), *device1_);
   manager->AllowHidDevice(extension_->id(), *device4_);
   manager->AllowHidDevice(extension_->id(), *device5_);
 
   DevicePermissions* device_permissions =
       manager->GetForExtension(extension_->id());
   scoped_refptr<DevicePermissionEntry> device0_entry =
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo());
+      device_permissions->FindUsbDeviceEntry(*device0_);
   ASSERT_TRUE(device0_entry);
   scoped_refptr<DevicePermissionEntry> device1_entry =
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo());
+      device_permissions->FindUsbDeviceEntry(*device1_);
   ASSERT_TRUE(device1_entry);
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device2_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device3_->GetDeviceInfo()));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device2_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device3_));
   scoped_refptr<DevicePermissionEntry> device4_entry =
       device_permissions->FindHidDeviceEntry(*device4_);
   ASSERT_TRUE(device4_entry);
@@ -160,14 +166,10 @@
   // The device_permissions object is deleted by Clear.
   device_permissions = manager->GetForExtension(extension_->id());
 
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device2_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device3_->GetDeviceInfo()));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device0_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device1_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device2_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device3_));
   EXPECT_FALSE(device_permissions->FindHidDeviceEntry(*device4_));
   EXPECT_FALSE(device_permissions->FindHidDeviceEntry(*device5_));
   EXPECT_FALSE(device_permissions->FindHidDeviceEntry(*device6_));
@@ -175,19 +177,15 @@
   EXPECT_EQ(0U, device_permissions->entries().size());
 
   // After clearing device it should be possible to grant permission again.
-  manager->AllowUsbDevice(extension_->id(), device0_->GetDeviceInfo());
-  manager->AllowUsbDevice(extension_->id(), device1_->GetDeviceInfo());
+  manager->AllowUsbDevice(extension_->id(), *device0_);
+  manager->AllowUsbDevice(extension_->id(), *device1_);
   manager->AllowHidDevice(extension_->id(), *device4_);
   manager->AllowHidDevice(extension_->id(), *device5_);
 
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo()));
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device2_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device3_->GetDeviceInfo()));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device0_));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device1_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device2_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device3_));
   EXPECT_TRUE(device_permissions->FindHidDeviceEntry(*device4_));
   EXPECT_TRUE(device_permissions->FindHidDeviceEntry(*device5_));
   EXPECT_FALSE(device_permissions->FindHidDeviceEntry(*device6_));
@@ -197,51 +195,40 @@
 TEST_F(DevicePermissionsManagerTest, DisconnectDevice) {
   DevicePermissionsManager* manager =
       DevicePermissionsManager::Get(env_->profile());
-  manager->AllowUsbDevice(extension_->id(), device0_->GetDeviceInfo());
-  manager->AllowUsbDevice(extension_->id(), device1_->GetDeviceInfo());
+  manager->AllowUsbDevice(extension_->id(), *device0_);
+  manager->AllowUsbDevice(extension_->id(), *device1_);
   manager->AllowHidDevice(extension_->id(), *device4_);
   manager->AllowHidDevice(extension_->id(), *device5_);
 
   DevicePermissions* device_permissions =
       manager->GetForExtension(extension_->id());
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo()));
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device2_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device3_->GetDeviceInfo()));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device0_));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device1_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device2_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device3_));
   EXPECT_TRUE(device_permissions->FindHidDeviceEntry(*device4_));
   EXPECT_TRUE(device_permissions->FindHidDeviceEntry(*device5_));
   EXPECT_FALSE(device_permissions->FindHidDeviceEntry(*device6_));
   EXPECT_FALSE(device_permissions->FindHidDeviceEntry(*device7_));
 
-  // TODO(donna.wu@intel.com): Remove the device entry through the observer
-  // interface on UsbDeviceManager, so it can test the real disconnect path.
-  manager->RemoveEntryByDeviceGUID(DevicePermissionEntry::Type::USB,
-                                   device0_->guid());
-  manager->RemoveEntryByDeviceGUID(DevicePermissionEntry::Type::USB,
-                                   device1_->guid());
+  fake_usb_manager_.RemoveDevice(device0_->guid);
+  fake_usb_manager_.RemoveDevice(device1_->guid);
 
   manager->RemoveEntryByDeviceGUID(DevicePermissionEntry::Type::HID,
                                    device4_->guid);
   manager->RemoveEntryByDeviceGUID(DevicePermissionEntry::Type::HID,
                                    device5_->guid);
+  base::RunLoop().RunUntilIdle();
 
   // Device 0 will be accessible when it is reconnected because it can be
   // recognized by its serial number.
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo()));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device0_));
   // Device 1 does not have a serial number and cannot be distinguished from
   // any other device of the same model so the app must request permission again
   // when it is reconnected.
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device2_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device3_->GetDeviceInfo()));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device1_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device2_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device3_));
   // Device 4 is like device 0, but HID.
   EXPECT_TRUE(device_permissions->FindHidDeviceEntry(*device4_));
   // Device 5 is like device 1, but HID.
@@ -253,18 +240,18 @@
 TEST_F(DevicePermissionsManagerTest, RevokeAndRegrantAccess) {
   DevicePermissionsManager* manager =
       DevicePermissionsManager::Get(env_->profile());
-  manager->AllowUsbDevice(extension_->id(), device0_->GetDeviceInfo());
-  manager->AllowUsbDevice(extension_->id(), device1_->GetDeviceInfo());
+  manager->AllowUsbDevice(extension_->id(), *device0_);
+  manager->AllowUsbDevice(extension_->id(), *device1_);
   manager->AllowHidDevice(extension_->id(), *device4_);
   manager->AllowHidDevice(extension_->id(), *device5_);
 
   DevicePermissions* device_permissions =
       manager->GetForExtension(extension_->id());
   scoped_refptr<DevicePermissionEntry> device0_entry =
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo());
+      device_permissions->FindUsbDeviceEntry(*device0_);
   ASSERT_TRUE(device0_entry);
   scoped_refptr<DevicePermissionEntry> device1_entry =
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo());
+      device_permissions->FindUsbDeviceEntry(*device1_);
   ASSERT_TRUE(device1_entry);
   scoped_refptr<DevicePermissionEntry> device4_entry =
       device_permissions->FindHidDeviceEntry(*device4_);
@@ -274,28 +261,20 @@
   ASSERT_TRUE(device5_entry);
 
   manager->RemoveEntry(extension_->id(), device0_entry);
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo()));
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device0_));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device1_));
 
-  manager->AllowUsbDevice(extension_->id(), device0_->GetDeviceInfo());
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo()));
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
+  manager->AllowUsbDevice(extension_->id(), *device0_);
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device0_));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device1_));
 
   manager->RemoveEntry(extension_->id(), device1_entry);
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device0_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device1_));
 
-  manager->AllowUsbDevice(extension_->id(), device1_->GetDeviceInfo());
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo()));
-  EXPECT_TRUE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
+  manager->AllowUsbDevice(extension_->id(), *device1_);
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device0_));
+  EXPECT_TRUE(device_permissions->FindUsbDeviceEntry(*device1_));
 
   manager->RemoveEntry(extension_->id(), device4_entry);
   EXPECT_FALSE(device_permissions->FindHidDeviceEntry(*device4_));
@@ -317,13 +296,13 @@
 TEST_F(DevicePermissionsManagerTest, UpdateLastUsed) {
   DevicePermissionsManager* manager =
       DevicePermissionsManager::Get(env_->profile());
-  manager->AllowUsbDevice(extension_->id(), device0_->GetDeviceInfo());
+  manager->AllowUsbDevice(extension_->id(), *device0_);
   manager->AllowHidDevice(extension_->id(), *device4_);
 
   DevicePermissions* device_permissions =
       manager->GetForExtension(extension_->id());
   scoped_refptr<DevicePermissionEntry> device0_entry =
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo());
+      device_permissions->FindUsbDeviceEntry(*device0_);
   EXPECT_TRUE(device0_entry->last_used().is_null());
   scoped_refptr<DevicePermissionEntry> device4_entry =
       device_permissions->FindHidDeviceEntry(*device4_);
@@ -362,14 +341,11 @@
   DevicePermissions* device_permissions =
       manager->GetForExtension(extension_->id());
   scoped_refptr<DevicePermissionEntry> device0_entry =
-      device_permissions->FindUsbDeviceEntry(device0_->GetDeviceInfo());
+      device_permissions->FindUsbDeviceEntry(*device0_);
   ASSERT_TRUE(device0_entry);
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device1_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device2_->GetDeviceInfo()));
-  EXPECT_FALSE(
-      device_permissions->FindUsbDeviceEntry(device3_->GetDeviceInfo()));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device1_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device2_));
+  EXPECT_FALSE(device_permissions->FindUsbDeviceEntry(*device3_));
   scoped_refptr<DevicePermissionEntry> device4_entry =
       device_permissions->FindHidDeviceEntry(*device4_);
   ASSERT_TRUE(device4_entry);
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
index 4403b6f..f189c53 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -164,7 +164,7 @@
 
 void IdentityGetAuthTokenFunction::GetAuthTokenForPrimaryAccount(
     const std::string& extension_gaia_id) {
-  AccountInfo primary_account_info =
+  CoreAccountInfo primary_account_info =
       IdentityManagerFactory::GetForProfile(GetProfile())
           ->GetPrimaryAccountInfo();
   bool primary_account_only = IsPrimaryAccountOnly();
@@ -187,7 +187,9 @@
             primary_account_info.account_id);
     OnReceivedExtensionAccountInfo(
         primary_account_info.gaia,
-        base::Optional<AccountInfo>(primary_account_info), account_state);
+        identity_manager->FindExtendedAccountInfoForAccount(
+            primary_account_info),
+        account_state);
   } else {
     // No primary account, try the first account in cookies.
     DCHECK_EQ(AccountListeningMode::kNotListening, account_listening_mode_);
@@ -268,7 +270,7 @@
             account.gaia_id));
   } else {
     OnReceivedExtensionAccountInfo(
-        /*extension_gaia_id=*/std::string(), base::Optional<AccountInfo>(),
+        /*extension_gaia_id=*/std::string(), base::nullopt,
         identity::AccountState());
   }
 }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 93375091..a828397 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2317,12 +2317,12 @@
   },
   {
     "name": "network-service",
-    // "owners": [ "your-team" ],
+    "owners": [ "network-service-dev" ],
     "expiry_milestone": 76
   },
   {
     "name": "network-service-in-process",
-    // "owners": [ "your-team" ],
+    "owners": [ "network-service-dev" ],
     "expiry_milestone": 76
   },
   {
diff --git a/chrome/browser/loader/cors_origin_access_list_browsertest.cc b/chrome/browser/loader/cors_origin_access_list_browsertest.cc
index 6751d1c..6f84bc1 100644
--- a/chrome/browser/loader/cors_origin_access_list_browsertest.cc
+++ b/chrome/browser/loader/cors_origin_access_list_browsertest.cc
@@ -41,34 +41,16 @@
 const char kTestHostInDifferentCase[] = "CrossOrigin.example.com";
 const char kTestSubdomainHost[] = "subdomain.crossorigin.example.com";
 
-enum class TestMode {
-  kOutOfBlinkCorsWithServicification,
-  kOutOfBlinkCorsWithoutServicification,
-};
-
 // Tests end to end functionality of CORS access origin allow lists.
-class CorsOriginAccessListBrowserTest
-    : public InProcessBrowserTest,
-      public testing::WithParamInterface<TestMode> {
+class CorsOriginAccessListBrowserTest : public InProcessBrowserTest {
  public:
   CorsOriginAccessListBrowserTest() {
-    switch (GetParam()) {
-      case TestMode::kOutOfBlinkCorsWithServicification:
-        scoped_feature_list_.InitWithFeatures(
-            // Enabled features
-            {network::features::kOutOfBlinkCors,
-             network::features::kNetworkService},
-            // Disabled features
-            {});
-        break;
-      case TestMode::kOutOfBlinkCorsWithoutServicification:
-        scoped_feature_list_.InitWithFeatures(
-            // Enabled features
-            {network::features::kOutOfBlinkCors},
-            // Disabled features
-            {network::features::kNetworkService});
-        break;
-    }
+    scoped_feature_list_.InitWithFeatures(
+        // Enabled features
+        {network::features::kOutOfBlinkCors,
+         network::features::kNetworkService},
+        // Disabled features
+        {});
   }
 
  protected:
@@ -166,7 +148,7 @@
 };
 
 // Tests if specifying only protocol allows all hosts to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAll) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowAll) {
   SetAllowList("http", "", kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -177,7 +159,7 @@
 }
 
 // Tests if specifying only protocol allows all IP address based hosts to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAllForIp) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowAllForIp) {
   SetAllowList("http", "", kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -190,7 +172,7 @@
 }
 
 // Tests if complete allow list set allows only exactly matched host to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowExactHost) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowExactHost) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -202,7 +184,7 @@
 
 // Tests if complete allow list set allows host that matches exactly, but in
 // case insensitive way to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        AllowExactHostInCaseInsensitive) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
@@ -216,7 +198,7 @@
 
 // Tests if complete allow list set does not allow a host with a different port
 // to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -227,7 +209,7 @@
 }
 
 // Tests if complete allow list set allows a subdomain to pass if it is allowed.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowSubdomain) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowSubdomain) {
   SetAllowList("http", kTestHost, kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -238,7 +220,7 @@
 }
 
 // Tests if complete allow list set does not allow a subdomain to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockSubdomain) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, BlockSubdomain) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -250,7 +232,7 @@
 
 // Tests if complete allow list set does not allow a host with a different
 // protocol to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        BlockDifferentProtocol) {
   SetAllowList("https", kTestHost, kDisallowSubdomains);
 
@@ -262,7 +244,7 @@
 }
 
 // Tests if IP address based hosts should not follow subdomain match rules.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        SubdomainMatchShouldNotBeAppliedForIPAddress) {
   SetAllowList("http", "*.0.0.1", kAllowSubdomains);
 
@@ -275,17 +257,4 @@
   EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()) << GetReason();
 }
 
-INSTANTIATE_TEST_SUITE_P(
-    OutOfBlinkCorsWithServicification,
-    CorsOriginAccessListBrowserTest,
-    ::testing::Values(TestMode::kOutOfBlinkCorsWithServicification));
-
-INSTANTIATE_TEST_SUITE_P(
-    OutOfBlinkCorsWithoutServicification,
-    CorsOriginAccessListBrowserTest,
-    ::testing::Values(TestMode::kOutOfBlinkCorsWithoutServicification));
-
-// TODO(toyoshim): Instantiates tests for the case kOutOfBlinkCors is disabled
-// and remove relevant web tests if it's possible.
-
 }  // namespace
diff --git a/chrome/browser/memory/memory_pressure_monitor_utils.h b/chrome/browser/memory/memory_pressure_monitor_utils.h
new file mode 100644
index 0000000..4a5d8bb
--- /dev/null
+++ b/chrome/browser/memory/memory_pressure_monitor_utils.h
@@ -0,0 +1,75 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_MEMORY_MEMORY_PRESSURE_MONITOR_UTILS_H_
+#define CHROME_BROWSER_MEMORY_MEMORY_PRESSURE_MONITOR_UTILS_H_
+
+#include <deque>
+#include <utility>
+
+#include "base/macros.h"
+#include "base/sequence_checker.h"
+#include "base/time/time.h"
+
+namespace base {
+class TickClock;
+}
+
+namespace memory {
+namespace internal {
+
+// An observation window consists of a series of samples. Samples in this window
+// will have a maximum age (the window length), samples that exceed that age
+// will be automatically trimmed when a new one is available.
+//
+// Concurrent calls to instances of this class aren't allowed.
+template <typename T>
+class ObservationWindow {
+ public:
+  explicit ObservationWindow(base::TimeDelta window_length);
+  virtual ~ObservationWindow();
+
+  // Function that should be called each time a new sample is available. When a
+  // new sample gets added the entries that exceeds the age of this window will
+  // first be removed, and then the new one will be added to it.
+  void OnSample(const T sample);
+
+ protected:
+  using Observation = std::pair<const base::TimeTicks, const T>;
+
+  // Called each time a sample gets added to the observation window.
+  virtual void OnSampleAdded(const T& sample) = 0;
+
+  // Called each time a sample gets removed from the observation window.
+  virtual void OnSampleRemoved(const T& sample) = 0;
+
+  const std::deque<Observation>& observations_for_testing() {
+    return observations_;
+  }
+
+  void set_clock_for_testing(const base::TickClock* clock) { clock_ = clock; }
+
+ private:
+  // The length of the window. Samples older than |base::TimeTicks::Now() -
+  // window_length_| will automatically be removed from this window when a new
+  // one gets added.
+  const base::TimeDelta window_length_;
+
+  // The observations, in order of arrival.
+  std::deque<Observation> observations_;
+
+  // Allow for an injectable clock for testing.
+  const base::TickClock* clock_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  DISALLOW_COPY_AND_ASSIGN(ObservationWindow);
+};
+
+}  // namespace internal
+}  // namespace memory
+
+#include "chrome/browser/memory/memory_pressure_monitor_utils_impl.h"
+
+#endif  // CHROME_BROWSER_MEMORY_MEMORY_PRESSURE_MONITOR_UTILS_H_
diff --git a/chrome/browser/memory/memory_pressure_monitor_utils_impl.h b/chrome/browser/memory/memory_pressure_monitor_utils_impl.h
new file mode 100644
index 0000000..ba3f61d
--- /dev/null
+++ b/chrome/browser/memory/memory_pressure_monitor_utils_impl.h
@@ -0,0 +1,47 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_MEMORY_MEMORY_PRESSURE_MONITOR_UTILS_IMPL_H_
+#define CHROME_BROWSER_MEMORY_MEMORY_PRESSURE_MONITOR_UTILS_IMPL_H_
+
+#ifndef CHROME_BROWSER_MEMORY_MEMORY_PRESSURE_MONITOR_UTILS_H_
+#error This file is meant to be included by memory_pressure_monitor_utils.h.
+#endif
+
+#include <utility>
+
+#include "base/time/default_tick_clock.h"
+
+namespace memory {
+namespace internal {
+
+template <typename T>
+ObservationWindow<T>::ObservationWindow(base::TimeDelta window_length)
+    : window_length_(window_length),
+      clock_(base::DefaultTickClock::GetInstance()) {}
+
+template <typename T>
+ObservationWindow<T>::~ObservationWindow() = default;
+
+template <typename T>
+void ObservationWindow<T>::OnSample(const T sample) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  const base::TimeTicks now = clock_->NowTicks();
+  // Trim some samples if needed.
+  while (observations_.size() &&
+         (observations_.begin()->first < (now - window_length_))) {
+    OnSampleRemoved(observations_.begin()->second);
+    observations_.pop_front();
+  }
+
+  // Add the new sample to the observations.
+  OnSampleAdded(sample);
+  observations_.emplace_back(std::make_pair(now, std::move(sample)));
+}
+
+}  // namespace internal
+}  // namespace memory
+
+#endif  // CHROME_BROWSER_MEMORY_MEMORY_PRESSURE_MONITOR_UTILS_IMPL_H_
diff --git a/chrome/browser/memory/memory_pressure_monitor_utils_unittest.cc b/chrome/browser/memory/memory_pressure_monitor_utils_unittest.cc
new file mode 100644
index 0000000..929e00b
--- /dev/null
+++ b/chrome/browser/memory/memory_pressure_monitor_utils_unittest.cc
@@ -0,0 +1,106 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/memory/memory_pressure_monitor_utils.h"
+
+#include "base/test/scoped_task_environment.h"
+#include "base/time/time.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace memory {
+namespace {
+
+constexpr base::TimeDelta kDefaultWindowLength =
+    base::TimeDelta::FromMinutes(1);
+
+}  // namespace
+
+// Test class used to expose some protected members from
+// internal::ObservationWindow and to simplify the tests by removing the
+// template argument.
+class TestObservationWindow : public internal::ObservationWindow<int> {
+ public:
+  TestObservationWindow()
+      : internal::ObservationWindow<int>(kDefaultWindowLength) {}
+  ~TestObservationWindow() override = default;
+
+  using internal::ObservationWindow<int>::observations_for_testing;
+  using internal::ObservationWindow<int>::set_clock_for_testing;
+
+  bool Empty() { return observations_for_testing().empty(); }
+
+  MOCK_METHOD1(OnSampleAdded, void(const int& sample));
+  MOCK_METHOD1(OnSampleRemoved, void(const int& sample));
+};
+
+using ObservationWindowTest = testing::Test;
+
+TEST_F(ObservationWindowTest, OnSample) {
+  base::test::ScopedTaskEnvironment scoped_task_environment(
+      base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
+
+  ::testing::StrictMock<TestObservationWindow> window;
+
+  typedef decltype(window.observations_for_testing()) ObservationContainerType;
+
+  const auto* tick_clock = scoped_task_environment.GetMockTickClock();
+  window.set_clock_for_testing(tick_clock);
+
+  // The window is expected to be empty by default.
+  EXPECT_TRUE(window.Empty());
+
+  // Add a first sample.
+  int t0_sample = 1;
+  base::TimeTicks t0_timestamp = tick_clock->NowTicks();
+
+  EXPECT_CALL(window, OnSampleAdded(t0_sample)).Times(1);
+  window.OnSample(t0_sample);
+  ::testing::Mock::VerifyAndClear(&window);
+
+  // decltype is used here to avoid having to expose the internal datatype used
+  // to represent this window.
+  EXPECT_THAT(window.observations_for_testing(),
+              ::testing::ContainerEq(ObservationContainerType{
+                  {t0_timestamp, t0_sample},
+              }));
+
+  // Fast forward by the length of the observation window, no sample should be
+  // removed as all samples have an age that doesn't exceed the window length.
+  scoped_task_environment.FastForwardBy(kDefaultWindowLength);
+
+  int t1_sample = 2;
+  base::TimeTicks t1_timestamp = tick_clock->NowTicks();
+
+  EXPECT_CALL(window, OnSampleAdded(t1_sample)).Times(1);
+  window.OnSample(t1_sample);
+  ::testing::Mock::VerifyAndClear(&window);
+
+  EXPECT_THAT(window.observations_for_testing(),
+              ::testing::ContainerEq(ObservationContainerType{
+                  {t0_timestamp, t0_sample},
+                  {t1_timestamp, t1_sample},
+              }));
+
+  // Fast forward by one second, the first sample should be removed the next
+  // time a sample gets added as its age exceed the length of the observation
+  // window.
+  scoped_task_environment.FastForwardBy(base::TimeDelta::FromSeconds(1));
+
+  int t2_sample = 3;
+  base::TimeTicks t2_timestamp = tick_clock->NowTicks();
+
+  EXPECT_CALL(window, OnSampleAdded(t2_sample)).Times(1);
+  EXPECT_CALL(window, OnSampleRemoved(t0_sample)).Times(1);
+  window.OnSample(t2_sample);
+  ::testing::Mock::VerifyAndClear(&window);
+
+  EXPECT_THAT(window.observations_for_testing(),
+              ::testing::ContainerEq(ObservationContainerType{
+                  {t1_timestamp, t1_sample},
+                  {t2_timestamp, t2_sample},
+              }));
+}
+
+}  // namespace memory
diff --git a/chrome/browser/performance_monitor/system_monitor.cc b/chrome/browser/performance_monitor/system_monitor.cc
index 1c3d0a5..6a5eb499 100644
--- a/chrome/browser/performance_monitor/system_monitor.cc
+++ b/chrome/browser/performance_monitor/system_monitor.cc
@@ -7,10 +7,12 @@
 #include <algorithm>
 #include <utility>
 
+#include "base/feature_list.h"
 #include "base/memory/ptr_util.h"
 #include "base/task/post_task.h"
 #include "base/task_runner_util.h"
 #include "build/build_config.h"
+#include "chrome/browser/performance_monitor/system_monitor_metrics_logger.h"
 
 #if defined(OS_WIN)
 #include "chrome/browser/performance_monitor/metric_evaluator_helper_win.h"
@@ -32,6 +34,9 @@
 constexpr base::TimeDelta kDefaultRefreshInterval =
     base::TimeDelta::FromSeconds(2);
 
+const base::Feature kSystemMonitorMetricLogger{
+    "SystemMonitorMetricLogger", base::FEATURE_DISABLED_BY_DEFAULT};
+
 std::unique_ptr<MetricEvaluatorsHelper> CreateMetricEvaluatorsHelper() {
 #if defined(OS_WIN)
   MetricEvaluatorsHelper* helper = new MetricEvaluatorsHelperWin();
@@ -57,6 +62,11 @@
       weak_factory_(this) {
   DCHECK(!g_system_metrics_monitor);
   g_system_metrics_monitor = this;
+
+  if (base::FeatureList::IsEnabled(kSystemMonitorMetricLogger)) {
+    // This has to be created after initializing |g_system_metrics_monitor|.
+    metrics_logger_ = std::make_unique<SystemMonitorMetricsLogger>();
+  }
 }
 
 SystemMonitor::~SystemMonitor() {
diff --git a/chrome/browser/performance_monitor/system_monitor.h b/chrome/browser/performance_monitor/system_monitor.h
index 6bb002a1..92a3fcf 100644
--- a/chrome/browser/performance_monitor/system_monitor.h
+++ b/chrome/browser/performance_monitor/system_monitor.h
@@ -23,6 +23,7 @@
 namespace performance_monitor {
 
 class MetricEvaluatorsHelper;
+class SystemMonitorMetricsLogger;
 
 // Monitors various various system metrics such as free memory, disk idle time,
 // etc.
@@ -283,6 +284,9 @@
   // |MetricEvaluator::Type|.
   MetricMetadataArray metric_evaluators_metadata_;
 
+  // The logger responsible of logging the system metrics.
+  std::unique_ptr<SystemMonitorMetricsLogger> metrics_logger_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   base::WeakPtrFactory<SystemMonitor> weak_factory_;
diff --git a/chrome/browser/performance_monitor/system_monitor_metrics_logger.cc b/chrome/browser/performance_monitor/system_monitor_metrics_logger.cc
new file mode 100644
index 0000000..c72352e
--- /dev/null
+++ b/chrome/browser/performance_monitor/system_monitor_metrics_logger.cc
@@ -0,0 +1,40 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/performance_monitor/system_monitor_metrics_logger.h"
+
+#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
+#include "build/build_config.h"
+
+namespace performance_monitor {
+
+SystemMonitorMetricsLogger::SystemMonitorMetricsLogger() {
+  // These metrics are only available on Windows for now.
+#if defined(OS_WIN)
+  if (auto* system_monitor = SystemMonitor::Get()) {
+    system_monitor->AddOrUpdateObserver(
+        this, {
+                  .free_phys_memory_mb_frequency =
+                      SystemMonitor::SamplingFrequency::kDefaultFrequency,
+                  .disk_idle_time_percent_frequency =
+                      SystemMonitor::SamplingFrequency::kDefaultFrequency,
+              });
+  }
+#endif
+}
+
+void SystemMonitorMetricsLogger::OnFreePhysicalMemoryMbSample(
+    int free_phys_memory_mb) {
+  UMA_HISTOGRAM_COUNTS_1M("PerformanceMonitor.SystemMonitor.FreePhysMemory",
+                          free_phys_memory_mb);
+}
+
+void SystemMonitorMetricsLogger::OnDiskIdleTimePercent(
+    float disk_idle_time_percent) {
+  UMA_HISTOGRAM_COUNTS_100("PerformanceMonitor.SystemMonitor.DiskIdleTime",
+                           disk_idle_time_percent * 100);
+}
+
+}  // namespace performance_monitor
diff --git a/chrome/browser/performance_monitor/system_monitor_metrics_logger.h b/chrome/browser/performance_monitor/system_monitor_metrics_logger.h
new file mode 100644
index 0000000..3d7327e
--- /dev/null
+++ b/chrome/browser/performance_monitor/system_monitor_metrics_logger.h
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PERFORMANCE_MONITOR_SYSTEM_MONITOR_METRICS_LOGGER_H_
+#define CHROME_BROWSER_PERFORMANCE_MONITOR_SYSTEM_MONITOR_METRICS_LOGGER_H_
+
+#include "base/macros.h"
+#include "chrome/browser/performance_monitor/system_monitor.h"
+
+namespace performance_monitor {
+
+// Logger responsible of logging the metrics collected by SystemMonitor to
+// UMA. This class register itself as an observer of SystemMonitor on
+// construction.
+class SystemMonitorMetricsLogger : public SystemMonitor::SystemObserver {
+ public:
+  SystemMonitorMetricsLogger();
+  ~SystemMonitorMetricsLogger() override = default;
+
+ private:
+  // SystemMonitor::SystemObserver.
+  void OnFreePhysicalMemoryMbSample(int free_phys_memory_mb) override;
+  void OnDiskIdleTimePercent(float disk_idle_time_percent) override;
+
+  DISALLOW_ASSIGN(SystemMonitorMetricsLogger);
+};
+
+}  // namespace performance_monitor
+
+#endif  // CHROME_BROWSER_PERFORMANCE_MONITOR_SYSTEM_MONITOR_METRICS_LOGGER_H_
diff --git a/chrome/browser/performance_monitor/wmi_refresher.cc b/chrome/browser/performance_monitor/wmi_refresher.cc
index dd30a23..c60c001 100644
--- a/chrome/browser/performance_monitor/wmi_refresher.cc
+++ b/chrome/browser/performance_monitor/wmi_refresher.cc
@@ -10,6 +10,7 @@
 #include <limits>
 #include <vector>
 
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/threading/scoped_blocking_call.h"
 #include "base/timer/elapsed_timer.h"
@@ -99,17 +100,24 @@
   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                 base::BlockingType::MAY_BLOCK);
 
+  base::ElapsedTimer elapsed_timer;
+
   // This assumes that CoInitialize(Ex) has already been called on this thread.
   AssertComApartmentType(base::win::ComApartmentType::MTA);
 
+  base::ElapsedTimer elapsed_timer_create_connection;
   if (!base::win::CreateLocalWmiConnection(true /* set_blanket */,
                                            &wmi_services_)) {
     LOG(ERROR) << "Unable to create the local WMI connection";
     *res = InitStatus::kLocalWMIConnectionError;
     return;
   }
+  base::UmaHistogramTimes(
+      "Memory.Experimental.WMIRefresher.Init.CreateLocalWmiConnectionDuration",
+      elapsed_timer_create_connection.Elapsed());
 
   HRESULT hr = S_OK;
+  base::ElapsedTimer elapsed_timer_cocreate_instance;
   // Creates the WMI refresher interface.
   if (FAILED(hr = ::CoCreateInstance(CLSID_WbemRefresher, nullptr,
                                      CLSCTX_INPROC_SERVER,
@@ -118,6 +126,9 @@
     *res = InitStatus::kRefresherCreationError;
     return;
   }
+  base::UmaHistogramTimes(
+      "Memory.Experimental.WMIRefresher.Init.CoCreateInstanceDuration",
+      elapsed_timer_cocreate_instance.Elapsed());
 
   // Get the interface to configure the refresher.
   ComPtr<IWbemConfigureRefresher> wmi_refresher_config;
@@ -129,6 +140,7 @@
   }
 
   long wmi_refresher_enum_id = 0;
+  base::ElapsedTimer elapsed_timer_add_enum;
   // Add the enumerator for the disk performance data.
   hr = wmi_refresher_config->AddEnum(
       wmi_services_.Get(), L"Win32_PerfRawData_PerfDisk_PhysicalDisk", 0,
@@ -139,8 +151,16 @@
     *res = InitStatus::kRefresherAddEnumError;
     return;
   }
+  base::UmaHistogramTimes(
+      "Memory.Experimental.WMIRefresher.Init.AddEnumDuration",
+      elapsed_timer_add_enum.Elapsed());
+
   *res = InitStatus::kInitStatusOk;
 
+  base::UmaHistogramTimes(
+      "Memory.Experimental.WMIRefresher.InitializeDiskIdleTimeConfigDuration",
+      elapsed_timer.Elapsed());
+
   refresh_ready_ = true;
 }
 
diff --git a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
index 04d2782..a8209f3bd 100644
--- a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
@@ -237,12 +237,7 @@
   ~PolicyFetchClientObserver() override { client_->RemoveObserver(this); }
 
   void OnPolicyFetched(CloudPolicyClient* client) override {
-    // The policy is fetched, wait for the policy is validated and stored.
-    store_observer_ = std::make_unique<PolicyFetchStoreObserver>(
-        g_browser_process->browser_policy_connector()
-            ->machine_level_user_cloud_policy_manager()
-            ->store(),
-        std::move(quit_closure_));
+    std::move(quit_closure_).Run();
   }
 
   void OnRegistrationStateChanged(CloudPolicyClient* client) override {}
@@ -626,14 +621,7 @@
   DISALLOW_COPY_AND_ASSIGN(MachineLevelUserCloudPolicyPolicyFetchTest);
 };
 
-// Crashes on Win only.  http://crbug.com/939261
-#if defined(OS_WIN)
-#define MAYBE_Test DISABLED_Test
-#else
-#define MAYBE_Test Test
-#endif
-
-IN_PROC_BROWSER_TEST_P(MachineLevelUserCloudPolicyPolicyFetchTest, MAYBE_Test) {
+IN_PROC_BROWSER_TEST_P(MachineLevelUserCloudPolicyPolicyFetchTest, Test) {
   MachineLevelUserCloudPolicyManager* manager =
       g_browser_process->browser_policy_connector()
           ->machine_level_user_cloud_policy_manager();
@@ -641,8 +629,18 @@
   // If the policy hasn't been updated, wait for it.
   if (manager->core()->client()->last_policy_timestamp().is_null()) {
     base::RunLoop run_loop;
-    PolicyFetchClientObserver observer(manager->core()->client(),
-                                       run_loop.QuitClosure());
+    // Listen to store event which is fired after policy validation if token is
+    // valid. Otherwise listen to the client event because there is no store
+    // event.
+    std::unique_ptr<PolicyFetchClientObserver> client_observer;
+    std::unique_ptr<PolicyFetchStoreObserver> store_observer;
+    if (dm_token() == kInvalidDMToken) {
+      client_observer = std::make_unique<PolicyFetchClientObserver>(
+          manager->core()->client(), run_loop.QuitClosure());
+    } else {
+      store_observer = std::make_unique<PolicyFetchStoreObserver>(
+          manager->store(), run_loop.QuitClosure());
+    }
     g_browser_process->browser_policy_connector()
         ->device_management_service()
         ->ScheduleInitialization(0);
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 5133d3b..d6c4ed7 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -161,9 +161,6 @@
   { key::kWPADQuickCheckEnabled,
     prefs::kQuickCheckEnabled,
     base::Value::Type::BOOLEAN },
-  { key::kPacHttpsUrlStrippingEnabled,
-    prefs::kPacHttpsUrlStrippingEnabled,
-    base::Value::Type::BOOLEAN },
   { key::kQuicAllowed,
     prefs::kQuicAllowed,
     base::Value::Type::BOOLEAN },
@@ -791,8 +788,8 @@
   { key::kPrintPreviewUseSystemDefaultPrinter,
     prefs::kPrintPreviewUseSystemDefaultPrinter,
     base::Value::Type::BOOLEAN },
-  { key::kCloudPolicyOverridesMachinePolicy,
-    policy_prefs::kCloudPolicyOverridesMachinePolicy,
+  { key::kCloudPolicyOverridesPlatformPolicy,
+    policy_prefs::kCloudPolicyOverridesPlatformPolicy,
     base::Value::Type::BOOLEAN },
   { key::kCloudReportingEnabled,
     prefs::kCloudReportingEnabled,
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 1f57213..be291ab 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -1933,40 +1933,6 @@
   EXPECT_TRUE(IsWebGLEnabled(contents));
 }
 
-namespace {
-
-bool GetPacHttpsUrlStrippingEnabled() {
-  network::mojom::NetworkContextParamsPtr network_context_params =
-      g_browser_process->system_network_context_manager()
-          ->CreateDefaultNetworkContextParams();
-  return !network_context_params->dangerously_allow_pac_access_to_secure_urls;
-}
-
-}  // namespace
-
-// Verifies that stripping of https:// URLs before sending to PAC scripts can
-// be disabled via a policy. Also verifies that stripping is enabled by
-// default.
-IN_PROC_BROWSER_TEST_F(PolicyTest, DisablePacHttpsUrlStripping) {
-  // Stripping is enabled by default.
-  EXPECT_TRUE(g_browser_process->local_state()->GetBoolean(
-      prefs::kPacHttpsUrlStrippingEnabled));
-  EXPECT_TRUE(GetPacHttpsUrlStrippingEnabled());
-
-  // Disable it via a policy.
-  PolicyMap policies;
-  policies.Set(key::kPacHttpsUrlStrippingEnabled, POLICY_LEVEL_MANDATORY,
-               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::WrapUnique(new base::Value(false)), nullptr);
-  UpdateProviderPolicy(policies);
-  content::RunAllPendingInMessageLoop();
-
-  // It should now reflect as disabled.
-  EXPECT_FALSE(g_browser_process->local_state()->GetBoolean(
-      prefs::kPacHttpsUrlStrippingEnabled));
-  EXPECT_FALSE(GetPacHttpsUrlStrippingEnabled());
-}
-
 IN_PROC_BROWSER_TEST_F(PolicyTest, DeveloperToolsDisabledByLegacyPolicy) {
   // Verifies that access to the developer tools can be disabled by setting the
   // legacy DeveloperToolsDisabled policy.
diff --git a/chrome/browser/profiles/profile_attributes_storage_unittest.cc b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
index 39a598d1..4f1e004 100644
--- a/chrome/browser/profiles/profile_attributes_storage_unittest.cc
+++ b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
@@ -590,13 +590,9 @@
   EXPECT_EQ(base::ASCIIToUTF16("OtherNewName"), first_entry->GetName());
 }
 
-TEST_F(ProfileAttributesStorageTest,
-       DISABLED_ChooseAvatarIconIndexForNewProfile) {
-  size_t total_icon_count = profiles::GetDefaultAvatarIconCount();
-#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
-  size_t generic_icon_count = profiles::GetGenericAvatarIconCount();
-  ASSERT_LE(generic_icon_count, total_icon_count);
-#endif
+TEST_F(ProfileAttributesStorageTest, ChooseAvatarIconIndexForNewProfile) {
+  size_t total_icon_count = profiles::GetDefaultAvatarIconCount() -
+                            profiles::GetModernAvatarIconStartIndex();
 
   // Run ChooseAvatarIconIndexForNewProfile |num_iterations| times before using
   // the final |icon_index| to add a profile. Multiple checks are needed because
@@ -612,7 +608,7 @@
       icon_index = storage()->ChooseAvatarIconIndexForNewProfile();
       // Icon must not be used.
       ASSERT_EQ(0u, used_icon_indices.count(icon_index));
-      ASSERT_GT(total_icon_count, icon_index);
+      ASSERT_TRUE(profiles::IsModernAvatarIconIndex(icon_index));
     }
 
     used_icon_indices.insert(icon_index);
@@ -628,8 +624,8 @@
 
   for (int iter = 0; iter < num_iterations; ++iter) {
     // All icons are used up, expect any valid icon.
-    ASSERT_GT(total_icon_count,
-              storage()->ChooseAvatarIconIndexForNewProfile());
+    ASSERT_TRUE(profiles::IsModernAvatarIconIndex(
+        storage()->ChooseAvatarIconIndexForNewProfile()));
   }
 }
 
diff --git a/chrome/browser/profiles/profile_avatar_icon_util.cc b/chrome/browser/profiles/profile_avatar_icon_util.cc
index 8774926..e5d5f570 100644
--- a/chrome/browser/profiles/profile_avatar_icon_util.cc
+++ b/chrome/browser/profiles/profile_avatar_icon_util.cc
@@ -533,15 +533,19 @@
 
 size_t GetRandomAvatarIconIndex(
     const std::unordered_set<size_t>& used_icon_indices) {
-  int rand = base::RandInt(0, GetDefaultAvatarIconCount());
+  size_t interval_begin = GetModernAvatarIconStartIndex();
+  size_t interval_end = GetDefaultAvatarIconCount();
+  size_t interval_length = interval_end - interval_begin;
+
+  size_t random_offset = base::RandInt(0, interval_length - 1);
   // Find the next unused index.
-  for (size_t i = 0; i < GetDefaultAvatarIconCount(); ++i) {
-    size_t icon_index = (rand + i) % GetDefaultAvatarIconCount();
+  for (size_t i = 0; i < interval_length; ++i) {
+    size_t icon_index = interval_begin + (random_offset + i) % interval_length;
     if (used_icon_indices.count(icon_index) == 0u)
       return icon_index;
   }
   // All indices are used, so return a random one.
-  return rand;
+  return interval_begin + random_offset;
 }
 
 }  // namespace profiles
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index 4a5f2d8..6d4c76d5 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -355,10 +355,11 @@
     {99, -1, IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE},
     {100, -1, IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE_ONCE},
     {101, -1, IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS},
+    {102, -1, IDC_SEND_TO_MY_DEVICES},
     // Add new items here and use |enum_id| from the next line.
     // Also, add new items to RenderViewContextMenuItem enum in
     // tools/metrics/histograms/enums.xml.
-    {102, -1, 0},  // Must be the last. Increment |enum_id| when new IDC
+    {103, -1, 0},  // Must be the last. Increment |enum_id| when new IDC
                    // was added.
 };
 
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn
index 8cc35f5..be91a1c 100644
--- a/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//chrome/test/base/js2gtest.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 
 js_type_check("closure_compile") {
@@ -39,3 +40,26 @@
     "//ui/webui/resources/js:util",
   ]
 }
+
+js2gtest("login_unitjs_tests") {
+  # These could be unit tests, except they need a browser context in order
+  # to construct a DOMParser object - so they are webui tests.
+  test_type = "webui"
+  sources = [
+    "saml_password_attributes_test.unitjs",
+    "saml_timestamps_test.unitjs",
+  ]
+  gen_include_files = [
+    "saml_password_attributes.js",
+    "saml_timestamps.js",
+    "//ui/webui/resources/js/cr.js",
+  ]
+  defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+}
+
+source_set("browser_tests") {
+  testonly = true
+  deps = [
+    ":login_unitjs_tests",
+  ]
+}
diff --git a/chrome/browser/resources/chromeos/login/saml_password_attributes.js b/chrome/browser/resources/chromeos/login/saml_password_attributes.js
new file mode 100644
index 0000000..d17eaab
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/saml_password_attributes.js
@@ -0,0 +1,97 @@
+// 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.
+
+/**
+ * @fileoverview A utility for extracting password information from SAML
+ * authorization response. This requires that the SAML IDP administrator
+ * has correctly configured their domain to issue these attributes.
+ */
+
+cr.define('samlPasswordAttributes', function() {
+  'use strict';
+
+  /** @const @private {number} The shortest XML string that could be useful. */
+  const MIN_SANE_XML_LENGTH = 100;
+
+  /** @const @private {number} The max length that we are willing to parse. */
+  const MAX_SANE_XML_LENGTH = 50 * 1024;  // 50 KB
+
+  /** @const @private {string} Schema name for password modified timestamp. */
+  const PASSWORD_MODIFIED_TIMESTAMP_NAME =
+      'http://schemas.google.com/saml/2019/passwordmodifiedtimestamp';
+
+  /** @const @private {string} Schema name for password expiration timestamp. */
+  const PASSWORD_EXPIRATION_TIMESTAMP_NAME =
+      'http://schemas.google.com/saml/2019/passwordexpirationtimestamp';
+
+  /**
+   * Query selector for finding an element with tag AttributeValue that is a
+   * child of an element of tag Attribute with a certain Name attribute.
+   * @const @private {string}
+   */
+  const QUERY_SELECTOR_FORMAT = 'Attribute[Name="{0}"] > AttributeValue';
+
+  /** @const @private {string} Query selector for password modified time. */
+  const PASSWORD_MODIFIED_TIMESTAMP_SELECTOR =
+      QUERY_SELECTOR_FORMAT.replace('{0}', PASSWORD_MODIFIED_TIMESTAMP_NAME);
+
+  /** @const @private {string} Query selector for password expiration time. */
+  const PASSWORD_EXPIRATION_TIMESTAMP_SELECTOR =
+      QUERY_SELECTOR_FORMAT.replace('{0}', PASSWORD_EXPIRATION_TIMESTAMP_NAME);
+
+  /**
+   * Extract password information from the Attribute elements in the given SAML
+   * authorization response.
+   * @param {string} xmlStr The SAML response XML, as a string.
+   * @return {!PasswordAttributes} The password information extracted.
+   */
+  function readPasswordAttributes(xmlStr) {
+    if (xmlStr.length < MIN_SANE_XML_LENGTH ||
+        xmlStr.length > MAX_SANE_XML_LENGTH) {
+      return new PasswordAttributes(null, null);
+    }
+    const xmlDom = new DOMParser().parseFromString(xmlStr, 'text/xml');
+    if (!xmlDom) {
+      return new PasswordAttributes(null, null);
+    }
+
+    return new PasswordAttributes(
+        extractTimestampFromXml(xmlDom, PASSWORD_MODIFIED_TIMESTAMP_SELECTOR),
+        extractTimestampFromXml(xmlDom, PASSWORD_EXPIRATION_TIMESTAMP_SELECTOR)
+    );
+  }
+
+  /**
+   * Extracts a timestamp from the given XML DOM, using the given query selector
+   * to find it and using {@code samlTimestamps.decodeTimestamp} to decode it.
+   * @param {!XMLDocument} xmlDom The XML DOM.
+   * @param {string} querySelectorStr The query selector to find the timestamp.
+   * @return {?Date} The decoded timestamp (null if failed to extract).
+   */
+  function extractTimestampFromXml(xmlDom, querySelectorStr) {
+    const element = xmlDom.querySelector(querySelectorStr);
+    const valueText = element && element.textContent;
+    return valueText ? samlTimestamps.decodeTimestamp(valueText) : null;
+  }
+
+  /**
+   * Struct to hold password attributes.
+   * @export @final
+   */
+  class PasswordAttributes {
+    constructor(modifiedTimestamp, expirationTimestamp) {
+      /** @type {?Date} Password last-modified timestamp. */
+      this.modifiedTimestamp = modifiedTimestamp;
+
+      /** @type {?Date} Password expiration timestamp. */
+      this.expirationTimestamp = expirationTimestamp;
+    }
+  }
+
+  // Public functions:
+  return {
+    readPasswordAttributes: readPasswordAttributes,
+    PasswordAttributes: PasswordAttributes,
+  };
+});
diff --git a/chrome/browser/resources/chromeos/login/saml_password_attributes_test.unitjs b/chrome/browser/resources/chromeos/login/saml_password_attributes_test.unitjs
new file mode 100644
index 0000000..d03756f6
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/saml_password_attributes_test.unitjs
@@ -0,0 +1,83 @@
+// 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 {string} Path to source root. */
+const ROOT_PATH = '../../../../../';
+
+GEN_INCLUDE([
+    ROOT_PATH + 'ui/webui/resources/js/cr.js',
+    'saml_timestamps.js',
+    'saml_password_attributes.js',
+]);
+
+function SamlPasswordAttributesUnitTest() {}
+
+SamlPasswordAttributesUnitTest.prototype = {
+  __proto__: testing.Test.prototype,
+
+  // WebUI tests run accessibility checks by default, but unit tests don't.
+  // Ideally this would be a unit test, but unit tests can't use the DOMParser.
+  // WebUI tests can, so this is a WebUI test. But, this test has no UI to run
+  // accessibility checks on, so we turn this off manually.
+  runAccessibilityChecks: false,
+
+  /** @override */
+  testGenCppIncludes: function() {
+    GEN(`#include "chrome/test/base/ui_test_utils.h"`);
+  },
+
+  /** @override */
+  testGenPreamble: function() {
+    // Generates a preamble that calls InitializeTestData with the contents
+    // of chrome/test/data/chromeos/login/saml_with_password_attributes.xml
+    GEN(`
+  BrowsePreload(GURL("chrome://DummyURL"));
+  base::ScopedAllowBlockingForTesting allow_blocking;
+  std::string xml_test_data;
+  base::FilePath xml_path = ui_test_utils::GetTestFilePath(
+        base::FilePath(FILE_PATH_LITERAL("chromeos/login")),
+        base::FilePath(FILE_PATH_LITERAL("saml_with_password_attributes.xml")));
+  base::ReadFileToString(xml_path, &xml_test_data);
+  RunJavascriptFunction("initializeTestData", base::Value(xml_test_data));
+    `);
+  },
+};
+
+let XML_TEST_DATA;
+let XML_TEST_DATA_WITH_TIMESTAMPS_REMOVED;
+
+const initializeTestData = function(xml_test_data) {
+  XML_TEST_DATA = xml_test_data;
+  // Strips out the timestamps that are in the <AttributeValue> tags.
+  XML_TEST_DATA_WITH_TIMESTAMPS_REMOVED = XML_TEST_DATA.replace(
+      /<AttributeValue>[0-9]+/g,
+      '<AttributeValue>');
+};
+
+TEST_F('SamlPasswordAttributesUnitTest', 'ReadInvalid', function() {
+  // Make sure null is returned for empty input:
+  let result = samlPasswordAttributes.readPasswordAttributes('');
+  assertEquals(null, result.modifiedTimestamp);
+  assertEquals(null, result.expirationTimestamp);
+
+  // Make sure null is returned for random junk:
+  result = samlPasswordAttributes.readPasswordAttributes('<abc></abc>');
+  assertEquals(null, result.modifiedTimestamp);
+  assertEquals(null, result.expirationTimestamp);
+
+  // Make sure null is returned when the input is almost valid, but not quite:
+  result = samlPasswordAttributes.readPasswordAttributes(
+      XML_TEST_DATA_WITH_TIMESTAMPS_REMOVED);
+  assertEquals(null, result.modifiedTimestamp);
+  assertEquals(null, result.expirationTimestamp);
+});
+
+TEST_F('SamlPasswordAttributesUnitTest', 'ReadValid', function() {
+  const result = samlPasswordAttributes.readPasswordAttributes(XML_TEST_DATA);
+
+  assertEquals(Date.parse('2019-02-22T11:50:58.421Z'),
+               result.modifiedTimestamp.valueOf());
+  assertEquals(Date.parse('2019-03-06T11:50:58.421Z'),
+               result.expirationTimestamp.valueOf());
+});
diff --git a/chrome/browser/resources/chromeos/login/saml_timestamps.js b/chrome/browser/resources/chromeos/login/saml_timestamps.js
new file mode 100644
index 0000000..9987ad9
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/saml_timestamps.js
@@ -0,0 +1,138 @@
+// 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.
+
+/**
+ * @fileoverview A utility for decoding timestamps strings into JS Date objects.
+ * This is needed for showing the SAML password expiry notifications.
+ * Timestamps are allowed to be sent to us in a variety of formats, since SAML
+ * administrators may not have the ability to convert between formats at their
+ * end. This class doesn't need to be informed which format the timestamp is in,
+ * since the different allowed formats don't tend to overlap in practice.
+ *
+ * The supported formats are NTFS filetimes, Unix time (in seconds or ms),
+ * and ISO 8601.
+ */
+
+cr.define('samlTimestamps', function() {
+  'use strict';
+
+  /** @const @private {number} Maximum length of a valid timestamp. */
+  const MAX_SANE_LENGTH = 30;
+
+  /** @const @private {!Date} The earliest date considered sane. */
+  const MIN_SANE_DATE = new Date('1980-01-01 UTC');
+
+  /** @const @private {!Date} The latest date considered sane. */
+  const MAX_SANE_DATE = new Date('10000-01-01 UTC');
+
+  /** @const @private {!Date} Epoch for Windows NTFS FILETIME timestamps. */
+  const NTFS_EPOCH = new Date('1601-01-01 UTC');
+
+  /** @const @private {!RegExp} Pattern to match integers. */
+  const INTEGER_PATTERN = /^-?\d+$/;
+
+  /**
+   * Pattern to match ISO 8601 dates / times. Rejects other text-based timestamp
+   * formats (eg '01-02-03') since they cannot be parsed in a consistent way.
+   * @const @private {!RegExp}
+   */
+  const ISO_8601_PATTERN = /^\d\d\d\d-\d\d-\d\d(T|$)/;
+
+  /**
+   * Decode a timestamp string that is in one of the supported formats.
+   * @param {string} str A timestamp formatted as a string.
+   * @return {?Date} A valid decoded timestamp, or null.
+   */
+  function decodeTimestamp(str) {
+    str = str.trim();
+    if (str.length == 0 || str.length > MAX_SANE_LENGTH) {
+      return null;
+    }
+
+    if (INTEGER_PATTERN.test(str)) {
+      return decodeIntegerTimestamp(parseInt(str));
+    } else if (ISO_8601_PATTERN.test(str)) {
+      return decodeIso8601(str);
+    }
+    return null;
+  }
+
+  /**
+   * Decode a timestamp that is in one of the supported integer formats:
+   * NTFS filetime, Unix time (s), or Unix time (ms).
+   * @param {number} num An integer timestamp.
+   * @return {?Date} A valid decoded timestamp, or null.
+   */
+  function decodeIntegerTimestamp(num) {
+    // We don't ask which format integer timestamps are in, because we can guess
+    // confidently by choosing the decode function that gives a sane result.
+    let result;
+    for (let decodeFunc of [decodeNtfsFiletime,
+                            decodeUnixMilliseconds,
+                            decodeUnixSeconds]) {
+      result = decodeFunc(num);
+      if (result && result >= MIN_SANE_DATE && result <= MAX_SANE_DATE) {
+        return result;
+      }
+    }
+    // For dates that fall outside the sane range, we cannot guess which format
+    // was used, but at least we can tell if the result should be in the far
+    // past or the far future, and return a result that is roughly equivalent.
+    return result && result < MIN_SANE_DATE
+          ? new Date(MIN_SANE_DATE)   // Copy-before-return protects these two
+          : new Date(MAX_SANE_DATE);  // constants (since Date is mutable).
+  }
+
+  /**
+   * Decode a NTFS filetime timestamp with an epoch of year 1601.
+   * @param {number} hundredsOfNs Each tick measures 100 nanoseconds.
+   * @return {?Date}
+   */
+  function decodeNtfsFiletime(hundredsOfNs) {
+    return createValidDate(NTFS_EPOCH.valueOf() + (hundredsOfNs / 10000));
+  }
+
+  /**
+   * Decode a Unix timestamp which is counting milliseconds since 1970.
+   * @param {number} milliseconds
+   * @return {?Date}
+   */
+  function decodeUnixMilliseconds(milliseconds) {
+    return createValidDate(milliseconds);
+  }
+
+  /**
+   * Decode a Unix timestamp which is counting seconds since 1970.
+   * @param {number} seconds
+   * @return {?Date}
+   */
+  function decodeUnixSeconds(seconds) {
+    return createValidDate(seconds * 1000);
+  }
+
+  /**
+   * Decodes a timestamp string that is in ISO 8601 format.
+   * @param {string} str
+   * @return {?Date}
+   */
+  function decodeIso8601(str) {
+    // If no timezone is specified, appending 'Z' means we will parse as UTC.
+    // (If a timezone is already specified, appending 'Z' is simply invalid.)
+    // Using UTC as a default is predictable, using local time is unpredictable.
+    return createValidDate(str + 'Z') || createValidDate(str);
+  }
+
+  /**
+   * Constructs a date and returns it if it is valid, otherwise returns null.
+   * @param {*} arg Argument for constructing the date.
+   * @return {?Date} A valid date object, or null.
+   */
+  function createValidDate(arg) {
+    const date = new Date(arg);
+    return isNaN(date) ? null : date;
+  }
+
+  // Public functions:
+  return {decodeTimestamp: decodeTimestamp};
+});
diff --git a/chrome/browser/resources/chromeos/login/saml_timestamps_test.unitjs b/chrome/browser/resources/chromeos/login/saml_timestamps_test.unitjs
new file mode 100644
index 0000000..5d7d9b4
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/saml_timestamps_test.unitjs
@@ -0,0 +1,141 @@
+// 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 {string} Path to source root. */
+const ROOT_PATH = '../../../../../';
+
+GEN_INCLUDE([
+    ROOT_PATH + 'ui/webui/resources/js/cr.js',
+    'saml_timestamps.js',
+]);
+
+function SamlTimestampsUnitTest() {}
+
+SamlTimestampsUnitTest.prototype = {
+  __proto__: testing.Test.prototype,
+
+  browsePreload: DUMMY_URL,
+
+  // No need to run these checks - see comment in SamlPasswordAttributesTest.
+  runAccessibilityChecks: false,
+};
+
+const ROUNDTRIP_DATA = [
+  '1980-01-01',
+  '1990-02-12',
+  '2000-03-13',
+  '2010-04-14',
+  '2020-05-25',
+  '2050-06-26',
+  '2100-07-27',
+  '3000-08-30',
+  '9999-12-31',
+];
+
+const NTFS_EPOCH = new Date('1601-01-01 UTC');
+
+const assertDecodesAs = function(expectedStr, encodedStr) {
+  const expectedMs = Date.parse(expectedStr);
+  const decodedMs = samlTimestamps.decodeTimestamp(encodedStr).valueOf();
+  assertEquals(expectedMs, decodedMs,
+      'Expected "' + encodedStr + '" to be decoded as "' + expectedStr + '"');
+}
+
+const assertInvalid = function(encoded) {
+  assertEquals(null, samlTimestamps.decodeTimestamp(encoded),
+      'Expected that "' + encoded + '" would not decode since it is invalid');
+}
+
+TEST_F('SamlTimestampsUnitTest', 'DecodeValidExamples', function() {
+  assertDecodesAs('2004-09-16T00:00Z', '1095292800');      // Unix time (s)
+  assertDecodesAs('2004-09-16T00:00Z', '1095292800000');   // Unix time (ms)
+
+  assertDecodesAs('2015-08-30T00:00Z', '130853664000000000');  // NTFS filetime
+
+  // ISO 8601
+  assertDecodesAs('2020-06-04T00:00Z', '2020-06-04');
+  assertDecodesAs('2020-06-04T12:00Z', '2020-06-04T12:00');
+  assertDecodesAs('2020-06-04T18:00Z', '2020-06-04T18:00Z');
+});
+
+TEST_F('SamlTimestampsUnitTest', 'RoundtripAsNTFS', function() {
+  for (let data of ROUNDTRIP_DATA) {
+    const ntfsTicks = (Date.parse(data) - NTFS_EPOCH.valueOf()) * 10000;
+    assertDecodesAs(data, ntfsTicks.toString());
+  }
+});
+
+TEST_F('SamlTimestampsUnitTest', 'RoundtripAsUnixSeconds', function() {
+  for (let data of ROUNDTRIP_DATA) {
+    const unixSeconds = Date.parse(data) / 1000;
+    assertDecodesAs(data, unixSeconds.toString());
+  }
+});
+
+TEST_F('SamlTimestampsUnitTest', 'RoundtripAsUnixMilliseconds', function() {
+  for (let data of ROUNDTRIP_DATA) {
+    const unixMilliseconds = Date.parse(data);
+    assertDecodesAs(data, unixMilliseconds.toString());
+  }
+});
+
+TEST_F('SamlTimestampsUnitTest', 'RoundtripAsIso8601', function() {
+  for (let data of ROUNDTRIP_DATA) {
+    assertDecodesAs(data, data);
+  }
+});
+
+TEST_F('SamlTimestampsUnitTest', 'Iso8601Timezones', function() {
+  // No time specified decodes as midnight UTC
+  assertDecodesAs('2020-06-04T00:00Z', '2020-06-04');
+  // No timezone specified decodes as UTC
+  assertDecodesAs('2020-06-04T12:00Z', '2020-06-04T12:00');
+
+  // There are different ways of specifying UTC
+  assertDecodesAs('2020-06-04T18:00Z', '2020-06-04T18:00Z');
+  assertDecodesAs('2020-06-04T18:00Z', '2020-06-04T18:00+0000');
+  assertDecodesAs('2020-06-04T18:00Z', '2020-06-04T18:00+00:00');
+
+  // Other timezones can also be specified
+  assertDecodesAs('2020-06-04T11:00Z', '2020-06-04T12:00+0100');
+  assertDecodesAs('2020-06-04T11:00Z', '2020-06-04T12:00+01:00');
+  assertDecodesAs('2020-06-04T13:00Z', '2020-06-04T12:00-0100');
+  assertDecodesAs('2020-06-04T13:00Z', '2020-06-04T12:00-01:00');
+});
+
+TEST_F('SamlTimestampsUnitTest', 'DecodeSpecialIntegers', function() {
+  // Zero or -1 could mean 1970 or 1601 - we can't guarantee we will decode it
+  // to the exact right value, but we must make sure it means the distant past.
+  assertTrue(samlTimestamps.decodeTimestamp('0') < new Date('2000-01-01'));
+  assertTrue(samlTimestamps.decodeTimestamp('-1') < new Date('2000-01-01'));
+
+  // Max signed int32 (2^31 - 1). Should decode as the year 2038:
+  assertDecodesAs('2038-01-19T03:14:07Z', '2147483647');
+
+  // Max signed int64 (2^63 - 1). Should decode to sometime in the very distant
+  // future, but it doesn't matter exactly when:
+  assertTrue(
+      samlTimestamps.decodeTimestamp('9223372036854775807')
+      > new Date('3000-01-01'));
+});
+
+TEST_F('SamlTimestampsUnitTest', 'DecodeInvalid', function() {
+  // Try some junk:
+  assertInvalid('');
+  assertInvalid('abc');
+  assertInvalid('01-02');
+
+  // These look like dates, but are not ISO 8601 so are rejected.
+  // For dates that are not in ISO 8601, we can't reliably know what was meant.
+  assertInvalid('01-02-03');
+  assertInvalid('99-01-01');
+  assertInvalid('01-02-2003');
+  assertInvalid('2020.01.01');
+  assertInvalid('2020/01/01');
+  assertInvalid('01 January 2020');
+  assertInvalid('2020-31-01');        // Almost, but there's no 31st month.
+  assertInvalid('2020-02-01 02:15');  // Almost, but missing the T separator
+  // Almost, but timezone must be described explicitly as +100:
+  assertInvalid('2020-02-01T02:15 (Central European Time)');
+});
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.cc b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
index 60b13deb..b8b17b2 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_factory.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
@@ -59,7 +59,7 @@
 
   return std::make_unique<chromeos::ChromeOSOAuth2TokenServiceDelegate>(
       AccountTrackerServiceFactory::GetInstance()->GetForProfile(profile),
-      account_manager);
+      content::GetNetworkConnectionTracker(), account_manager);
 }
 #endif  // defined(OS_CHROMEOS)
 
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index d2d3f07..efc8fbbe 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -378,7 +378,7 @@
     if (active_) {
 #if !defined(OS_ANDROID)
       IdentityManagerFactory::GetForProfile(profile_)
-          ->LegacyLoadCredentialsForSupervisedUser(
+          ->DeprecatedLoadCredentialsForSupervisedUser(
               supervised_users::kSupervisedUserPseudoEmail);
 #else
       NOTREACHED();
diff --git a/chrome/browser/sync/sync_ui_util.h b/chrome/browser/sync/sync_ui_util.h
index aaa687a..33652d95 100644
--- a/chrome/browser/sync/sync_ui_util.h
+++ b/chrome/browser/sync/sync_ui_util.h
@@ -39,9 +39,6 @@
   NO_SYNC_ERROR,                     // No sync error.
   MANAGED_USER_UNRECOVERABLE_ERROR,  // Unrecoverable error for managed users.
   UNRECOVERABLE_ERROR,               // Unrecoverable error for regular users.
-  // TODO(crbug.com/911153): Remove this value. It is never returned, but some
-  // clients still check for it.
-  SUPERVISED_USER_AUTH_ERROR,  // Auth token error for supervised users.
   AUTH_ERROR,                  // Authentication error.
   UPGRADE_CLIENT_ERROR,        // Out-of-date client error.
   PASSPHRASE_ERROR,            // Sync passphrase error.
diff --git a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc
index 6c09d13..b61c1381 100644
--- a/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc
+++ b/chrome/browser/ui/views/policy/enterprise_startup_dialog_view.cc
@@ -133,9 +133,13 @@
   // On mac, we need to stop the modal message loop before returning the result
   // to the caller who controls its own run loop.
   StopModal();
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::BindOnce(std::move(callback_), was_accepted,
-                                can_show_browser_window_));
+  if (can_show_browser_window_) {
+    std::move(callback_).Run(was_accepted, can_show_browser_window_);
+  } else {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(std::move(callback_), was_accepted,
+                                  can_show_browser_window_));
+  }
 #else
   std::move(callback_).Run(was_accepted, can_show_browser_window_);
 #endif
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index 591fb24..33ae165 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -428,9 +428,6 @@
           ShowViewFromMode(profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN);
         }
         break;
-      case sync_ui_util::SUPERVISED_USER_AUTH_ERROR:
-        NOTREACHED();
-        break;
       case sync_ui_util::AUTH_ERROR:
         ShowViewFromMode(profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH);
         break;
@@ -661,7 +658,7 @@
 
   ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
 
-  if (error != sync_ui_util::SUPERVISED_USER_AUTH_ERROR && dice_enabled_)
+  if (dice_enabled_)
     return CreateDiceSyncErrorView(avatar_item, error, button_string_id);
 
   // Sets an overall horizontal layout.
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector_mac_browsertest.mm b/chrome/browser/ui/views/ssl_client_certificate_selector_mac_browsertest.mm
index 655c578..2f50ceda 100644
--- a/chrome/browser/ui/views/ssl_client_certificate_selector_mac_browsertest.mm
+++ b/chrome/browser/ui/views/ssl_client_certificate_selector_mac_browsertest.mm
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#import "base/mac/mac_util.h"
 #include "base/macros.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ssl/ssl_client_auth_metrics.h"
@@ -224,8 +223,7 @@
                                 ClientCertSelectionResult::kUserSelect, 1);
 
   // The test keys are RSA keys.
-  EXPECT_EQ(net::SSLPrivateKey::DefaultAlgorithmPreferences(
-                EVP_PKEY_RSA, base::mac::IsAtLeastOS10_13()),
+  EXPECT_EQ(net::SSLPrivateKey::DefaultAlgorithmPreferences(EVP_PKEY_RSA, true),
             results.key->GetAlgorithmPreferences());
   TestSSLPrivateKeyMatches(results.key.get(), pkcs8_key1_);
 }
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
index bbc9c6f..ccc6c46 100644
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
@@ -20,15 +20,12 @@
 #include "chrome/browser/ui/webui/print_preview/print_preview_utils.h"
 #include "components/cloud_devices/common/cloud_device_description.h"
 #include "components/cloud_devices/common/printer_description.h"
-#include "device/base/device_client.h"
-#include "device/usb/mojo/type_converters.h"
 #include "device/usb/public/mojom/device.mojom.h"
-#include "device/usb/usb_device.h"
-#include "device/usb/usb_service.h"
 #include "extensions/browser/api/device_permissions_manager.h"
 #include "extensions/browser/api/printer_provider/printer_provider_api.h"
 #include "extensions/browser/api/printer_provider/printer_provider_api_factory.h"
 #include "extensions/browser/api/printer_provider/printer_provider_print_job.h"
+#include "extensions/browser/api/usb/usb_device_manager.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/api/printer_provider/usb_printer_manifest_data.h"
 #include "extensions/common/permissions/permissions_data.h"
@@ -38,12 +35,12 @@
 #include "printing/print_job_constants.h"
 #include "printing/pwg_raster_settings.h"
 
-using device::UsbDevice;
 using extensions::DevicePermissionsManager;
 using extensions::DictionaryBuilder;
 using extensions::Extension;
 using extensions::ExtensionRegistry;
 using extensions::ListBuilder;
+using extensions::UsbDeviceManager;
 using extensions::UsbPrinterManifestData;
 
 namespace printing {
@@ -78,10 +75,11 @@
             extensions::APIPermission::kUsb);
 }
 
-std::string GenerateProvisionalUsbPrinterId(const Extension* extension,
-                                            const UsbDevice* device) {
+std::string GenerateProvisionalUsbPrinterId(
+    const Extension* extension,
+    const device::mojom::UsbDeviceInfo& device) {
   return base::StringPrintf("%s:%s:%s", kProvisionalUsbLabel,
-                            extension->id().c_str(), device->guid().c_str());
+                            extension->id().c_str(), device.guid.c_str());
 }
 
 bool ParseProvisionalUsbPrinterId(const std::string& printer_id,
@@ -140,9 +138,10 @@
   }
 
   if (extension_supports_usb_printers) {
-    device::UsbService* service = device::DeviceClient::Get()->GetUsbService();
     pending_enumeration_count_++;
-    service->GetDevices(
+    UsbDeviceManager* usb_manager = UsbDeviceManager::Get(profile_);
+    DCHECK(usb_manager);
+    usb_manager->GetDevices(
         base::Bind(&ExtensionPrinterHandler::OnUsbDevicesEnumerated,
                    weak_ptr_factory_.GetWeakPtr(), callback));
   }
@@ -215,8 +214,11 @@
     return;
   }
 
-  device::UsbService* service = device::DeviceClient::Get()->GetUsbService();
-  scoped_refptr<UsbDevice> device = service->GetDevice(device_guid);
+  UsbDeviceManager* usb_manager = UsbDeviceManager::Get(profile_);
+  DCHECK(usb_manager);
+
+  const device::mojom::UsbDeviceInfo* device =
+      usb_manager->GetDeviceInfo(device_guid);
   if (!device) {
     std::move(callback).Run(base::DictionaryValue());
     return;
@@ -224,12 +226,10 @@
 
   DevicePermissionsManager* permissions_manager =
       DevicePermissionsManager::Get(profile_);
-  auto device_info = device::mojom::UsbDeviceInfo::From(*device);
-  DCHECK(device_info);
-  permissions_manager->AllowUsbDevice(extension_id, *device_info);
+  permissions_manager->AllowUsbDevice(extension_id, *device);
 
   GetPrinterProviderAPI(profile_)->DispatchGetUsbPrinterInfoRequested(
-      extension_id, *device_info,
+      extension_id, *device,
       base::BindOnce(&ExtensionPrinterHandler::WrapGetPrinterInfoCallback,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
@@ -318,7 +318,7 @@
 
 void ExtensionPrinterHandler::OnUsbDevicesEnumerated(
     const AddedPrintersCallback& callback,
-    const std::vector<scoped_refptr<UsbDevice>>& devices) {
+    std::vector<device::mojom::UsbDeviceInfoPtr> devices) {
   ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
   DevicePermissionsManager* permissions_manager =
       DevicePermissionsManager::Get(profile_);
@@ -337,8 +337,8 @@
       if (manifest_data->SupportsDevice(*device)) {
         std::unique_ptr<extensions::UsbDevicePermission::CheckParam> param =
             extensions::UsbDevicePermission::CheckParam::ForUsbDevice(
-                extension.get(), device.get());
-        if (device_permissions->FindUsbDeviceEntry(device) ||
+                extension.get(), *device);
+        if (device_permissions->FindUsbDeviceEntry(*device) ||
             extension->permissions_data()->CheckAPIPermissionWithParam(
                 extensions::APIPermission::kUsbDevice, param.get())) {
           // Skip devices the extension already has permission to access.
@@ -347,13 +347,14 @@
 
         printer_list.Append(
             DictionaryBuilder()
-                .Set("id", GenerateProvisionalUsbPrinterId(extension.get(),
-                                                           device.get()))
+                .Set("id",
+                     GenerateProvisionalUsbPrinterId(extension.get(), *device))
                 .Set("name",
                      DevicePermissionsManager::GetPermissionMessage(
-                         device->vendor_id(), device->product_id(),
-                         device->manufacturer_string(),
-                         device->product_string(), base::string16(), false))
+                         device->vendor_id, device->product_id,
+                         device->manufacturer_name.value_or(base::string16()),
+                         device->product_name.value_or(base::string16()),
+                         base::string16(), false))
                 .Set("extensionId", extension->id())
                 .Set("extensionName", extension->name())
                 .Set("provisional", true)
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.h b/chrome/browser/ui/webui/print_preview/extension_printer_handler.h
index 6cceb78..2dacc08b3 100644
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.h
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.h
@@ -25,10 +25,6 @@
 class CloudDeviceDescription;
 }
 
-namespace device {
-class UsbDevice;
-}
-
 namespace gfx {
 class Size;
 }
@@ -98,7 +94,7 @@
 
   void OnUsbDevicesEnumerated(
       const AddedPrintersCallback& callback,
-      const std::vector<scoped_refptr<device::UsbDevice>>& devices);
+      std::vector<device::mojom::UsbDeviceInfoPtr> devices);
 
   Profile* const profile_;
   GetPrintersDoneCallback done_callback_;
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
index af526b3..ae0c900 100644
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
@@ -28,15 +28,13 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/version_info/version_info.h"
 #include "content/public/test/test_utils.h"
-#include "device/base/mock_device_client.h"
-#include "device/usb/mock_usb_device.h"
-#include "device/usb/mock_usb_service.h"
-#include "device/usb/mojo/type_converters.h"
+#include "device/usb/public/cpp/fake_usb_device_manager.h"
 #include "device/usb/public/mojom/device.mojom.h"
 #include "extensions/browser/api/device_permissions_manager.h"
 #include "extensions/browser/api/printer_provider/printer_provider_api.h"
 #include "extensions/browser/api/printer_provider/printer_provider_api_factory.h"
 #include "extensions/browser/api/printer_provider/printer_provider_print_job.h"
+#include "extensions/browser/api/usb/usb_device_manager.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/value_builder.h"
 #include "printing/pdf_render_settings.h"
@@ -46,8 +44,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/size.h"
 
-using device::MockUsbDevice;
-using device::MockUsbService;
+using device::mojom::UsbDeviceInfoPtr;
 using extensions::DictionaryBuilder;
 using extensions::Extension;
 using extensions::PrinterProviderAPI;
@@ -508,6 +505,13 @@
     pwg_raster_converter_ = pwg_raster_converter.get();
     extension_printer_handler_->SetPwgRasterConverterForTesting(
         std::move(pwg_raster_converter));
+
+    // Set fake USB device manager for extensions::UsbDeviceManager.
+    device::mojom::UsbDeviceManagerPtr usb_manager_ptr;
+    fake_usb_manager_.AddBinding(mojo::MakeRequest(&usb_manager_ptr));
+    extensions::UsbDeviceManager::Get(env_.profile())
+        ->SetDeviceManagerForTesting(std::move(usb_manager_ptr));
+    base::RunLoop().RunUntilIdle();
   }
 
  protected:
@@ -517,11 +521,7 @@
             ->GetForBrowserContext(env_.profile()));
   }
 
-  device::MockUsbService& usb_service() {
-    return *device_client_.usb_service();
-  }
-
-  device::MockDeviceClient device_client_;
+  device::FakeUsbDeviceManager fake_usb_manager_;
   TestExtensionEnvironment env_;
   std::unique_ptr<ExtensionPrinterHandler> extension_printer_handler_;
 
@@ -587,12 +587,11 @@
 }
 
 TEST_F(ExtensionPrinterHandlerTest, GetUsbPrinters) {
-  scoped_refptr<device::UsbDevice> device0 =
-      base::MakeRefCounted<MockUsbDevice>(0, 0, "Google", "USB Printer", "");
-  usb_service().AddDevice(device0);
-  scoped_refptr<device::UsbDevice> device1 =
-      base::MakeRefCounted<MockUsbDevice>(0, 1, "Google", "USB Printer", "");
-  usb_service().AddDevice(device1);
+  UsbDeviceInfoPtr device0 =
+      fake_usb_manager_.CreateAndAddDevice(0, 0, "Google", "USB Printer", "");
+  UsbDeviceInfoPtr device1 =
+      fake_usb_manager_.CreateAndAddDevice(0, 1, "Google", "USB Printer", "");
+  base::RunLoop().RunUntilIdle();
 
   const Extension* extension_1 =
       env_.MakeExtension(*base::test::ParseJsonDeprecated(kExtension1),
@@ -603,9 +602,7 @@
 
   extensions::DevicePermissionsManager* permissions_manager =
       extensions::DevicePermissionsManager::Get(env_.profile());
-  auto device_info_0 = device::mojom::UsbDeviceInfo::From(*device0);
-  DCHECK(device_info_0);
-  permissions_manager->AllowUsbDevice(extension_2->id(), *device_info_0);
+  permissions_manager->AllowUsbDevice(extension_2->id(), *device0);
 
   size_t call_count = 0;
   std::unique_ptr<base::ListValue> printers;
@@ -628,7 +625,7 @@
       DictionaryBuilder()
           .Set("id", base::StringPrintf("provisional-usb:%s:%s",
                                         extension_1->id().c_str(),
-                                        device0->guid().c_str()))
+                                        device0->guid.c_str()))
           .Set("name", "USB Printer")
           .Set("extensionName", "Provider 1")
           .Set("extensionId", extension_1->id())
@@ -638,7 +635,7 @@
       DictionaryBuilder()
           .Set("id", base::StringPrintf("provisional-usb:%s:%s",
                                         extension_2->id().c_str(),
-                                        device1->guid().c_str()))
+                                        device1->guid.c_str()))
           .Set("name", "USB Printer")
           .Set("extensionName", "Provider 2")
           .Set("extensionId", extension_2->id())
@@ -980,15 +977,15 @@
 }
 
 TEST_F(ExtensionPrinterHandlerTest, GrantUsbPrinterAccess) {
-  auto device =
-      base::MakeRefCounted<MockUsbDevice>(0, 0, "Google", "USB Printer", "");
-  usb_service().AddDevice(device);
+  UsbDeviceInfoPtr device =
+      fake_usb_manager_.CreateAndAddDevice(0, 0, "Google", "USB Printer", "");
+  base::RunLoop().RunUntilIdle();
 
   size_t call_count = 0;
   std::unique_ptr<base::DictionaryValue> printer_info;
 
   std::string printer_id = base::StringPrintf(
-      "provisional-usb:fake extension id:%s", device->guid().c_str());
+      "provisional-usb:fake extension id:%s", device->guid.c_str());
   extension_printer_handler_->StartGrantPrinterAccess(
       printer_id, base::Bind(&RecordPrinterInfo, &call_count, &printer_info));
 
@@ -1012,16 +1009,16 @@
 }
 
 TEST_F(ExtensionPrinterHandlerTest, GrantUsbPrinterAccess_Reset) {
-  auto device =
-      base::MakeRefCounted<MockUsbDevice>(0, 0, "Google", "USB Printer", "");
-  usb_service().AddDevice(device);
+  UsbDeviceInfoPtr device =
+      fake_usb_manager_.CreateAndAddDevice(0, 0, "Google", "USB Printer", "");
+  base::RunLoop().RunUntilIdle();
 
   size_t call_count = 0;
   std::unique_ptr<base::DictionaryValue> printer_info;
 
   extension_printer_handler_->StartGrantPrinterAccess(
       base::StringPrintf("provisional-usb:fake extension id:%s",
-                         device->guid().c_str()),
+                         device->guid.c_str()),
       base::Bind(&RecordPrinterInfo, &call_count, &printer_info));
 
   EXPECT_FALSE(printer_info.get());
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index eeeb1fa..2276729 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -620,8 +620,11 @@
     if (service && !sync_blocker_)
       sync_blocker_ = service->GetSetupInProgressHandle();
 
-    // TODO(treib): Should we also call SetSyncRequested(true) here? That's what
-    // happens in the non-Unity code path.
+    // Mark Sync as requested by the user. It might already be requested, but
+    // it's not e.g. if Sync was reset via the dashboard. This also pokes the
+    // SyncService to start up immediately, i.e. bypass deferred startup.
+    if (service)
+      service->GetUserSettings()->SetSyncRequested(true);
 
     GetLoginUIService()->SetLoginUI(this);
 
@@ -669,8 +672,8 @@
     // re-entrant call to early exit.
     sync_startup_tracker_ = std::make_unique<SyncStartupTracker>(service, this);
     // SetSyncRequested(true) does two things:
-    // 1) If DISABLE_REASON_USER_CHOICE is set (meaning that Sync was reset via
-    //    the dashboard), clears it.
+    // 1) As the name says, it marks Sync as requested by the user (it might not
+    //    be requested yet if Sync was reset via the dashboard).
     // 2) Pokes the sync service to start *immediately*, i.e. bypass deferred
     //    startup.
     // It's possible that both of these are already the case, i.e. the engine is
@@ -767,14 +770,9 @@
   auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_);
   DCHECK(identity_manager->HasPrimaryAccount());
 
-  CoreAccountInfo primary_account_info =
-      identity_manager->GetPrimaryAccountInfo();
-
-  identity_manager->GetAccountsMutator()->AddOrUpdateAccount(
-      primary_account_info.gaia, primary_account_info.email,
-      OAuth2TokenServiceDelegate::kInvalidRefreshToken,
-      primary_account_info.is_under_advanced_protection,
-      signin_metrics::SourceForRefreshTokenOperation::kSettings_PauseSync);
+  identity_manager->GetAccountsMutator()
+      ->InvalidateRefreshTokenForPrimaryAccount(
+          signin_metrics::SourceForRefreshTokenOperation::kSettings_PauseSync);
 }
 #endif
 
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
index a72cddae..e1d569f 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
@@ -102,13 +102,16 @@
 
 void SyncConfirmationHandler::HandleAccountImageRequest(
     const base::ListValue* args) {
-  AccountInfo account_info = identity_manager_->GetPrimaryAccountInfo();
+  base::Optional<AccountInfo> primary_account_info =
+      identity_manager_->FindExtendedAccountInfoForAccount(
+          identity_manager_->GetPrimaryAccountInfo());
 
   // Fire the "account-image-changed" listener from |SetUserImageURL()|.
   // Note: If the account info is not available yet in the
   // IdentityManager, i.e. account_info is empty, the listener will be
   // fired again through |OnAccountUpdated()|.
-  SetUserImageURL(account_info.picture_url);
+  if (primary_account_info)
+    SetUserImageURL(primary_account_info->picture_url);
 }
 
 void SyncConfirmationHandler::RecordConsent(const base::ListValue* args) {
@@ -222,18 +225,20 @@
   if (!browser_)
     return;
 
-  if (!identity_manager_->HasPrimaryAccount()) {
+  base::Optional<AccountInfo> primary_account_info =
+      identity_manager_->FindExtendedAccountInfoForAccount(
+          identity_manager_->GetPrimaryAccountInfo());
+  if (!primary_account_info) {
     // No account is signed in, so there is nothing to be displayed in the sync
     // confirmation dialog.
     return;
   }
-  AccountInfo account_info = identity_manager_->GetPrimaryAccountInfo();
 
-  if (!account_info.IsValid()) {
+  if (!primary_account_info->IsValid()) {
     SetUserImageURL(kNoPictureURLFound);
     identity_manager_->AddObserver(this);
   } else {
-    SetUserImageURL(account_info.picture_url);
+    SetUserImageURL(primary_account_info->picture_url);
   }
 
   signin::SetInitializedModalHeight(browser_, web_ui(), args);
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
index 3b94cf3..9f31e851 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
@@ -167,10 +167,14 @@
     ASSERT_TRUE(call_data.arg1()->GetAsString(&event));
     EXPECT_EQ("account-image-changed", event);
 
+    identity::IdentityManager* identity_manager =
+        IdentityManagerFactory::GetForProfile(profile());
+    base::Optional<AccountInfo> primary_account =
+        identity_manager->FindExtendedAccountInfoForAccount(
+            identity_manager->GetPrimaryAccountInfo());
+
     std::string original_picture_url =
-        IdentityManagerFactory::GetForProfile(profile())
-            ->GetPrimaryAccountInfo()
-            .picture_url;
+        primary_account ? primary_account->picture_url : std::string();
     std::string expected_picture_url =
         original_picture_url.empty()
             ? profiles::GetPlaceholderAvatarIconUrl()
@@ -235,10 +239,13 @@
   EXPECT_EQ("sync.confirmation.clearFocus",
             web_ui()->call_data()[1]->function_name());
 
+  identity::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(profile());
+  base::Optional<AccountInfo> primary_account_info =
+      identity_manager->FindExtendedAccountInfoForAccount(
+          identity_manager->GetPrimaryAccountInfo());
   std::string original_picture_url =
-      IdentityManagerFactory::GetForProfile(profile())
-          ->GetPrimaryAccountInfo()
-          .picture_url;
+      primary_account_info ? primary_account_info->picture_url : std::string();
   GURL picture_url_with_size = signin::GetAvatarImageURLWithOptions(
       GURL(original_picture_url), kExpectedProfileImageSize,
       false /* no_silhouette */);
@@ -298,10 +305,14 @@
   EXPECT_TRUE(
       web_ui()->call_data()[2]->arg1()->GetAsString(&passed_picture_url));
 
+  identity::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(profile());
+  base::Optional<AccountInfo> primary_account_info =
+      identity_manager->FindExtendedAccountInfoForAccount(
+          identity_manager->GetPrimaryAccountInfo());
+
   std::string original_picture_url =
-      IdentityManagerFactory::GetForProfile(profile())
-          ->GetPrimaryAccountInfo()
-          .picture_url;
+      primary_account_info ? primary_account_info->picture_url : std::string();
   GURL picture_url_with_size = signin::GetAvatarImageURLWithOptions(
       GURL(original_picture_url), kExpectedProfileImageSize,
       false /* no_silhouette */);
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
index 572e5cf4..9fac4278 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -66,9 +66,14 @@
 
     constexpr int kAccountPictureSize = 68;
     std::string custom_picture_url = profiles::GetPlaceholderAvatarIconUrl();
-    GURL account_picture_url(IdentityManagerFactory::GetForProfile(profile)
-                                 ->GetPrimaryAccountInfo()
-                                 .picture_url);
+    identity::IdentityManager* identity_manager =
+        IdentityManagerFactory::GetForProfile(profile);
+    base::Optional<AccountInfo> primary_account_info =
+        identity_manager->FindExtendedAccountInfoForAccount(
+            identity_manager->GetPrimaryAccountInfo());
+    GURL account_picture_url(primary_account_info
+                                 ? primary_account_info->picture_url
+                                 : std::string());
     if (account_picture_url.is_valid()) {
       custom_picture_url = signin::GetAvatarImageURLWithOptions(
                                account_picture_url, kAccountPictureSize,
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 856bb2d..091967c 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -2261,8 +2261,7 @@
 // (i.e. the path and query components of an https:// URL).
 //
 // This preference is not exposed in the UI, but is overridable using
-// a Policy (PacHttpsUrlStrippingEnabled), or using a commandline
-// flag --unsafe-pac-url.
+// a commandline flag --unsafe-pac-url.
 //
 // The ability to turn off this security feature is not intended to be
 // a long-lived feature, but rather an escape-hatch for enterprises
diff --git a/chrome/credential_provider/common/gcp_strings.cc b/chrome/credential_provider/common/gcp_strings.cc
index 1969142..3ff0891 100644
--- a/chrome/credential_provider/common/gcp_strings.cc
+++ b/chrome/credential_provider/common/gcp_strings.cc
@@ -45,6 +45,7 @@
     L"SOFTWARE\\Google\\Update\\ClientState\\" GCPW_UPDATE_CLIENT_GUID;
 const wchar_t kRegUpdaterClientsAppPath[] =
     L"SOFTWARE\\Google\\Update\\Clients\\" GCPW_UPDATE_CLIENT_GUID;
+const wchar_t kRegUsageStatsName[] = L"usagestats";
 
 // Chrome is being opened to show the credential provider logon page.  This
 // page is always shown in incognito mode.
diff --git a/chrome/credential_provider/common/gcp_strings.h b/chrome/credential_provider/common/gcp_strings.h
index d28e397..15357a5e 100644
--- a/chrome/credential_provider/common/gcp_strings.h
+++ b/chrome/credential_provider/common/gcp_strings.h
@@ -73,6 +73,7 @@
 // Google Update related registry paths.
 extern const wchar_t kRegUpdaterClientStateAppPath[];
 extern const wchar_t kRegUpdaterClientsAppPath[];
+extern const wchar_t kRegUsageStatsName[];
 
 // These are command line switches passed to chrome to start it as a process
 // used as a logon stub.
diff --git a/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc b/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc
index f787f25..bac94ef 100644
--- a/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc
+++ b/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc
@@ -78,8 +78,7 @@
 AssociatedUserValidatorTest ::~AssociatedUserValidatorTest() = default;
 
 void AssociatedUserValidatorTest::SetUp() {
-  ASSERT_NO_FATAL_FAILURE(
-      registry_override_.OverrideRegistry(HKEY_LOCAL_MACHINE));
+  InitializeRegistryOverrideForTesting(&registry_override_);
 }
 
 TEST_F(AssociatedUserValidatorTest, CleanupStaleUsers) {
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
index 6e2bc7a2..53122bb6 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
@@ -1156,11 +1156,7 @@
     // case where enrollment to Google MDM is required, the UI should be
     // blocked until the enrollment either succeeds or fails.  To perform this
     // CreateAndRunLogonStub() waits for WaitForLoginUI() to complete.
-    wchar_t mdm_url[256];
-    ULONG mdm_length = base::size(mdm_url);
-    hr = credential_provider::GetGlobalFlag(credential_provider::kRegMdmUrl,
-                                            mdm_url, &mdm_length);
-    if (SUCCEEDED(hr) && mdm_length > 0)
+    if (MdmEnrollmentEnabled())
       ::WaitForSingleObject(reinterpret_cast<HANDLE>(wait_thread), INFINITE);
 
     ::CloseHandle(reinterpret_cast<HANDLE>(wait_thread));
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
index f6d236d..5e09d53 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
@@ -10,7 +10,6 @@
 #include <tuple>
 
 #include "base/synchronization/waitable_event.h"
-#include "base/test/test_reg_util_win.h"
 #include "base/win/registry.h"
 #include "chrome/credential_provider/common/gcp_strings.h"
 #include "chrome/credential_provider/gaiacp/associated_user_validator.h"
@@ -53,8 +52,7 @@
 };
 
 void GcpCredentialProviderTest::SetUp() {
-  ASSERT_NO_FATAL_FAILURE(
-      registry_override_.OverrideRegistry(HKEY_LOCAL_MACHINE));
+  InitializeRegistryOverrideForTesting(&registry_override_);
 }
 
 TEST_F(GcpCredentialProviderTest, Basic) {
diff --git a/chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.cc b/chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.cc
index 8fde8e0..2d45d05 100644
--- a/chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.cc
+++ b/chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.cc
@@ -89,11 +89,20 @@
 }
 
 bool GetGCPWCollectStatsConsent() {
+  // This value is provided by Omaha during install based on how the installer
+  // is tagged. The installer is tagged based on the consent checkbox found
+  // on the download page.
+  //
+  // This value can also be changed after install by running the setup
+  // program with --enable-stats or --disable-stats.
+  //
+  // This consent is different from chrome's consent in that each products
+  // stores the consent in its own part of the registry.
   DWORD collect_stats = 0;
   base::win::RegKey key(HKEY_LOCAL_MACHINE,
                         credential_provider::kRegUpdaterClientStateAppPath,
                         KEY_QUERY_VALUE | KEY_WOW64_32KEY);
-  key.ReadValueDW(L"usagestats", &collect_stats);
+  key.ReadValueDW(kRegUsageStatsName, &collect_stats);
   return collect_stats == 1;
 }
 
diff --git a/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc b/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc
index 33828f5a..4e275105e 100644
--- a/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc
@@ -429,9 +429,7 @@
 TEST(Enroll, EnrollToGoogleMdmIfNeeded_NotEnabled) {
   // Make sure MDM is not enforced.
   registry_util::RegistryOverrideManager registry_override;
-  ASSERT_NO_FATAL_FAILURE(
-      registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE));
-  ASSERT_EQ(S_OK, SetGlobalFlagForTesting(kRegMdmUrl, L""));
+  InitializeRegistryOverrideForTesting(&registry_override);
 
   // EnrollToGoogleMdmIfNeeded() should be a noop.
   base::DictionaryValue properties;
@@ -443,9 +441,7 @@
 TEST(Enroll, EnrollToGoogleMdmIfNeeded_MissingArgs) {
   // Does not matter whether MDM is enforced or not.
   registry_util::RegistryOverrideManager registry_override;
-  ASSERT_NO_FATAL_FAILURE(
-      registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE));
-  ASSERT_EQ(S_OK, SetGlobalFlagForTesting(kRegMdmUrl, L""));
+  InitializeRegistryOverrideForTesting(&registry_override);
 
   // EnrollToGoogleMdmIfNeeded() should fail if email and/or id token are
   // not provided.
diff --git a/chrome/credential_provider/gaiacp/mdm_utils.cc b/chrome/credential_provider/gaiacp/mdm_utils.cc
index 9c09939..f84a589 100644
--- a/chrome/credential_provider/gaiacp/mdm_utils.cc
+++ b/chrome/credential_provider/gaiacp/mdm_utils.cc
@@ -64,8 +64,10 @@
   wchar_t mdm_url[256];
   ULONG length = base::size(mdm_url);
   HRESULT hr = GetGlobalFlag(kRegMdmUrl, mdm_url, &length);
+  if (FAILED(hr))
+    return L"https://deviceenrollmentforwindows.googleapis.com/v1/discovery";
 
-  return hr == S_OK ? mdm_url : base::string16();
+  return mdm_url;
 }
 
 bool IsEnrolledWithGoogleMdm(const base::string16& mdm_url) {
diff --git a/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc b/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc
index a767aa6..7bbd799 100644
--- a/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc
+++ b/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc
@@ -51,8 +51,7 @@
 };
 
 void GcpReauthCredentialTest::SetUp() {
-  ASSERT_NO_FATAL_FAILURE(
-      registry_override_.OverrideRegistry(HKEY_LOCAL_MACHINE));
+  InitializeRegistryOverrideForTesting(&registry_override_);
 }
 
 TEST_F(GcpReauthCredentialTest, SetOSUserInfoAndReauthEmail) {
diff --git a/chrome/credential_provider/setup/setup.cc b/chrome/credential_provider/setup/setup.cc
index 7560e73..e573ced 100644
--- a/chrome/credential_provider/setup/setup.cc
+++ b/chrome/credential_provider/setup/setup.cc
@@ -113,6 +113,13 @@
   base::win::RegisterInvalidParamHandler();
   base::win::SetupCRT(*base::CommandLine::ForCurrentProcess());
 
+  // If the program is being run to either enable or disable stats, do that
+  // and exit.
+  if (cmdline->HasSwitch(credential_provider::switches::kEnableStats) ||
+      cmdline->HasSwitch(credential_provider::switches::kDisableStats)) {
+    return credential_provider::EnableStatsCollection(*cmdline);
+  }
+
   base::FilePath gcp_setup_exe_path;
   hr = credential_provider::GetPathToDllFromHandle(hInstance,
                                                    &gcp_setup_exe_path);
diff --git a/chrome/credential_provider/setup/setup_lib.cc b/chrome/credential_provider/setup/setup_lib.cc
index 2e621a4..99446e3 100644
--- a/chrome/credential_provider/setup/setup_lib.cc
+++ b/chrome/credential_provider/setup/setup_lib.cc
@@ -21,12 +21,14 @@
 #include "base/stl_util.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/win/registry.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/win_util.h"
 #include "base/win/windows_version.h"
-#include "chrome/installer/util/delete_after_reboot_helper.h"
+#include "chrome/credential_provider/common/gcp_strings.h"
 #include "chrome/credential_provider/gaiacp/gcp_utils.h"
 #include "chrome/credential_provider/gaiacp/logging.h"
+#include "chrome/installer/util/delete_after_reboot_helper.h"
 
 namespace credential_provider {
 
@@ -182,6 +184,13 @@
 // is not present the assumption is to install GCP.
 const char kUninstall[] = "uninstall";
 
+// Command line arguments used to either enable or disable stats and crash
+// dump collection.  When either of these command line args is used setup
+// will perform the requested action and exit without trying to install or
+// uninstall anything.  Disable takes precedence over enable.
+const char kEnableStats[] = "enable-stats";
+const char kDisableStats[] = "disable-stats";
+
 }  // namespace switches
 
 HRESULT DoInstall(const base::FilePath& installer_path,
@@ -299,4 +308,27 @@
   *count = base::size(kFilenames);
 }
 
+int EnableStatsCollection(const base::CommandLine& cmdline) {
+  DCHECK(cmdline.HasSwitch(credential_provider::switches::kEnableStats) ||
+         cmdline.HasSwitch(credential_provider::switches::kDisableStats));
+
+  bool enable =
+      !cmdline.HasSwitch(credential_provider::switches::kDisableStats);
+
+  base::win::RegKey key;
+  LONG sts = key.Create(HKEY_LOCAL_MACHINE,
+                        credential_provider::kRegUpdaterClientStateAppPath,
+                        KEY_SET_VALUE | KEY_WOW64_32KEY);
+  if (sts != ERROR_SUCCESS) {
+    LOGFN(ERROR) << "Unable to open omaha key sts=" << sts;
+  } else {
+    sts =
+        key.WriteValue(credential_provider::kRegUsageStatsName, enable ? 1 : 0);
+    if (sts != ERROR_SUCCESS)
+      LOGFN(ERROR) << "Unable to write userstats value sts=" << sts;
+  }
+
+  return sts == ERROR_SUCCESS ? 0 : -1;
+}
+
 }  // namespace credential_provider
diff --git a/chrome/credential_provider/setup/setup_lib.h b/chrome/credential_provider/setup/setup_lib.h
index b578537..120cd34 100644
--- a/chrome/credential_provider/setup/setup_lib.h
+++ b/chrome/credential_provider/setup/setup_lib.h
@@ -10,6 +10,7 @@
 #include "base/win/windows_types.h"
 
 namespace base {
+class CommandLine;
 class FilePath;
 }  // namespace base
 
@@ -24,6 +25,8 @@
 extern const char kParentHandle[];
 extern const char kInstallPath[];
 extern const char kUninstall[];
+extern const char kEnableStats[];
+extern const char kDisableStats[];
 
 }  // namespace switches
 
@@ -51,6 +54,10 @@
 void GetInstalledFileBasenames(const base::FilePath::CharType* const** names,
                                size_t* count);
 
+// Enable or disable stats and crash report collection.  Returns 0 on success
+// and -1 on failure.
+int EnableStatsCollection(const base::CommandLine& cmdline);
+
 }  // namespace credential_provider
 
 #endif  // CHROME_CREDENTIAL_PROVIDER_SETUP_SETUP_LIB_H_
diff --git a/chrome/credential_provider/test/gcp_fakes.cc b/chrome/credential_provider/test/gcp_fakes.cc
index ff1b857d..cdd5799 100644
--- a/chrome/credential_provider/test/gcp_fakes.cc
+++ b/chrome/credential_provider/test/gcp_fakes.cc
@@ -22,6 +22,7 @@
 #include "base/win/scoped_process_information.h"
 #include "chrome/credential_provider/common/gcp_strings.h"
 #include "chrome/credential_provider/gaiacp/logging.h"
+#include "chrome/credential_provider/gaiacp/mdm_utils.h"
 #include "chrome/credential_provider/gaiacp/reg_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -42,6 +43,18 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+void InitializeRegistryOverrideForTesting(
+    registry_util::RegistryOverrideManager* registry_override) {
+  ASSERT_NO_FATAL_FAILURE(
+      registry_override->OverrideRegistry(HKEY_LOCAL_MACHINE));
+  base::win::RegKey key;
+  ASSERT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_LOCAL_MACHINE, kGcpRootKeyName, KEY_WRITE));
+  ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(kRegMdmUrl, L""));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 FakeOSProcessManager::FakeOSProcessManager()
     : original_manager_(*GetInstanceStorage()) {
   *GetInstanceStorage() = this;
diff --git a/chrome/credential_provider/test/gcp_fakes.h b/chrome/credential_provider/test/gcp_fakes.h
index 9b437af..0209cc6 100644
--- a/chrome/credential_provider/test/gcp_fakes.h
+++ b/chrome/credential_provider/test/gcp_fakes.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/strings/string16.h"
+#include "base/test/test_reg_util_win.h"
 #include "base/win/scoped_handle.h"
 #include "chrome/credential_provider/gaiacp/associated_user_validator.h"
 #include "chrome/credential_provider/gaiacp/internet_availability_checker.h"
@@ -26,6 +27,9 @@
 
 namespace credential_provider {
 
+void InitializeRegistryOverrideForTesting(
+    registry_util::RegistryOverrideManager* registry_override);
+
 ///////////////////////////////////////////////////////////////////////////////
 
 class FakeOSProcessManager : public OSProcessManager {
diff --git a/chrome/credential_provider/test/gcp_setup_unittests.cc b/chrome/credential_provider/test/gcp_setup_unittests.cc
index db2bec3..f5c6604 100644
--- a/chrome/credential_provider/test/gcp_setup_unittests.cc
+++ b/chrome/credential_provider/test/gcp_setup_unittests.cc
@@ -12,6 +12,7 @@
 #include <memory>
 
 #include "base/base_paths.h"
+#include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/environment.h"
 #include "base/file_version_info.h"
@@ -412,6 +413,73 @@
       fake_scoped_lsa_policy_factory()->private_data()[kLsaKeyGaiaUsername]);
 }
 
+TEST_F(GcpSetupTest, EnableStats) {
+  // Make sure usagestats does not exist.
+  base::win::RegKey key;
+  EXPECT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_LOCAL_MACHINE,
+                       credential_provider::kRegUpdaterClientStateAppPath,
+                       KEY_ALL_ACCESS | KEY_WOW64_32KEY));
+  DWORD value;
+  EXPECT_NE(ERROR_SUCCESS,
+            key.ReadValueDW(credential_provider::kRegUsageStatsName, &value));
+
+  // Enable stats.
+  base::CommandLine cmdline(base::CommandLine::NO_PROGRAM);
+  cmdline.AppendSwitch(credential_provider::switches::kEnableStats);
+  EXPECT_EQ(0, EnableStatsCollection(cmdline));
+
+  // Stats should be enabled.
+  EXPECT_EQ(ERROR_SUCCESS,
+            key.ReadValueDW(credential_provider::kRegUsageStatsName, &value));
+  EXPECT_EQ(1u, value);
+}
+
+TEST_F(GcpSetupTest, DisableStats) {
+  // Make sure usagestats does not exist.
+  base::win::RegKey key;
+  EXPECT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_LOCAL_MACHINE,
+                       credential_provider::kRegUpdaterClientStateAppPath,
+                       KEY_ALL_ACCESS | KEY_WOW64_32KEY));
+  DWORD value;
+  EXPECT_NE(ERROR_SUCCESS,
+            key.ReadValueDW(credential_provider::kRegUsageStatsName, &value));
+
+  // Disable stats.
+  base::CommandLine cmdline(base::CommandLine::NO_PROGRAM);
+  cmdline.AppendSwitch(credential_provider::switches::kDisableStats);
+  EXPECT_EQ(0, EnableStatsCollection(cmdline));
+
+  // Stats should be disabled.
+  EXPECT_EQ(ERROR_SUCCESS,
+            key.ReadValueDW(credential_provider::kRegUsageStatsName, &value));
+  EXPECT_EQ(0u, value);
+}
+
+TEST_F(GcpSetupTest, EnableDisableStats) {
+  // Make sure usagestats does not exist.
+  base::win::RegKey key;
+  EXPECT_EQ(ERROR_SUCCESS,
+            key.Create(HKEY_LOCAL_MACHINE,
+                       credential_provider::kRegUpdaterClientStateAppPath,
+                       KEY_ALL_ACCESS | KEY_WOW64_32KEY));
+  DWORD value;
+  EXPECT_NE(ERROR_SUCCESS,
+            key.ReadValueDW(credential_provider::kRegUsageStatsName, &value));
+
+  // Enable and disable stats.
+  base::CommandLine cmdline(base::CommandLine::NO_PROGRAM);
+  cmdline.AppendSwitch(credential_provider::switches::kEnableStats);
+  cmdline.AppendSwitch(credential_provider::switches::kDisableStats);
+  EXPECT_EQ(0, EnableStatsCollection(cmdline));
+
+  // Stats should be disabled.
+  EXPECT_EQ(ERROR_SUCCESS,
+            key.ReadValueDW(credential_provider::kRegUsageStatsName, &value));
+  EXPECT_EQ(0u, value);
+}
+
 // This test checks the expect success / failure of DLL registration when
 // a gaia user already exists
 // Parameters:
diff --git a/chrome/credential_provider/test/gls_runner_test_base.cc b/chrome/credential_provider/test/gls_runner_test_base.cc
index e7f564a..6cc03139 100644
--- a/chrome/credential_provider/test/gls_runner_test_base.cc
+++ b/chrome/credential_provider/test/gls_runner_test_base.cc
@@ -15,8 +15,7 @@
 void GlsRunnerTestBase::SetUp() {
   // Make sure not to read random GCPW settings from the machine that is running
   // the tests.
-  ASSERT_NO_FATAL_FAILURE(
-      registry_override_.OverrideRegistry(HKEY_LOCAL_MACHINE));
+  InitializeRegistryOverrideForTesting(&registry_override_);
 }
 
 }  // namespace testing
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 6450d4c..4c08f50 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -536,6 +536,7 @@
       "//chrome/browser/chromeos:test_support",
       "//chrome/browser/media/router:test_support",
       "//chrome/browser/resources/chromeos/chromevox:browser_tests",
+      "//chrome/browser/resources/chromeos/login:browser_tests",
       "//chrome/browser/resources/chromeos/select_to_speak:browser_tests",
       "//chrome/browser/resources/chromeos/switch_access:browser_tests",
       "//chrome/services/file_util/public/cpp:browser_tests",
@@ -1809,6 +1810,7 @@
         "../browser/chromeos/login/demo_mode/demo_setup_test_utils.cc",
         "../browser/chromeos/login/demo_mode/demo_setup_test_utils.h",
         "../browser/chromeos/login/enable_debugging_browsertest.cc",
+        "../browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc",
         "../browser/chromeos/login/enrollment/enrollment_screen_browsertest.cc",
         "../browser/chromeos/login/enrollment/hands_off_enrollment_browsertest.cc",
         "../browser/chromeos/login/enrollment/mock_auto_enrollment_check_screen.cc",
@@ -3298,6 +3300,7 @@
       "../browser/media_galleries/media_galleries_preferences_unittest.cc",
       "../browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc",
       "../browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc",
+      "../browser/memory/memory_pressure_monitor_utils_unittest.cc",
       "../browser/memory/swap_thrashing_monitor_delegate_win_unittest.cc",
       "../browser/metrics/desktop_session_duration/desktop_session_duration_tracker_unittest.cc",
       "../browser/metrics/tab_stats_data_store_unittest.cc",
diff --git a/chrome/test/base/js2gtest.gni b/chrome/test/base/js2gtest.gni
index 197bf0b..412f9ecb 100644
--- a/chrome/test/base/js2gtest.gni
+++ b/chrome/test/base/js2gtest.gni
@@ -135,6 +135,9 @@
     if (defined(invoker.deps)) {
       deps += invoker.deps
     }
+    if (defined(invoker.gen_include_files)) {
+      data = invoker.gen_include_files
+    }
     if (defined(invoker.extra_js_files)) {
       data_deps = [
         ":$copy_target_name",
diff --git a/chrome/test/data/chromeos/login/saml_with_password_attributes.xml b/chrome/test/data/chromeos/login/saml_with_password_attributes.xml
new file mode 100644
index 0000000..06cd955
--- /dev/null
+++ b/chrome/test/data/chromeos/login/saml_with_password_attributes.xml
@@ -0,0 +1,64 @@
+<samlp:Response ID="_b8afb9ac-43e8-48f4-9fed-3140e2341c49"
+                Version="2.0"
+                IssueInstant="2019-02-22T11:51:03.561Z"
+                Destination="https://www.google.com/a/example.com/acs"
+                Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
+                InResponseTo="cppcinkhfplikcngllgnbodnjlbeolappkepmcik"
+                xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
+  <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://samlserver.example.com/adfs/services/trust</Issuer>
+  <samlp:Status>
+    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
+  </samlp:Status>
+  <Assertion ID="_573cbf2c-2f08-428c-8cbf-2f4d6307baaf"
+             IssueInstant="2019-02-22T11:51:03.546Z"
+             Version="2.0"
+             xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
+    <Issuer>http://example.com/adfs/services/trust</Issuer>
+    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+      <ds:SignedInfo>
+        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+        <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
+        <ds:Reference URI="#_573cbf2c-2f08-428c-8cbf-2f4d6307baaf">
+          <ds:Transforms>
+            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
+            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+          </ds:Transforms>
+          <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+          <ds:DigestValue>2OU6vFwZC7WtR4pZDzLw/H+GIoOWJXQqZkWRz4gtSwk=</ds:DigestValue>
+        </ds:Reference>
+      </ds:SignedInfo>
+      <ds:SignatureValue>Xl0SOKkQTjhzJOS9g7os+bit6i8P/RD0sfXI7dNzhaIF+xj49Rc3v5qJR92+xIFxp05iDhZDCv3CM/IjFvn9M3FDCQYYloV09qmpbRebdkR/npB6wir377gBK8K1Mnafv87A2QfxnpezIQhlyE4fj9LoRVeExNe44Ly2ZqWtXUtmXzX6TaDsWCIxlsuG1PFPLiw7RKTYURmZDNEo9FoDjl8ZQT2zPN8uebgAkQXAk9BbKqnUmrlEs/jyRe1rHNJhe10XmbytbDK5TLOW8q1fCxzrL/rd3EdrIUtJZkmE29QMqmtzK8oOxMaxOL+Q4Tx9F/x21yJW4KCxotcP8PnhIg==</ds:SignatureValue>
+      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
+        <ds:X509Data>
+         <ds:X509Certificate>BREZTIFNpZ25pbmcgLSBzYW1sc2VydmVyLmNocm9tYWQtc2FtbC5jb20wHhcNMTkwMjAxMjIyNTQ1WhcNMjAwMjAxMjIyNTQ1WjA1MTMwMQYDVQQDEypMIIC8jCCAdqgAwIBAgIQMp5bjJKzcYlMEl0zoHjYGzANBgkqhkiG9w0BAQsFADA1MTMwMQYDVQQDEypBREZTIFNpZ25pbmcgLSBzYW1sc2VydmVyLmNocm9tYWQtc2FtbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCjIEgYd6sirn0dJ9CzifbFDk+4FK63Uzy1DNkhDh56W8VJCOIZ3qsgPziB44GBa4kK7158XB+G973+SGtZ1Lie/VjYkbpMFzNl98SeenFwr1iwT5b1SsaZsazzsx31J11B2ukbhC1RmdcUFbQU6G3O4AwrvWtkPcu04oYycFtin7XsQWgEpmXoJIeVTiHLkbjJoOeEAi0PbSjvzILOESJtY3p1WtCyDJgCjezvHpgFDBfx+HKUUEeUHywuz6Nonhp83VRj/SqXBC6Quq49NOSrKdttxpBYH+LGOXd+KVufIzBxwYII3voqREXj/ZUHckHlT0aD5Fs3nJTwBAGIETpfAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAkA6u7q1zLFcZeFf39nY5eVQCOCD7PtYaSmxc8UTVrhZl93sVuvBA5he5SXIWUBZB6TZ7Jx6iMzAqPlKmvQUAWYjB33JRq+umUn53wETrDfiSf2wPiLXL6jRB1+7dmUujSdioovD5lJF8dKU7Ja6Rezh8sy6hQggg0sUKZuafSXXWiWmoPCV8kwl+THSqHKt16MeJaIuFsOlrI+V4WFk6FSgdPBjaL0/BZhAZWUKdq8MjXiY8CWBdUF3PV8Q8zjbpRsu3E5XxEDeAcWoR6LKq1AhPqDrkqHA1S9o2rZedyOxBMQ3WAIIc5oXLmjaQnmrI/hyU4DGph53z23jyrkZ4w=</ds:X509Certificate>
+        </ds:X509Data>
+      </KeyInfo>
+    </ds:Signature>
+    <Subject>
+      <NameID>testuser@example.com</NameID>
+      <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+        <SubjectConfirmationData InResponseTo="cppcinkhfplikcngllgnbodnjlbeolappkepmcik"
+                                 NotOnOrAfter="2019-02-22T11:56:03.561Z"
+                                 Recipient="https://www.google.com/a/example.com/acs" />
+      </SubjectConfirmation>
+    </Subject>
+    <Conditions NotBefore="2019-02-22T11:51:03.546Z" NotOnOrAfter="2019-02-22T12:51:03.546Z">
+      <AudienceRestriction>
+        <Audience>google.com/a/example.com</Audience>
+      </AudienceRestriction>
+    </Conditions>
+    <AttributeStatement>
+      <Attribute Name="http://schemas.google.com/saml/2019/passwordmodifiedtimestamp">
+        <AttributeValue>131953098584212478</AttributeValue>
+      </Attribute>
+      <Attribute Name="http://schemas.google.com/saml/2019/passwordexpirationtimestamp">
+        <AttributeValue>131963466584212478</AttributeValue>
+      </Attribute>
+    </AttributeStatement>
+    <AuthnStatement AuthnInstant="2019-02-22T11:51:03.358Z" SessionIndex="_573cbf2c-2f08-428c-8cbf-2f4d6307baaf">
+      <AuthnContext>
+        <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
+      </AuthnContext>
+    </AuthnStatement>
+  </Assertion>
+</samlp:Response>
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 58e9911..67a7b1d 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2278,13 +2278,7 @@
   },
 
   "PacHttpsUrlStrippingEnabled": {
-    "os": ["win", "linux", "mac", "chromeos"],
-    "test_policy": { "PacHttpsUrlStrippingEnabled": true },
-    "pref_mappings": [
-      { "pref": "proxy.pac_https_url_stripping_enabled",
-        "local_state": true
-      }
-    ]
+    "note": "This policy has been removed, see https://crbug.com/939760."
   },
 
   "RegisteredProtocolHandlers": {
@@ -2452,13 +2446,7 @@
   },
 
   "SSLVersionMax": {
-    "os": ["win", "linux", "mac", "chromeos"],
-    "test_policy": { "SSLVersionMax": "tls1.2" },
-    "pref_mappings": [
-      { "pref": "ssl.version_max",
-        "local_state": true
-      }
-    ]
+     "note": "This policy has been removed, see https://crbug.com/939760."
   },
 
   "CertificateTransparencyEnforcementDisabledForUrls": {
@@ -3360,9 +3348,9 @@
     ]
   },
 
-  "CloudPolicyOverridesMachinePolicy": {
+  "CloudPolicyOverridesPlatformPolicy": {
     "os": ["win", "linux", "mac"],
-    "test_policy": { "CloudPolicyOverridesMachinePolicy": false },
+    "test_policy": { "CloudPolicyOverridesPlatformPolicy": false },
     "pref_mappings": [
       { "pref": "policy.cloud_override",
         "local_state": true
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index e34d073..50321a1c 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -250,6 +250,15 @@
       "//components/crash/content/app",
       "//components/crash/content/browser",
     ]
+
+    # TODO(crbug.com/933142): Fuchsia needs its own methods to bridge with heap
+    # profiling service
+    deps += [
+      "//components/heap_profiling",
+      "//components/services/heap_profiling",
+      "//components/services/heap_profiling/public/cpp",
+      "//components/services/heap_profiling/public/mojom",
+    ]
   }
 
   if (use_ozone) {
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS
index 70336de..ceb7f0fd4 100644
--- a/chromecast/browser/DEPS
+++ b/chromecast/browser/DEPS
@@ -12,12 +12,16 @@
   "+components/cdm/browser",
   "+components/crash",
   "+components/download/public/common",
+  "+components/heap_profiling",
   "+components/keyed_service",
   "+components/network_hints/browser",
   "+components/network_session_configurator/common",
   "+components/prefs",
   "+components/pref_registry",
   "+components/proxy_config",
+  "+components/services/heap_profiling/heap_profiling_service.h",
+  "+components/services/heap_profiling/public/mojom",
+  "+components/services/heap_profiling/public/cpp/settings.h",
   "+components/storage_monitor",
   "+components/user_prefs",
   "+components/variations/net",
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index 8143641..e0790f4f 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -8,6 +8,7 @@
 #include <string.h>
 
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/bind.h"
@@ -64,7 +65,6 @@
 #include "media/base/media_switches.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "ui/base/ui_base_switches.h"
-#include "ui/compositor/compositor_switches.h"
 #include "ui/gl/gl_switches.h"
 
 #if defined(OS_LINUX)
@@ -122,6 +122,12 @@
 #include "device/bluetooth/cast/bluetooth_adapter_cast.h"
 #endif  // !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
 
+#if !defined(OS_FUCHSIA)
+#include "base/bind_helpers.h"
+#include "components/heap_profiling/client_connection_manager.h"
+#include "components/heap_profiling/supervisor.h"
+#endif  // !defined(OS_FUCHSIA)
+
 namespace {
 
 #if !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
@@ -219,6 +225,18 @@
 
 #endif  // !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
 
+#if !defined(OS_FUCHSIA)
+
+std::unique_ptr<heap_profiling::ClientConnectionManager>
+CreateClientConnectionManager(
+    base::WeakPtr<heap_profiling::Controller> controller_weak_ptr,
+    heap_profiling::Mode mode) {
+  return std::make_unique<heap_profiling::ClientConnectionManager>(
+      std::move(controller_weak_ptr), mode);
+}
+
+#endif
+
 }  // namespace
 
 namespace chromecast {
@@ -670,5 +688,16 @@
 #endif  // !defined(OS_ANDROID)
 }
 
+void CastBrowserMainParts::ServiceManagerConnectionStarted(
+    content::ServiceManagerConnection* connection) {
+#if !defined(OS_FUCHSIA)
+  heap_profiling::Supervisor* supervisor =
+      heap_profiling::Supervisor::GetInstance();
+  supervisor->SetClientConnectionManagerConstructor(
+      &CreateClientConnectionManager);
+  supervisor->Start(connection, base::NullCallback());
+#endif  // !defined(OS_FUCHSIA)
+}
+
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromecast/browser/cast_browser_main_parts.h b/chromecast/browser/cast_browser_main_parts.h
index 662b5d4..4577385 100644
--- a/chromecast/browser/cast_browser_main_parts.h
+++ b/chromecast/browser/cast_browser_main_parts.h
@@ -82,6 +82,8 @@
   bool MainMessageLoopRun(int* result_code) override;
   void PostMainMessageLoopRun() override;
   void PostDestroyThreads() override;
+  void ServiceManagerConnectionStarted(
+      content::ServiceManagerConnection* connection) override;
 
  private:
   std::unique_ptr<CastBrowserProcess> cast_browser_process_;
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 63be8879..44392fa3 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -136,6 +136,12 @@
 #include "chromecast/external_mojo/broker_service/broker_service.h"
 #endif
 
+#if !defined(OS_FUCHSIA)
+#include "components/services/heap_profiling/heap_profiling_service.h"
+#include "components/services/heap_profiling/public/cpp/settings.h"
+#include "components/services/heap_profiling/public/mojom/constants.mojom.h"
+#endif  // !defined(OS_FUCHSIA)
+
 namespace chromecast {
 namespace shell {
 
@@ -1009,5 +1015,27 @@
   return chromecast::shell::GetUserAgent();
 }
 
+void CastContentBrowserClient::RegisterOutOfProcessServices(
+    OutOfProcessServiceMap* services) {
+#if !defined(OS_FUCHSIA)
+  if (!heap_profiling::IsInProcessModeEnabled()) {
+    services->emplace(
+        heap_profiling::mojom::kServiceName,
+        base::BindRepeating(&base::ASCIIToUTF16, "Profiling Service"));
+  }
+#endif  // !defined(OS_FUCHSIA)
+}
+
+void CastContentBrowserClient::RegisterIOThreadServiceHandlers(
+    content::ServiceManagerConnection* connection) {
+#if !defined(OS_FUCHSIA)
+  if (heap_profiling::IsInProcessModeEnabled()) {
+    connection->AddServiceRequestHandler(
+        heap_profiling::mojom::kServiceName,
+        heap_profiling::HeapProfilingService::GetServiceFactory());
+  }
+#endif  // !defined(OS_FUCHSIA)
+}
+
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index 1e1f5c26f..0ac977f0 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -216,6 +216,9 @@
       bool in_memory,
       const base::FilePath& relative_partition_path) override;
   std::string GetUserAgent() const override;
+  void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
+  void RegisterIOThreadServiceHandlers(
+      content::ServiceManagerConnection* connection) override;
   CastFeatureListCreator* GetCastFeatureListCreator() {
     return cast_feature_list_creator_;
   }
diff --git a/chromecast/browser/cast_http_user_agent_settings.h b/chromecast/browser/cast_http_user_agent_settings.h
index 97f9a6b2..47885941 100644
--- a/chromecast/browser/cast_http_user_agent_settings.h
+++ b/chromecast/browser/cast_http_user_agent_settings.h
@@ -9,7 +9,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "net/url_request/http_user_agent_settings.h"
+#include "net/base/http_user_agent_settings.h"
 
 namespace chromecast {
 namespace shell {
diff --git a/chromecast/browser/cast_overlay_manifests.cc b/chromecast/browser/cast_overlay_manifests.cc
index 3ab7d82..f0d4ddc 100644
--- a/chromecast/browser/cast_overlay_manifests.cc
+++ b/chromecast/browser/cast_overlay_manifests.cc
@@ -25,12 +25,24 @@
 #include "chromecast/internal/shell/browser/cast_content_renderer_internal_manifest_overlay.h"
 #endif
 
+#if !defined(OS_FUCHSIA)
+#include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h"
+#endif  // !defined(OS_FUCHSIA)
+
 namespace chromecast {
 namespace shell {
 
 const service_manager::Manifest& GetCastContentBrowserOverlayManifest() {
   static base::NoDestructor<service_manager::Manifest> manifest {
     service_manager::ManifestBuilder()
+#if !defined(OS_FUCHSIA)
+        .RequireCapability("heap_profiling", "heap_profiler")
+        .RequireCapability("heap_profiling", "profiling")
+        .RequireCapability("content_browser", "profiling_client")
+        .ExposeCapability("profiling_client",
+                          service_manager::Manifest::InterfaceList<
+                              heap_profiling::mojom::ProfilingClient>())
+#endif  // !defined(OS_FUCHSIA)
         .ExposeCapability("renderer",
                           service_manager::Manifest::InterfaceList<
                               chromecast::media::mojom::MediaCaps,
@@ -50,6 +62,11 @@
 const service_manager::Manifest& GetCastContentRendererOverlayManifest() {
   static base::NoDestructor<service_manager::Manifest> manifest {
     service_manager::ManifestBuilder()
+#if !defined(OS_FUCHSIA)
+        .ExposeCapability("browser",
+                          service_manager::Manifest::InterfaceList<
+                              heap_profiling::mojom::ProfilingClient>())
+#endif  // !defined(OS_FUCHSIA)
         .ExposeInterfaceFilterCapability_Deprecated(
             "navigation:frame", "browser",
             service_manager::Manifest::InterfaceList<
diff --git a/chromecast/common/BUILD.gn b/chromecast/common/BUILD.gn
index dac6096..925976d 100644
--- a/chromecast/common/BUILD.gn
+++ b/chromecast/common/BUILD.gn
@@ -52,4 +52,8 @@
       "//extensions/shell:resources_grit",
     ]
   }
+
+  if (!is_fuchsia) {
+    deps += [ "//components/services/heap_profiling/public/cpp" ]
+  }
 }
diff --git a/chromecast/common/DEPS b/chromecast/common/DEPS
index 288eeae..9dcc12d 100644
--- a/chromecast/common/DEPS
+++ b/chromecast/common/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+components/services/heap_profiling/public/cpp",
   "+components/version_info",
   "+content/public/common",
   "+extensions/common",
@@ -6,6 +7,7 @@
   "+extensions/shell/common/api",
   "+extensions/shell/grit",
   "+mojo/public/cpp/bindings",
+  "+services/service_manager/public/cpp",
   "+ui/accessibility",
   "+ui/base",
   "+ui/gfx",
diff --git a/chromecast/common/cast_content_client.cc b/chromecast/common/cast_content_client.cc
index 491e0842..62a38baa 100644
--- a/chromecast/common/cast_content_client.cc
+++ b/chromecast/common/cast_content_client.cc
@@ -5,6 +5,8 @@
 #include "chromecast/common/cast_content_client.h"
 
 #include <stdint.h>
+#include <memory>
+#include <utility>
 
 #include "base/strings/stringprintf.h"
 #include "base/system/sys_info.h"
@@ -25,6 +27,14 @@
 #include "chromecast/common/media/cast_media_drm_bridge_client.h"
 #endif
 
+#if !defined(OS_FUCHSIA)
+#include "base/no_destructor.h"
+#include "components/services/heap_profiling/public/cpp/client.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/common/simple_connection_filter.h"
+#include "services/service_manager/public/cpp/binder_registry.h"
+#endif
+
 namespace chromecast {
 namespace shell {
 
@@ -133,5 +143,20 @@
 }
 #endif  // OS_ANDROID
 
+void CastContentClient::OnServiceManagerConnected(
+    content::ServiceManagerConnection* connection) {
+#if !defined(OS_FUCHSIA)
+  static base::NoDestructor<heap_profiling::Client> profiling_client;
+
+  std::unique_ptr<service_manager::BinderRegistry> registry(
+      std::make_unique<service_manager::BinderRegistry>());
+  registry->AddInterface(
+      base::BindRepeating(&heap_profiling::Client::BindToInterface,
+                          base::Unretained(profiling_client.get())));
+  connection->AddConnectionFilter(
+      std::make_unique<content::SimpleConnectionFilter>(std::move(registry)));
+#endif  // !defined(OS_FUCHSIA)
+}
+
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromecast/common/cast_content_client.h b/chromecast/common/cast_content_client.h
index b3cd2aec..f535ae7 100644
--- a/chromecast/common/cast_content_client.h
+++ b/chromecast/common/cast_content_client.h
@@ -31,6 +31,8 @@
 #if defined(OS_ANDROID)
   ::media::MediaDrmBridgeClient* GetMediaDrmBridgeClient() override;
 #endif  // OS_ANDROID
+  void OnServiceManagerConnected(
+      content::ServiceManagerConnection* connection) override;
 
  private:
   GURL last_active_url_;
diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
index 5beb1ab..3528131 100644
--- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc
+++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
@@ -556,7 +556,7 @@
     const AudioConfig& audio_config = audio_decoder->config();
     EXPECT_EQ(kCodecPCM, audio_config.codec);
     EXPECT_EQ(kSampleFormatS16, audio_config.sample_format);
-    EXPECT_FALSE(audio_config.encryption_scheme.is_encrypted());
+    EXPECT_EQ(audio_config.encryption_scheme, EncryptionScheme::kUnencrypted);
 
     stream->Close();
   }
diff --git a/chromecast/media/cdm/cast_cdm.cc b/chromecast/media/cdm/cast_cdm.cc
index 3c367bf..e334ba9 100644
--- a/chromecast/media/cdm/cast_cdm.cc
+++ b/chromecast/media/cdm/cast_cdm.cc
@@ -48,7 +48,7 @@
 
   std::unique_ptr<DecryptContextImpl> GetDecryptContext(
       const std::string& key_id,
-      const EncryptionScheme& encryption_scheme) override {
+      EncryptionScheme encryption_scheme) override {
     return cast_cdm_->GetDecryptContext(key_id, encryption_scheme);
   }
 
diff --git a/chromecast/media/cdm/cast_cdm.h b/chromecast/media/cdm/cast_cdm.h
index 9f274cd0..6adec4c 100644
--- a/chromecast/media/cdm/cast_cdm.h
+++ b/chromecast/media/cdm/cast_cdm.h
@@ -58,7 +58,7 @@
   // |key_id|. Returns null if |key_id| is not available.
   virtual std::unique_ptr<DecryptContextImpl> GetDecryptContext(
       const std::string& key_id,
-      const EncryptionScheme& encryption_scheme) const = 0;
+      EncryptionScheme encryption_scheme) const = 0;
 
   // Notifies that key status has changed (e.g. if expiry is detected by
   // hardware decoder).
diff --git a/chromecast/media/cdm/cast_cdm_context.h b/chromecast/media/cdm/cast_cdm_context.h
index 606509d..5b4296eb 100644
--- a/chromecast/media/cdm/cast_cdm_context.h
+++ b/chromecast/media/cdm/cast_cdm_context.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 
+#include "chromecast/public/media/cast_decrypt_config.h"
 #include "chromecast/public/media/cast_key_status.h"
 #include "media/base/cdm_context.h"
 
@@ -15,7 +16,6 @@
 namespace media {
 
 class DecryptContextImpl;
-struct EncryptionScheme;
 
 // CdmContext implementation + some extra APIs needed by CastRenderer.
 class CastCdmContext : public ::media::CdmContext {
@@ -37,7 +37,7 @@
   // |key_id|. Returns null if |key_id| is not available.
   virtual std::unique_ptr<DecryptContextImpl> GetDecryptContext(
       const std::string& key_id,
-      const EncryptionScheme& encryption_scheme) = 0;
+      EncryptionScheme encryption_scheme) = 0;
 
   // Notifies that key status has changed (e.g. if expiry is detected by
   // hardware decoder).
diff --git a/chromecast/media/cma/backend/audio_decoder_software_wrapper.cc b/chromecast/media/cma/backend/audio_decoder_software_wrapper.cc
index 6d4a26e9..908e68d3 100644
--- a/chromecast/media/cma/backend/audio_decoder_software_wrapper.cc
+++ b/chromecast/media/cma/backend/audio_decoder_software_wrapper.cc
@@ -112,7 +112,7 @@
   }
   output_config_.bytes_per_channel = 2;
   output_config_.samples_per_second = config.samples_per_second;
-  output_config_.encryption_scheme = Unencrypted();
+  output_config_.encryption_scheme = EncryptionScheme::kUnencrypted;
   return backend_decoder_->SetConfig(output_config_);
 }
 
diff --git a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
index 68737d8..517e348 100644
--- a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
+++ b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
@@ -84,7 +84,7 @@
   default_config.codec = kCodecH264;
   default_config.profile = kH264Main;
   default_config.additional_config = nullptr;
-  default_config.encryption_scheme = Unencrypted();
+  default_config.encryption_scheme = EncryptionScheme::kUnencrypted;
   return default_config;
 }
 
@@ -587,7 +587,7 @@
     video_config.codec = kCodecH264;
     video_config.profile = kH264Main;
     video_config.additional_config = nullptr;
-    video_config.encryption_scheme = Unencrypted();
+    video_config.encryption_scheme = EncryptionScheme::kUnencrypted;
   } else {
     base::FilePath file_path = GetTestDataFilePath(filename);
     DemuxResult demux_result = FFmpegDemuxForTest(file_path, false /* audio */);
diff --git a/chromecast/media/cma/base/cast_decrypt_config_impl.cc b/chromecast/media/cma/base/cast_decrypt_config_impl.cc
index 0c676129..eaad673 100644
--- a/chromecast/media/cma/base/cast_decrypt_config_impl.cc
+++ b/chromecast/media/cma/base/cast_decrypt_config_impl.cc
@@ -10,9 +10,11 @@
 CastDecryptConfigImpl::CastDecryptConfigImpl(
     std::string key_id,
     std::string iv,
+    const EncryptionPattern& pattern,
     std::vector<SubsampleEntry> subsamples)
     : key_id_(std::move(key_id)),
       iv_(std::move(iv)),
+      pattern_(pattern),
       subsamples_(std::move(subsamples)) {}
 
 CastDecryptConfigImpl::~CastDecryptConfigImpl() {}
@@ -25,6 +27,10 @@
   return iv_;
 }
 
+const EncryptionPattern& CastDecryptConfigImpl::pattern() const {
+  return pattern_;
+}
+
 const std::vector<SubsampleEntry>& CastDecryptConfigImpl::subsamples() const {
   return subsamples_;
 }
diff --git a/chromecast/media/cma/base/cast_decrypt_config_impl.h b/chromecast/media/cma/base/cast_decrypt_config_impl.h
index 19bc64e01..b9a62e6 100644
--- a/chromecast/media/cma/base/cast_decrypt_config_impl.h
+++ b/chromecast/media/cma/base/cast_decrypt_config_impl.h
@@ -15,16 +15,19 @@
  public:
   CastDecryptConfigImpl(std::string key_id,
                         std::string iv,
+                        const EncryptionPattern& pattern,
                         std::vector<SubsampleEntry> subsamples);
   ~CastDecryptConfigImpl() override;
 
   const std::string& key_id() const override;
   const std::string& iv() const override;
+  const EncryptionPattern& pattern() const override;
   const std::vector<SubsampleEntry>& subsamples() const override;
 
  private:
   std::string key_id_;
   std::string iv_;
+  const EncryptionPattern pattern_;
   std::vector<SubsampleEntry> subsamples_;
 };
 
diff --git a/chromecast/media/cma/base/decoder_buffer_adapter.cc b/chromecast/media/cma/base/decoder_buffer_adapter.cc
index e9b1ef6..df2fb74 100644
--- a/chromecast/media/cma/base/decoder_buffer_adapter.cc
+++ b/chromecast/media/cma/base/decoder_buffer_adapter.cc
@@ -35,8 +35,17 @@
       // consistent backend handling.
       subsamples.emplace_back(0, buffer_->data_size());
     }
+
+    EncryptionPattern pattern;
+    if (decrypt_config->encryption_pattern()) {
+      pattern = EncryptionPattern(
+          decrypt_config->encryption_pattern()->crypt_byte_block(),
+          decrypt_config->encryption_pattern()->skip_byte_block());
+    }
+
     decrypt_config_.reset(new CastDecryptConfigImpl(
-        decrypt_config->key_id(), decrypt_config->iv(), std::move(subsamples)));
+        decrypt_config->key_id(), decrypt_config->iv(), pattern,
+        std::move(subsamples)));
   }
 }
 
diff --git a/chromecast/media/cma/base/decoder_config_adapter.cc b/chromecast/media/cma/base/decoder_config_adapter.cc
index 30808a53..933704f 100644
--- a/chromecast/media/cma/base/decoder_config_adapter.cc
+++ b/chromecast/media/cma/base/decoder_config_adapter.cc
@@ -144,13 +144,13 @@
 }
 
 ::media::EncryptionScheme::CipherMode ToMediaCipherMode(
-    EncryptionScheme::CipherMode mode) {
-  switch (mode) {
-    case EncryptionScheme::CIPHER_MODE_UNENCRYPTED:
+    EncryptionScheme scheme) {
+  switch (scheme) {
+    case EncryptionScheme::kUnencrypted:
       return ::media::EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
-    case EncryptionScheme::CIPHER_MODE_AES_CTR:
+    case EncryptionScheme::kAesCtr:
       return ::media::EncryptionScheme::CIPHER_MODE_AES_CTR;
-    case EncryptionScheme::CIPHER_MODE_AES_CBC:
+    case EncryptionScheme::kAesCbc:
       return ::media::EncryptionScheme::CIPHER_MODE_AES_CBC;
     default:
       NOTREACHED();
@@ -158,45 +158,24 @@
   }
 }
 
-EncryptionScheme::CipherMode ToCipherMode(
-    ::media::EncryptionScheme::CipherMode mode) {
-  switch (mode) {
+EncryptionScheme ToEncryptionScheme(const ::media::EncryptionScheme& scheme) {
+  switch (scheme.mode()) {
     case ::media::EncryptionScheme::CIPHER_MODE_UNENCRYPTED:
-      return EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
+      return EncryptionScheme::kUnencrypted;
     case ::media::EncryptionScheme::CIPHER_MODE_AES_CTR:
-      return EncryptionScheme::CIPHER_MODE_AES_CTR;
+      return EncryptionScheme::kAesCtr;
     case ::media::EncryptionScheme::CIPHER_MODE_AES_CBC:
-      return EncryptionScheme::CIPHER_MODE_AES_CBC;
+      return EncryptionScheme::kAesCbc;
     default:
       NOTREACHED();
-      return EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
+      return EncryptionScheme::kUnencrypted;
   }
 }
 
-EncryptionScheme::Pattern ToPatternSpec(
-    const ::media::EncryptionPattern& pattern) {
-  return EncryptionScheme::Pattern(pattern.crypt_byte_block(),
-                                   pattern.skip_byte_block());
-}
-
-::media::EncryptionPattern ToMediaPatternSpec(
-    const EncryptionScheme::Pattern& pattern) {
-  return ::media::EncryptionPattern(pattern.encrypt_blocks,
-                                    pattern.skip_blocks);
-}
-
-EncryptionScheme ToEncryptionScheme(
-    const ::media::EncryptionScheme& scheme) {
-  return EncryptionScheme(
-    ToCipherMode(scheme.mode()),
-    ToPatternSpec(scheme.pattern()));
-}
-
-::media::EncryptionScheme ToMediaEncryptionScheme(
-    const EncryptionScheme& scheme) {
-  return ::media::EncryptionScheme(
-    ToMediaCipherMode(scheme.mode),
-    ToMediaPatternSpec(scheme.pattern));
+// TODO(yucliu): Remove pattern after update ::media::Audio/VideoDecoderConfig.
+::media::EncryptionScheme ToMediaEncryptionScheme(EncryptionScheme scheme) {
+  return ::media::EncryptionScheme(ToMediaCipherMode(scheme),
+                                   ::media::EncryptionPattern());
 }
 
 }  // namespace
diff --git a/chromecast/media/cma/decoder/cast_audio_decoder.cc b/chromecast/media/cma/decoder/cast_audio_decoder.cc
index dad1ac731..aef70d6 100644
--- a/chromecast/media/cma/decoder/cast_audio_decoder.cc
+++ b/chromecast/media/cma/decoder/cast_audio_decoder.cc
@@ -69,7 +69,7 @@
       // TODO(kmackay) Should call OnInitialized(false) here, but that generally
       // causes the browsertests to crash since it happens during the render
       // pipeline initialization.
-      input_config.encryption_scheme = Unencrypted();
+      input_config.encryption_scheme = EncryptionScheme::kUnencrypted;
     }
     config_ = input_config;
 
diff --git a/chromecast/media/cma/pipeline/audio_pipeline_impl.cc b/chromecast/media/cma/pipeline/audio_pipeline_impl.cc
index bc433573..7a77990 100644
--- a/chromecast/media/cma/pipeline/audio_pipeline_impl.cc
+++ b/chromecast/media/cma/pipeline/audio_pipeline_impl.cc
@@ -73,14 +73,13 @@
   }
 }
 
-const EncryptionScheme& AudioPipelineImpl::GetEncryptionScheme(
-    StreamId id) const {
+EncryptionScheme AudioPipelineImpl::GetEncryptionScheme(StreamId id) const {
   return audio_config_.encryption_scheme;
 }
 
 std::unique_ptr<StreamDecryptor> AudioPipelineImpl::CreateDecryptor() {
   bool clear_buffer_needed = audio_decoder_->RequiresDecryption();
-  if (audio_config_.encryption_scheme.is_encrypted() &&
+  if (audio_config_.is_encrypted() &&
       MediaPipelineBackend::CreateAudioDecryptor && clear_buffer_needed) {
     LOG(INFO) << __func__ << " Create backend decryptor for audio.";
     return std::make_unique<BackendDecryptor>(audio_config_.encryption_scheme);
diff --git a/chromecast/media/cma/pipeline/audio_pipeline_impl.h b/chromecast/media/cma/pipeline/audio_pipeline_impl.h
index e0de5f4..b17e39a 100644
--- a/chromecast/media/cma/pipeline/audio_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/audio_pipeline_impl.h
@@ -44,7 +44,7 @@
   void OnUpdateConfig(StreamId id,
                       const ::media::AudioDecoderConfig& audio_config,
                       const ::media::VideoDecoderConfig& video_config) override;
-  const EncryptionScheme& GetEncryptionScheme(StreamId id) const override;
+  EncryptionScheme GetEncryptionScheme(StreamId id) const override;
   std::unique_ptr<StreamDecryptor> CreateDecryptor() override;
 
   CmaBackend::AudioDecoder* const audio_decoder_;
diff --git a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
index 89ce23e2..847a567d 100644
--- a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
+++ b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
@@ -75,7 +75,7 @@
 
   std::unique_ptr<DecryptContextImpl> GetDecryptContext(
       const std::string& key_id,
-      const EncryptionScheme& encryption_scheme) override {
+      EncryptionScheme encryption_scheme) override {
     if (license_installed_) {
       return std::unique_ptr<DecryptContextImpl>(
           new DecryptContextImpl(KEY_SYSTEM_CLEAR_KEY));
diff --git a/chromecast/media/cma/pipeline/av_pipeline_impl.h b/chromecast/media/cma/pipeline/av_pipeline_impl.h
index 3d8e3c1d..7935ccfc 100644
--- a/chromecast/media/cma/pipeline/av_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/av_pipeline_impl.h
@@ -20,6 +20,7 @@
 #include "chromecast/media/cma/backend/cma_backend.h"
 #include "chromecast/media/cma/pipeline/av_pipeline_client.h"
 #include "chromecast/media/cma/pipeline/stream_decryptor.h"
+#include "chromecast/public/media/cast_decrypt_config.h"
 #include "chromecast/public/media/stream_id.h"
 #include "media/base/pipeline_status.h"
 
@@ -35,7 +36,6 @@
 class BufferingState;
 class CodedFrameProvider;
 class DecoderBufferBase;
-struct EncryptionScheme;
 
 class AvPipelineImpl : CmaBackend::Decoder::Delegate {
  public:
@@ -75,7 +75,7 @@
       StreamId id,
       const ::media::AudioDecoderConfig& audio_config,
       const ::media::VideoDecoderConfig& video_config) = 0;
-  virtual const EncryptionScheme& GetEncryptionScheme(StreamId id) const = 0;
+  virtual EncryptionScheme GetEncryptionScheme(StreamId id) const = 0;
 
   // Create a decoder for decrypt and decode.
   virtual std::unique_ptr<StreamDecryptor> CreateDecryptor() = 0;
diff --git a/chromecast/media/cma/pipeline/backend_decryptor.cc b/chromecast/media/cma/pipeline/backend_decryptor.cc
index aaa03b0..1c7d10b 100644
--- a/chromecast/media/cma/pipeline/backend_decryptor.cc
+++ b/chromecast/media/cma/pipeline/backend_decryptor.cc
@@ -14,7 +14,7 @@
 namespace chromecast {
 namespace media {
 
-BackendDecryptor::BackendDecryptor(const EncryptionScheme& scheme)
+BackendDecryptor::BackendDecryptor(EncryptionScheme scheme)
     : decrypt_success_(true),
       wait_eos_(false),
       task_runner_(new TaskRunnerImpl) {
diff --git a/chromecast/media/cma/pipeline/backend_decryptor.h b/chromecast/media/cma/pipeline/backend_decryptor.h
index 42b361ae..99bdd67d 100644
--- a/chromecast/media/cma/pipeline/backend_decryptor.h
+++ b/chromecast/media/cma/pipeline/backend_decryptor.h
@@ -19,12 +19,11 @@
 class TaskRunnerImpl;
 
 namespace media {
-struct EncryptionScheme;
 
 class BackendDecryptor : public StreamDecryptor,
                          MediaPipelineBackend::AudioDecryptor::Delegate {
  public:
-  explicit BackendDecryptor(const EncryptionScheme& scheme);
+  explicit BackendDecryptor(EncryptionScheme scheme);
   ~BackendDecryptor() override;
 
   // StreamDecryptor implementation:
diff --git a/chromecast/media/cma/pipeline/video_pipeline_impl.cc b/chromecast/media/cma/pipeline/video_pipeline_impl.cc
index 871a9943..634fc116 100644
--- a/chromecast/media/cma/pipeline/video_pipeline_impl.cc
+++ b/chromecast/media/cma/pipeline/video_pipeline_impl.cc
@@ -119,8 +119,7 @@
   }
 }
 
-const EncryptionScheme& VideoPipelineImpl::GetEncryptionScheme(
-    StreamId id) const {
+EncryptionScheme VideoPipelineImpl::GetEncryptionScheme(StreamId id) const {
   DCHECK_LT(id, encryption_schemes_.size());
   return encryption_schemes_[static_cast<int>(id)];
 }
diff --git a/chromecast/media/cma/pipeline/video_pipeline_impl.h b/chromecast/media/cma/pipeline/video_pipeline_impl.h
index 6c74fc5..ee2860e 100644
--- a/chromecast/media/cma/pipeline/video_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/video_pipeline_impl.h
@@ -44,7 +44,7 @@
   void OnUpdateConfig(StreamId id,
                       const ::media::AudioDecoderConfig& audio_config,
                       const ::media::VideoDecoderConfig& video_config) override;
-  const EncryptionScheme& GetEncryptionScheme(StreamId id) const override;
+  EncryptionScheme GetEncryptionScheme(StreamId id) const override;
   std::unique_ptr<StreamDecryptor> CreateDecryptor() override;
 
   CmaBackend::VideoDecoder* const video_decoder_;
diff --git a/chromecast/public/media/cast_decrypt_config.h b/chromecast/public/media/cast_decrypt_config.h
index 582bce9..16e5796 100644
--- a/chromecast/public/media/cast_decrypt_config.h
+++ b/chromecast/public/media/cast_decrypt_config.h
@@ -12,6 +12,39 @@
 namespace chromecast {
 namespace media {
 
+// Specification of whether and how the stream is encrypted (in whole or part).
+//
+// Algorithm and mode that was used to encrypt the stream.
+enum class EncryptionScheme { kUnencrypted, kAesCtr, kAesCbc };
+
+// CENC 3rd Edition adds pattern encryption, through two new protection
+// schemes: 'cens' (with AES-CTR) and 'cbcs' (with AES-CBC).
+// The pattern applies independently to each 'encrypted' part of the frame (as
+// defined by the relevant subsample entries), and reduces further the
+// actual encryption applied through a repeating pattern of (encrypt:skip)
+// 16 byte blocks. For example, in a (1:9) pattern, the first block is
+// encrypted, and the next nine are skipped. This pattern is applied
+// repeatedly until the end of the last 16-byte block in the subsample.
+// Any remaining bytes are left clear.
+// If either of encrypt_blocks or skip_blocks is 0, pattern encryption is
+// disabled.
+struct EncryptionPattern {
+  EncryptionPattern() = default;
+  EncryptionPattern(uint32_t encrypt_blocks, uint32_t skip_blocks);
+  bool IsInEffect() const;
+
+  uint32_t encrypt_blocks = 0;
+  uint32_t skip_blocks = 0;
+};
+
+inline EncryptionPattern::EncryptionPattern(uint32_t encrypt_blocks,
+                                            uint32_t skip_blocks)
+    : encrypt_blocks(encrypt_blocks), skip_blocks(skip_blocks) {}
+
+inline bool EncryptionPattern::IsInEffect() const {
+  return encrypt_blocks != 0 && skip_blocks != 0;
+}
+
 // The Common Encryption spec provides for subsample encryption, where portions
 // of a sample are set in cleartext. A SubsampleEntry specifies the number of
 // clear and encrypted bytes in each subsample. For decryption, all of the
@@ -32,7 +65,7 @@
 // Contains all metadata needed to decrypt a media sample.
 class CastDecryptConfig {
  public:
-  virtual ~CastDecryptConfig() {}
+  virtual ~CastDecryptConfig() = default;
 
   // Returns the ID for this sample's decryption key.
   virtual const std::string& key_id() const = 0;
@@ -40,6 +73,9 @@
   // Returns the initialization vector as defined by the encryption format.
   virtual const std::string& iv() const = 0;
 
+  // Returns the encryption pattern for current sample.
+  virtual const EncryptionPattern& pattern() const = 0;
+
   // Returns the clear and encrypted portions of the sample as described above.
   virtual const std::vector<SubsampleEntry>& subsamples() const = 0;
 };
diff --git a/chromecast/public/media/decoder_config.h b/chromecast/public/media/decoder_config.h
index e06e86da..4dc0acf 100644
--- a/chromecast/public/media/decoder_config.h
+++ b/chromecast/public/media/decoder_config.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 #include <vector>
 
+#include "cast_decrypt_config.h"
 #include "stream_id.h"
 
 namespace chromecast {
@@ -106,68 +107,6 @@
   int level;
 };
 
-// Specification of whether and how the stream is encrypted (in whole or part).
-struct EncryptionScheme {
-  // Algorithm and mode that was used to encrypt the stream.
-  enum CipherMode {
-    CIPHER_MODE_UNENCRYPTED,
-    CIPHER_MODE_AES_CTR,
-    CIPHER_MODE_AES_CBC
-  };
-
-  // CENC 3rd Edition adds pattern encryption, through two new protection
-  // schemes: 'cens' (with AES-CTR) and 'cbcs' (with AES-CBC).
-  // The pattern applies independently to each 'encrypted' part of the frame (as
-  // defined by the relevant subsample entries), and reduces further the
-  // actual encryption applied through a repeating pattern of (encrypt:skip)
-  // 16 byte blocks. For example, in a (1:9) pattern, the first block is
-  // encrypted, and the next nine are skipped. This pattern is applied
-  // repeatedly until the end of the last 16-byte block in the subsample.
-  // Any remaining bytes are left clear.
-  // If either of encrypt_blocks or skip_blocks is 0, pattern encryption is
-  // disabled.
-  struct Pattern {
-    Pattern() {}
-    Pattern(uint32_t encrypt_blocks, uint32_t skip_blocks);
-    ~Pattern() {}
-    bool IsInEffect() const;
-
-    uint32_t encrypt_blocks = 0;
-    uint32_t skip_blocks = 0;
-  };
-
-  EncryptionScheme() {}
-  EncryptionScheme(CipherMode mode, const Pattern& pattern);
-  ~EncryptionScheme() {}
-  bool is_encrypted() const { return mode != CIPHER_MODE_UNENCRYPTED; }
-
-  CipherMode mode = CIPHER_MODE_UNENCRYPTED;
-  Pattern pattern;
-};
-
-inline EncryptionScheme::Pattern::Pattern(uint32_t encrypt_blocks,
-                                          uint32_t skip_blocks)
-    : encrypt_blocks(encrypt_blocks), skip_blocks(skip_blocks) {
-}
-
-inline bool EncryptionScheme::Pattern::IsInEffect() const {
-  return encrypt_blocks != 0 && skip_blocks != 0;
-}
-
-inline EncryptionScheme::EncryptionScheme(CipherMode mode,
-                                          const Pattern& pattern)
-    : mode(mode), pattern(pattern) {
-}
-
-inline EncryptionScheme Unencrypted() {
-  return EncryptionScheme();
-}
-
-inline EncryptionScheme AesCtrEncryptionScheme() {
-  return EncryptionScheme(EncryptionScheme::CIPHER_MODE_AES_CTR,
-                          EncryptionScheme::Pattern());
-}
-
 // ---- Begin copy/paste from //media/base/video_color_space.h ----
 // Described in ISO 23001-8:2016
 
@@ -291,7 +230,9 @@
   AudioConfig(const AudioConfig& other);
   ~AudioConfig();
 
-  bool is_encrypted() const { return encryption_scheme.is_encrypted(); }
+  bool is_encrypted() const {
+    return encryption_scheme != EncryptionScheme::kUnencrypted;
+  }
 
   // Stream id.
   StreamId id;
@@ -317,7 +258,8 @@
       sample_format(kUnknownSampleFormat),
       bytes_per_channel(0),
       channel_number(0),
-      samples_per_second(0) {}
+      samples_per_second(0),
+      encryption_scheme(EncryptionScheme::kUnencrypted) {}
 inline AudioConfig::AudioConfig(const AudioConfig& other) = default;
 inline AudioConfig::~AudioConfig() {
 }
@@ -330,7 +272,9 @@
   VideoConfig(const VideoConfig& other);
   ~VideoConfig();
 
-  bool is_encrypted() const { return encryption_scheme.is_encrypted(); }
+  bool is_encrypted() const {
+    return encryption_scheme != EncryptionScheme::kUnencrypted;
+  }
 
   // Stream Id.
   StreamId id;
@@ -361,8 +305,8 @@
     : id(kPrimary),
       codec(kVideoCodecUnknown),
       profile(kVideoProfileUnknown),
-      additional_config(nullptr) {
-}
+      additional_config(nullptr),
+      encryption_scheme(EncryptionScheme::kUnencrypted) {}
 
 inline VideoConfig::VideoConfig(const VideoConfig& other) = default;
 
diff --git a/chromecast/public/media/media_pipeline_backend.h b/chromecast/public/media/media_pipeline_backend.h
index 4695edc4..d5736e3 100644
--- a/chromecast/public/media/media_pipeline_backend.h
+++ b/chromecast/public/media/media_pipeline_backend.h
@@ -299,7 +299,7 @@
   // object. Platforms which support standard CDM decryption APIs do not need to
   // implement this function.
   CHROMECAST_EXPORT static AudioDecryptor* CreateAudioDecryptor(
-      const EncryptionScheme& scheme,
+      EncryptionScheme scheme,
       TaskRunner* task_runner) __attribute__((weak));
 };
 
diff --git a/chromecast/utility/BUILD.gn b/chromecast/utility/BUILD.gn
index a9e2938..421cd0e 100644
--- a/chromecast/utility/BUILD.gn
+++ b/chromecast/utility/BUILD.gn
@@ -17,4 +17,15 @@
   if (chromecast_branding == "public") {
     sources += [ "cast_content_utility_client_simple.cc" ]
   }
+
+  if (!is_fuchsia) {
+    sources += [ "cast_content_utility_client.cc" ]
+
+    deps += [
+      "//chromecast:chromecast_buildflags",
+      "//components/services/heap_profiling",
+      "//components/services/heap_profiling/public/mojom",
+      "//services/service_manager/public/cpp",
+    ]
+  }
 }
diff --git a/chromecast/utility/DEPS b/chromecast/utility/DEPS
index 8ad521e..6ab23ad 100644
--- a/chromecast/utility/DEPS
+++ b/chromecast/utility/DEPS
@@ -1,3 +1,5 @@
 include_rules = [
+  "+components/services/heap_profiling",
+  "+components/services/heap_profiling/public/mojom",
   "+content/public/utility",
 ]
diff --git a/chromecast/utility/cast_content_utility_client.cc b/chromecast/utility/cast_content_utility_client.cc
new file mode 100644
index 0000000..39d76f7e
--- /dev/null
+++ b/chromecast/utility/cast_content_utility_client.cc
@@ -0,0 +1,58 @@
+// 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 "chromecast/utility/cast_content_utility_client.h"
+
+#include <string>
+#include <utility>
+
+#include "base/callback_forward.h"
+#include "components/services/heap_profiling/heap_profiling_service.h"
+#include "components/services/heap_profiling/public/mojom/constants.mojom.h"
+#include "content/public/utility/utility_thread.h"
+
+namespace {
+
+std::unique_ptr<service_manager::Service> CreateHeapProfilingService(
+    service_manager::mojom::ServiceRequest request) {
+  return std::make_unique<heap_profiling::HeapProfilingService>(
+      std::move(request));
+}
+
+using ServiceFactory =
+    base::OnceCallback<std::unique_ptr<service_manager::Service>()>;
+void RunServiceOnIOThread(ServiceFactory factory) {
+  base::OnceClosure terminate_process = base::BindOnce(
+      base::IgnoreResult(&base::SequencedTaskRunner::PostTask),
+      base::SequencedTaskRunnerHandle::Get(), FROM_HERE,
+      base::BindOnce([] { content::UtilityThread::Get()->ReleaseProcess(); }));
+  content::ChildThread::Get()->GetIOTaskRunner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          [](ServiceFactory factory, base::OnceClosure terminate_process) {
+            service_manager::Service::RunAsyncUntilTermination(
+                std::move(factory).Run(), std::move(terminate_process));
+          },
+          std::move(factory), std::move(terminate_process)));
+}
+
+}  // namespace
+
+namespace chromecast {
+namespace shell {
+
+bool CastContentUtilityClient::HandleServiceRequest(
+    const std::string& service_name,
+    service_manager::mojom::ServiceRequest request) {
+  if (service_name == heap_profiling::mojom::kServiceName) {
+    RunServiceOnIOThread(
+        base::BindOnce(&CreateHeapProfilingService, std::move(request)));
+    return true;
+  }
+
+  return false;
+}
+
+}  // namespace shell
+}  // namespace chromecast
diff --git a/chromecast/utility/cast_content_utility_client.h b/chromecast/utility/cast_content_utility_client.h
index 7f7528d..5f04c27 100644
--- a/chromecast/utility/cast_content_utility_client.h
+++ b/chromecast/utility/cast_content_utility_client.h
@@ -6,8 +6,10 @@
 #define CHROMECAST_UTILITY_CAST_CONTENT_UTILITY_CLIENT_H_
 
 #include <memory>
+#include <string>
 
 #include "base/macros.h"
+#include "build/build_config.h"
 #include "content/public/utility/content_utility_client.h"
 
 namespace chromecast {
@@ -19,6 +21,13 @@
 
   CastContentUtilityClient() {}
 
+#if !defined(OS_FUCHSIA)
+  // content::ContentUtilityClient implementation:
+  bool HandleServiceRequest(
+      const std::string& service_name,
+      service_manager::mojom::ServiceRequest request) override;
+#endif  // !defined(OS_FUCHSIA)
+
  private:
   DISALLOW_COPY_AND_ASSIGN(CastContentUtilityClient);
 };
diff --git a/chromeos/dbus/fake_session_manager_client.cc b/chromeos/dbus/fake_session_manager_client.cc
index 8bb048d..b8d142c 100644
--- a/chromeos/dbus/fake_session_manager_client.cc
+++ b/chromeos/dbus/fake_session_manager_client.cc
@@ -283,10 +283,6 @@
 
 void FakeSessionManagerClient::StopSession() {}
 
-void FakeSessionManagerClient::NotifySupervisedUserCreationStarted() {}
-
-void FakeSessionManagerClient::NotifySupervisedUserCreationFinished() {}
-
 void FakeSessionManagerClient::StartDeviceWipe() {
   start_device_wipe_call_count_++;
 }
diff --git a/chromeos/dbus/fake_session_manager_client.h b/chromeos/dbus/fake_session_manager_client.h
index fb331ea..ff7e2356 100644
--- a/chromeos/dbus/fake_session_manager_client.h
+++ b/chromeos/dbus/fake_session_manager_client.h
@@ -54,8 +54,6 @@
   void StartSession(
       const cryptohome::AccountIdentifier& cryptohome_id) override;
   void StopSession() override;
-  void NotifySupervisedUserCreationStarted() override;
-  void NotifySupervisedUserCreationFinished() override;
   void StartDeviceWipe() override;
   void ClearForcedReEnrollmentVpd(VoidDBusMethodCallback callback) override;
   void StartTPMFirmwareUpdate(const std::string& update_mode) override;
diff --git a/chromeos/dbus/session_manager_client.cc b/chromeos/dbus/session_manager_client.cc
index 1004ccc8..f83547e 100644
--- a/chromeos/dbus/session_manager_client.cc
+++ b/chromeos/dbus/session_manager_client.cc
@@ -262,16 +262,6 @@
         login_manager::kSessionManagerHandleLockScreenDismissed);
   }
 
-  void NotifySupervisedUserCreationStarted() override {
-    SimpleMethodCallToSessionManager(
-        login_manager::kSessionManagerHandleSupervisedUserCreationStarting);
-  }
-
-  void NotifySupervisedUserCreationFinished() override {
-    SimpleMethodCallToSessionManager(
-        login_manager::kSessionManagerHandleSupervisedUserCreationFinished);
-  }
-
   void RetrieveActiveSessions(ActiveSessionsCallback callback) override {
     dbus::MethodCall method_call(
         login_manager::kSessionManagerInterface,
diff --git a/chromeos/dbus/session_manager_client.h b/chromeos/dbus/session_manager_client.h
index 156f17d7..24260a4a 100644
--- a/chromeos/dbus/session_manager_client.h
+++ b/chromeos/dbus/session_manager_client.h
@@ -156,12 +156,6 @@
   // Notifies session_manager that Chrome has hidden the lock screen.
   virtual void NotifyLockScreenDismissed() = 0;
 
-  // Notifies that supervised user creation have started.
-  virtual void NotifySupervisedUserCreationStarted() = 0;
-
-  // Notifies that supervised user creation have finished.
-  virtual void NotifySupervisedUserCreationFinished() = 0;
-
   // Map that is used to describe the set of active user sessions where |key|
   // is cryptohome id and |value| is user_id_hash.
   using ActiveSessionsMap = std::map<std::string, std::string>;
diff --git a/components/autofill/content/renderer/prefilled_values_detector.cc b/components/autofill/content/renderer/prefilled_values_detector.cc
index 80290a4..8ef1d3a 100644
--- a/components/autofill/content/renderer/prefilled_values_detector.cc
+++ b/components/autofill/content/renderer/prefilled_values_detector.cc
@@ -57,7 +57,7 @@
                      "ååååmmddxxxx",
                      "아이디 or @이하 모두 입력",
                      "Имя",
-                     "Имя (логин)"
+                     "Имя (логин)",
                      "Логин",
                      "Логин...",
                      "Логин (e-mail)",
diff --git a/components/autofill/core/browser/autofill_type.cc b/components/autofill/core/browser/autofill_type.cc
index 62bb3c046..e873833 100644
--- a/components/autofill/core/browser/autofill_type.cc
+++ b/components/autofill/core/browser/autofill_type.cc
@@ -777,10 +777,10 @@
       return "SEARCH_TERM";
     case PRICE:
       return "PRICE";
-
+    case NOT_PASSWORD:
+      return "NOT_PASSWORD";
     case AMBIGUOUS_TYPE:
       return "AMBIGUOUS_TYPE";
-
     case MAX_VALID_FIELD_TYPE:
       return std::string();
   }
diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h
index c10fd8df..022575a16 100644
--- a/components/autofill/core/browser/field_types.h
+++ b/components/autofill/core/browser/field_types.h
@@ -172,9 +172,12 @@
   // Price fields are detected, but not filled.
   PRICE = 98,
 
+  // Password-type fields which are not actual passwords.
+  NOT_PASSWORD = 99,
+
   // No new types can be added without a corresponding change to the Autofill
   // server.
-  MAX_VALID_FIELD_TYPE = 99,
+  MAX_VALID_FIELD_TYPE = 100,
 };
 
 // The list of all HTML autocomplete field type hints supported by Chrome.
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h
index a624ba2..9b110af 100644
--- a/components/autofill_assistant/browser/actions/action_delegate.h
+++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -192,6 +192,9 @@
   // Show the progress bar and set it at |progress|%.
   virtual void SetProgress(int progress) = 0;
 
+  // Shows the progress bar when |visible| is true. Hides it when false.
+  virtual void SetProgressVisible(bool visible) = 0;
+
  protected:
   ActionDelegate() = default;
 };
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h
index 6c79cca5..70dd5920 100644
--- a/components/autofill_assistant/browser/actions/mock_action_delegate.h
+++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -134,6 +134,7 @@
   MOCK_METHOD1(SetDetails, void(const Details& details));
   MOCK_METHOD0(ClearDetails, void());
   MOCK_METHOD1(SetProgress, void(int progress));
+  MOCK_METHOD1(SetProgressVisible, void(bool visible));
   MOCK_METHOD1(SetChips, void(std::unique_ptr<std::vector<Chip>> chips));
 };
 
diff --git a/components/autofill_assistant/browser/actions/show_progress_bar_action.cc b/components/autofill_assistant/browser/actions/show_progress_bar_action.cc
index abc8560..243f4da 100644
--- a/components/autofill_assistant/browser/actions/show_progress_bar_action.cc
+++ b/components/autofill_assistant/browser/actions/show_progress_bar_action.cc
@@ -30,6 +30,9 @@
   int progress =
       std::min(100, std::max(0, proto_.show_progress_bar().progress()));
   delegate->SetProgress(progress);
+  if (proto_.show_progress_bar().has_hide()) {
+    delegate->SetProgressVisible(!proto_.show_progress_bar().hide());
+  }
 
   UpdateProcessedAction(ACTION_APPLIED);
   std::move(callback).Run(std::move(processed_action_proto_));
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc
index 4b98e1f..e8c0398 100644
--- a/components/autofill_assistant/browser/controller.cc
+++ b/components/autofill_assistant/browser/controller.cc
@@ -153,6 +153,18 @@
   GetUiController()->OnProgressChanged(progress);
 }
 
+void Controller::SetProgressVisible(bool visible) {
+  if (progress_visible_ == visible)
+    return;
+
+  progress_visible_ = visible;
+  GetUiController()->OnProgressVisibilityChanged(visible);
+}
+
+bool Controller::GetProgressVisible() const {
+  return progress_visible_;
+}
+
 const std::vector<Chip>& Controller::GetSuggestions() const {
   static const base::NoDestructor<std::vector<Chip>> no_suggestions_;
   return suggestions_ ? *suggestions_ : *no_suggestions_;
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h
index cbb55e9..9e7fc0b9 100644
--- a/components/autofill_assistant/browser/controller.h
+++ b/components/autofill_assistant/browser/controller.h
@@ -89,6 +89,7 @@
   void SetDetails(const Details& details) override;
   void ClearDetails() override;
   void SetProgress(int progress) override;
+  void SetProgressVisible(bool visible) override;
   void SetChips(std::unique_ptr<std::vector<Chip>> chips) override;
 
   // Stops the controller with |reason| and destroys this. The current status
@@ -105,6 +106,7 @@
   void OnUserInteractionInsideTouchableArea() override;
   const Details* GetDetails() const override;
   int GetProgress() const override;
+  bool GetProgressVisible() const override;
   const std::vector<Chip>& GetSuggestions() const override;
   void SelectSuggestion(int index) override;
   const std::vector<Chip>& GetActions() const override;
@@ -252,6 +254,9 @@
   // Current progress.
   int progress_ = 0;
 
+  // Current visibility of the progress bar. It is initially visible.
+  bool progress_visible_ = true;
+
   // Current set of suggestions. May be null, but never empty.
   std::unique_ptr<std::vector<Chip>> suggestions_;
 
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
index 0d56d026..b3c7620 100644
--- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc
+++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -70,6 +70,8 @@
 
 void FakeScriptExecutorDelegate::SetProgress(int progress) {}
 
+void FakeScriptExecutorDelegate::SetProgressVisible(bool visible) {}
+
 void FakeScriptExecutorDelegate::SetChips(
     std::unique_ptr<std::vector<Chip>> chips) {
   chips_ = std::move(chips);
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.h b/components/autofill_assistant/browser/fake_script_executor_delegate.h
index a44abc5..2d8e7cc5 100644
--- a/components/autofill_assistant/browser/fake_script_executor_delegate.h
+++ b/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -37,6 +37,7 @@
   void SetDetails(const Details& details) override;
   void ClearDetails() override;
   void SetProgress(int progress) override;
+  void SetProgressVisible(bool visible) override;
   void SetChips(std::unique_ptr<std::vector<Chip>> chips) override;
   void SetPaymentRequestOptions(
       std::unique_ptr<PaymentRequestOptions> options) override;
diff --git a/components/autofill_assistant/browser/mock_ui_controller.h b/components/autofill_assistant/browser/mock_ui_controller.h
index 72b5357dd..801c9e3b 100644
--- a/components/autofill_assistant/browser/mock_ui_controller.h
+++ b/components/autofill_assistant/browser/mock_ui_controller.h
@@ -32,6 +32,7 @@
                void(const PaymentRequestOptions* options));
   MOCK_METHOD1(OnDetailsChanged, void(const Details* details));
   MOCK_METHOD1(OnProgressChanged, void(int progress));
+  MOCK_METHOD1(OnProgressVisibilityChanged, void(bool visible));
   MOCK_METHOD1(OnTouchableAreaChanged, void(const std::vector<RectF>& areas));
   MOCK_CONST_METHOD0(Terminate, bool());
   MOCK_CONST_METHOD0(GetDropOutReason, Metrics::DropOutReason());
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc
index 736e8df..7c5f7cb6 100644
--- a/components/autofill_assistant/browser/script_executor.cc
+++ b/components/autofill_assistant/browser/script_executor.cc
@@ -336,6 +336,10 @@
   delegate_->SetProgress(progress);
 }
 
+void ScriptExecutor::SetProgressVisible(bool visible) {
+  delegate_->SetProgressVisible(visible);
+}
+
 void ScriptExecutor::SetFieldValue(const Selector& selector,
                                    const std::string& value,
                                    bool simulate_key_presses,
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h
index caef653..eee363c 100644
--- a/components/autofill_assistant/browser/script_executor.h
+++ b/components/autofill_assistant/browser/script_executor.h
@@ -158,6 +158,7 @@
   void ClearDetails() override;
   void SetDetails(const Details& details) override;
   void SetProgress(int progress) override;
+  void SetProgressVisible(bool visible) override;
 
  private:
   // Helper for WaitForElementVisible that keeps track of the state required to
diff --git a/components/autofill_assistant/browser/script_executor_delegate.h b/components/autofill_assistant/browser/script_executor_delegate.h
index 7d46b65..53a9f08 100644
--- a/components/autofill_assistant/browser/script_executor_delegate.h
+++ b/components/autofill_assistant/browser/script_executor_delegate.h
@@ -53,6 +53,7 @@
   virtual void SetPaymentRequestOptions(
       std::unique_ptr<PaymentRequestOptions> options) = 0;
   virtual void SetProgress(int progress) = 0;
+  virtual void SetProgressVisible(bool visible) = 0;
   virtual void SetChips(std::unique_ptr<std::vector<Chip>> chips) = 0;
 
   // Makes no area of the screen touchable.
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index 057da29c..fbff834b 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -573,6 +573,9 @@
   // will be capped to 100, values below 0 will be capped to 0 by the client.
   // NOTE: Setting |progress| to 100 is an equivalent of setting |done| to true.
   optional int32 progress = 6;
+
+  // Hide the progress bar in the UI.
+  optional bool hide = 7;
 }
 
 // Contain all arguments to perform a highlight element action.
diff --git a/components/autofill_assistant/browser/ui_controller.cc b/components/autofill_assistant/browser/ui_controller.cc
index 509c4f93..1ac6b7a 100644
--- a/components/autofill_assistant/browser/ui_controller.cc
+++ b/components/autofill_assistant/browser/ui_controller.cc
@@ -21,6 +21,7 @@
     const PaymentRequestOptions* options) {}
 void UiController::OnDetailsChanged(const Details* details) {}
 void UiController::OnProgressChanged(int progress) {}
+void UiController::OnProgressVisibilityChanged(bool visible) {}
 void UiController::OnTouchableAreaChanged(const std::vector<RectF>& areas) {}
 
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/ui_controller.h b/components/autofill_assistant/browser/ui_controller.h
index 4aee0a6..8905b14 100644
--- a/components/autofill_assistant/browser/ui_controller.h
+++ b/components/autofill_assistant/browser/ui_controller.h
@@ -59,6 +59,10 @@
   // percentage.
   virtual void OnProgressChanged(int progress);
 
+  // Called when the current progress bar visibility has changed. If |visible|
+  // is true, then the bar is now shown.
+  virtual void OnProgressVisibilityChanged(bool visible);
+
   // Updates the area of the visible viewport that is accessible when the
   // overlay state is OverlayState::PARTIAL.
   //
diff --git a/components/autofill_assistant/browser/ui_delegate.h b/components/autofill_assistant/browser/ui_delegate.h
index f9409c8..0741031 100644
--- a/components/autofill_assistant/browser/ui_delegate.h
+++ b/components/autofill_assistant/browser/ui_delegate.h
@@ -47,6 +47,9 @@
   // Returns the current progress; a percentage.
   virtual int GetProgress() const = 0;
 
+  // Returns whether the progress bar is visible.
+  virtual bool GetProgressVisible() const = 0;
+
   // Returns the current set of suggestions.
   virtual const std::vector<Chip>& GetSuggestions() const = 0;
 
diff --git a/components/cronet/android/cronet_bidirectional_stream_adapter.cc b/components/cronet/android/cronet_bidirectional_stream_adapter.cc
index 17570231..557c5f8 100644
--- a/components/cronet/android/cronet_bidirectional_stream_adapter.cc
+++ b/components/cronet/android/cronet_bidirectional_stream_adapter.cc
@@ -17,6 +17,7 @@
 #include "components/cronet/android/url_request_error.h"
 #include "components/cronet/metrics_util.h"
 #include "jni/CronetBidirectionalStream_jni.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
 #include "net/http/bidirectional_stream_request_info.h"
@@ -28,7 +29,6 @@
 #include "net/ssl/ssl_info.h"
 #include "net/third_party/quic/core/quic_packets.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "url/gurl.h"
 
diff --git a/components/cronet/ios/cronet_environment.mm b/components/cronet/ios/cronet_environment.mm
index 49bda283..044f37a2 100644
--- a/components/cronet/ios/cronet_environment.mm
+++ b/components/cronet/ios/cronet_environment.mm
@@ -30,6 +30,7 @@
 #include "ios/web/public/global_state/ios_global_state.h"
 #include "ios/web/public/global_state/ios_global_state_configuration.h"
 #include "ios/web/public/user_agent.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/network_change_notifier.h"
 #include "net/base/url_util.h"
 #include "net/cert/cert_verifier.h"
@@ -48,7 +49,6 @@
 #include "net/ssl/channel_id_service.h"
 #include "net/ssl/ssl_key_logger_impl.h"
 #include "net/third_party/quic/core/quic_versions.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_builder.h"
 #include "net/url_request/url_request_context_storage.h"
diff --git a/components/cronet/url_request_context_config_unittest.cc b/components/cronet/url_request_context_config_unittest.cc
index 6e4916e..2b094f7f 100644
--- a/components/cronet/url_request_context_config_unittest.cc
+++ b/components/cronet/url_request_context_config_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "net/base/host_port_pair.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/net_errors.h"
 #include "net/cert/cert_verifier.h"
 #include "net/dns/host_resolver.h"
@@ -23,7 +24,6 @@
 #include "net/log/net_log_with_source.h"
 #include "net/proxy_resolution/proxy_config.h"
 #include "net/proxy_resolution/proxy_config_service_fixed.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_builder.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
index 50175ff1..4b3a1d1 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -31,8 +31,6 @@
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_throttle_manager.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_request_headers.h"
-#include "net/url_request/http_user_agent_settings.h"
-#include "net/url_request/static_http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_builder.h"
 #include "net/url_request/url_request_context_getter.h"
diff --git a/components/grpc_support/bidirectional_stream.cc b/components/grpc_support/bidirectional_stream.cc
index 1d13e63..44808d8 100644
--- a/components/grpc_support/bidirectional_stream.cc
+++ b/components/grpc_support/bidirectional_stream.cc
@@ -15,6 +15,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
@@ -27,7 +28,6 @@
 #include "net/http/http_util.h"
 #include "net/ssl/ssl_info.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "url/gurl.h"
diff --git a/components/grpc_support/bidirectional_stream_c.cc b/components/grpc_support/bidirectional_stream_c.cc
index 8b739a4..a64b597 100644
--- a/components/grpc_support/bidirectional_stream_c.cc
+++ b/components/grpc_support/bidirectional_stream_c.cc
@@ -31,7 +31,6 @@
 #include "net/http/http_util.h"
 #include "net/ssl/ssl_info.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "url/gurl.h"
 
diff --git a/components/management_strings.grdp b/components/management_strings.grdp
index 60a0008c..4d41e18 100644
--- a/components/management_strings.grdp
+++ b/components/management_strings.grdp
@@ -129,8 +129,8 @@
   <message name="IDS_MANAGEMENT_EXTENSION_REPORT_EXTENSIONS_PLUGINS" desc="Message explaining that an extension currently reports the user's exensions and plugins">
     Information about installed extensions and plugins
   </message>
-  <message name="IDS_MANAGEMENT_EXTENSION_REPORT_SAFE_BROWSING_WARNINGS" desc="Message explaining that an extension currently reports the user's safe browsing warnings and ignored warnings">
-    <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Safe Browsing<ph name="END_LINK">&lt;/a&gt;</ph> warnings
+  <message name="IDS_MANAGEMENT_EXTENSION_REPORT_SAFE_BROWSING_WARNINGS" desc="Message explaining that an extension currently reports the user's Safe Browsing warnings and ignored warnings">
+    <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;<ex>&lt;a target="_blank" href="https://example.com"&gt;</ex></ph>Safe Browsing<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph> warnings
   </message>
   <message name="IDS_MANAGEMENT_EXTENSION_REPORT_USER_BROWSING_DATA" desc="Message explaining that an extension currently reports the user's browsing data">
     Websites you visit and time spent on them
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc
index a6ebac40..1b143730 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <iterator>
 #include <set>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -20,6 +21,7 @@
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/common/autofill_regex_constants.h"
 #include "components/autofill/core/common/autofill_regexes.h"
 #include "components/autofill/core/common/form_data.h"
@@ -104,12 +106,11 @@
   // The flag derived from field->autocomplete_attribute.
   AutocompleteFlag autocomplete_flag = AutocompleteFlag::kNone;
 
-  // True iff field->form_control_type == "password".
+  // True if field->form_control_type == "password".
   bool is_password = false;
 
-  // True if this field was marked CREDIT_CARD_VERIFICATION_CODE in server
-  // predictions.
-  bool server_hints_CVC = false;
+  // True if the server predicts this field not to be a password.
+  bool server_hints_not_password = false;
 
   Interactability interactability = Interactability::kUnlikely;
 };
@@ -122,19 +123,15 @@
   return autofill::MatchesPattern(str, *kCardCvcReCached);
 }
 
-// TODO(crbug.com/860700): Remove once server-side provides hints for CVC
-// fields.
-// Returns true if the |field| is suspected to be a CVC field.
-bool IsFieldCVC(const ProcessedField& field) {
-  return field.server_hints_CVC ||
+// TODO(crbug.com/860700): Remove name and attribute checking once server-side
+// provides hints for CVC.
+// Returns true if the |field| is suspected to be not the password field.
+// The suspicion is based on server-side provided hints and on checking the
+// field's id and name for hinting towards a CVC code.
+bool IsNotPasswordField(const ProcessedField& field) {
+  return field.server_hints_not_password ||
          StringMatchesCVC(field.field->name_attribute) ||
-         StringMatchesCVC(field.field->id_attribute);
-}
-
-// Returns true if the |field| is suspected to be a credit card related field
-// (credit card owner name, CVC code, expiration date etc).
-bool IsCreditCardField(const ProcessedField& field) {
-  return IsFieldCVC(field) ||
+         StringMatchesCVC(field.field->id_attribute) ||
          field.autocomplete_flag == AutocompleteFlag::kCreditCard;
 }
 
@@ -356,13 +353,15 @@
   if (result->confirmation_password && !result->new_password)
     result->confirmation_password = nullptr;
 
-  // For the use of basic heuristics, also mark CVC fields as such.
+  // For the use of basic heuristics, also mark CVC fields and NOT_PASSWORD
+  // fields as such.
   for (const auto& prediction : predictions) {
-    if (prediction.second.type == autofill::CREDIT_CARD_VERIFICATION_CODE) {
+    if (prediction.second.type == autofill::CREDIT_CARD_VERIFICATION_CODE ||
+        prediction.second.type == autofill::NOT_PASSWORD) {
       ProcessedField* processed_field =
           FindFieldWithUniqueRendererId(processed_fields, prediction.first);
       if (processed_field)
-        processed_field->server_hints_CVC = true;
+        processed_field->server_hints_not_password = true;
     }
   }
 }
@@ -433,7 +432,7 @@
     ++*ignored_readonly;
     return false;
   }
-  return !IsCreditCardField(field);
+  return !IsNotPasswordField(field);
 }
 
 // Filters the available passwords from |processed_fields| using these rules:
@@ -612,7 +611,7 @@
       continue;
     if (is_saving && IsProbablyNotUsername(it->field->value))
       continue;
-    if (!is_fallback && IsCreditCardField(*it))
+    if (!is_fallback && IsNotPasswordField(*it))
       continue;
     if (!username)
       username = it->field;
@@ -660,7 +659,7 @@
     // What is the best interactability among passwords?
     Interactability password_max = Interactability::kUnlikely;
     for (const ProcessedField& processed_field : processed_fields) {
-      if (processed_field.is_password && !IsCreditCardField(processed_field))
+      if (processed_field.is_password && !IsNotPasswordField(processed_field))
         password_max = std::max(password_max, processed_field.interactability);
     }
 
@@ -706,7 +705,7 @@
   *username_max = Interactability::kUnlikely;
   for (auto it = processed_fields.begin(); it != first_relevant_password;
        ++it) {
-    if (!it->is_password && !IsCreditCardField(*it))
+    if (!it->is_password && !IsNotPasswordField(*it))
       *username_max = std::max(*username_max, it->interactability);
   }
 
@@ -926,6 +925,9 @@
 
 std::unique_ptr<PasswordForm> FormDataParser::Parse(const FormData& form_data,
                                                     Mode mode) {
+  if (form_data.fields.size() > kMaxParseableFields)
+    return nullptr;
+
   readonly_status_ = ReadonlyPasswordFields::kNoHeuristics;
   autofill::ValueElementVector all_possible_passwords;
   autofill::ValueElementVector all_possible_usernames;
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.h b/components/password_manager/core/browser/form_parsing/form_parser.h
index fd551751..7adcace0 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.h
+++ b/components/password_manager/core/browser/form_parsing/form_parser.h
@@ -65,6 +65,10 @@
     kAllIgnored = 4,
   };
 
+  // The parser will give up on parsing any FormData with more than
+  // |kMaxParseableFields| fields.
+  static const size_t kMaxParseableFields = 10000;
+
   FormDataParser();
 
   ~FormDataParser();
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
index 1b0eaa1..462b1af4 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
+#include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "components/autofill/core/common/password_form.h"
@@ -1484,6 +1485,33 @@
   });
 }
 
+// The parser should avoid identifying NOT_PASSWORD fields as passwords.
+TEST(FormParserTest, NotPasswordField) {
+  CheckTestData({
+      {
+          "Server hints: NOT_PASSWORD.",
+          {
+              {.role = ElementRole::USERNAME, .form_control_type = "text"},
+              {.form_control_type = "password",
+               .prediction = {.type = autofill::NOT_PASSWORD}},
+              {.role = ElementRole::CURRENT_PASSWORD,
+               .form_control_type = "password"},
+          },
+          .fallback_only = false,
+      },
+      {
+          "Server hints: NOT_PASSWORD on only password.",
+          {
+              {.role = ElementRole::USERNAME, .form_control_type = "text"},
+              {.role = ElementRole::CURRENT_PASSWORD,
+               .prediction = {.type = autofill::NOT_PASSWORD},
+               .form_control_type = "password"},
+          },
+          .fallback_only = true,
+      },
+  });
+}
+
 // Check that "readonly status" is reported accordingly.
 TEST(FormParserTest, ReadonlyStatus) {
   CheckTestData({
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
index 356c7b6..50e5df3 100644
--- a/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
+++ b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
@@ -4,10 +4,12 @@
 
 #include "components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.h"
 
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "components/autofill/core/common/form_field_data.h"
+#include "components/password_manager/core/browser/form_parsing/form_parser.h"
 #include "components/password_manager/core/browser/form_parsing/fuzzer/form_data_essentials.pb.h"
 #include "url/gurl.h"
 #include "url/origin.h"
@@ -21,6 +23,15 @@
 FormData GenerateWithProto(const ::form_data_fuzzer::Form& form_proto) {
   FormData result;
 
+  // |kMaxParseableFields| is the largest number of fields the parser will
+  // accept. Generating significantly more than that is just wasting fuzzing
+  // resources. Allow exceeding this number though, to test that the parser
+  // indeed handles such inputs.
+  if (base::checked_cast<size_t>(form_proto.fields_size()) >
+      FormDataParser::kMaxParseableFields + 1) {
+    return result;
+  }
+
   result.id_attribute = UTF8ToUTF16(form_proto.id());
   result.name_attribute = UTF8ToUTF16(form_proto.name());
   result.is_form_tag = form_proto.is_form_tag();
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index 9cf66f8..801c474 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include <algorithm>
 #include <map>
 #include <memory>
 #include <utility>
@@ -160,7 +161,8 @@
 bool IsPredictedTypeNotPasswordPrediction(
     autofill::ServerFieldType field_type) {
   return field_type == autofill::CREDIT_CARD_NUMBER ||
-         field_type == autofill::CREDIT_CARD_VERIFICATION_CODE;
+         field_type == autofill::CREDIT_CARD_VERIFICATION_CODE ||
+         field_type == autofill::NOT_PASSWORD;
 }
 
 bool AreAllFieldsEmpty(const PasswordForm& form) {
diff --git a/components/policy/core/browser/browser_policy_connector.cc b/components/policy/core/browser/browser_policy_connector.cc
index ed126dd..a7710f9910 100644
--- a/components/policy/core/browser/browser_policy_connector.cc
+++ b/components/policy/core/browser/browser_policy_connector.cc
@@ -182,7 +182,7 @@
   registry->RegisterBooleanPref(
       policy_prefs::kCloudManagementEnrollmentMandatory, false);
   registry->RegisterBooleanPref(
-      policy_prefs::kCloudPolicyOverridesMachinePolicy, false);
+      policy_prefs::kCloudPolicyOverridesPlatformPolicy, false);
 }
 
 }  // namespace policy
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.cc b/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.cc
index 39cc7763..ad6936e4c 100644
--- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.cc
+++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.cc
@@ -51,7 +51,8 @@
   CreateComponentCloudPolicyService(
       dm_protocol::kChromeMachineLevelExtensionCloudPolicyType,
       policy_dir_.Append(kComponentPolicyCache),
-      (local_state->GetBoolean(policy_prefs::kCloudPolicyOverridesMachinePolicy)
+      (local_state->GetBoolean(
+           policy_prefs::kCloudPolicyOverridesPlatformPolicy)
            ? POLICY_SOURCE_PRIORITY_CLOUD
            : POLICY_SOURCE_CLOUD),
       client.get(), schema_registry());
diff --git a/components/policy/core/common/cloud/user_cloud_policy_manager.cc b/components/policy/core/common/cloud/user_cloud_policy_manager.cc
index 844de2b..11b50e09 100644
--- a/components/policy/core/common/cloud/user_cloud_policy_manager.cc
+++ b/components/policy/core/common/cloud/user_cloud_policy_manager.cc
@@ -74,7 +74,8 @@
 
   CreateComponentCloudPolicyService(
       dm_protocol::kChromeExtensionPolicyType, component_policy_cache_path_,
-      (local_state->GetBoolean(policy_prefs::kCloudPolicyOverridesMachinePolicy)
+      (local_state->GetBoolean(
+           policy_prefs::kCloudPolicyOverridesPlatformPolicy)
            ? POLICY_SOURCE_PRIORITY_CLOUD
            : POLICY_SOURCE_CLOUD),
       client.get(), schema_registry());
diff --git a/components/policy/core/common/policy_loader_win.cc b/components/policy/core/common/policy_loader_win.cc
index aaf9a56..a58137d1 100644
--- a/components/policy/core/common/policy_loader_win.cc
+++ b/components/policy/core/common/policy_loader_win.cc
@@ -66,7 +66,6 @@
 const char* kInsecurePolicies[] = {
     key::kChromeCleanupEnabled,
     key::kChromeCleanupReportingEnabled,
-    key::kCloudPolicyOverridesMachinePolicy,
     key::kDefaultSearchProviderEnabled,
     key::kHomepageIsNewTabPage,
     key::kHomepageLocation,
diff --git a/components/policy/core/common/policy_pref_names.cc b/components/policy/core/common/policy_pref_names.cc
index a3841d55..c5c3c58 100644
--- a/components/policy/core/common/policy_pref_names.cc
+++ b/components/policy/core/common/policy_pref_names.cc
@@ -37,7 +37,7 @@
 
 // Boolean that specifies whether the cloud policy will override conflicting
 // machine policy.
-const char kCloudPolicyOverridesMachinePolicy[] = "policy.cloud_override";
+const char kCloudPolicyOverridesPlatformPolicy[] = "policy.cloud_override";
 
 }  // namespace policy_prefs
 }  // namespace policy
diff --git a/components/policy/core/common/policy_pref_names.h b/components/policy/core/common/policy_pref_names.h
index f23328c5..ed1a9b1 100644
--- a/components/policy/core/common/policy_pref_names.h
+++ b/components/policy/core/common/policy_pref_names.h
@@ -17,7 +17,7 @@
 POLICY_EXPORT extern const char kUrlWhitelist[];
 POLICY_EXPORT extern const char kUserPolicyRefreshRate[];
 POLICY_EXPORT extern const char kCloudManagementEnrollmentMandatory[];
-POLICY_EXPORT extern const char kCloudPolicyOverridesMachinePolicy[];
+POLICY_EXPORT extern const char kCloudPolicyOverridesPlatformPolicy[];
 
 }  // namespace policy_prefs
 }  // namespace policy
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 58d9eaa..43ec74cf 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -11089,7 +11089,8 @@
       'name': 'PacHttpsUrlStrippingEnabled',
       'type': 'main',
       'schema': { 'type': 'boolean' },
-      'supported_on': [ 'chrome.*:52-75', 'chrome_os:52-75' ],
+      'supported_on': [ 'chrome.*:52-74', 'chrome_os:52-74' ],
+      'deprecated': True,
       'features': {
         'dynamic_refresh': False,
         'per_profile': False,
@@ -12294,25 +12295,25 @@
       'desc': '''If "OffHours" policy is set, then the specified device policies are ignored (use the default settings of these policies) during the defined time intervals. Device policies are re-applied by Chrome on every event when "OffHours" period starts or ends. User will be notified and forced to sign out when "OffHours" time end and device policy settings are changed (e.g. when user is logged in not with an allowed account).''',
     },
     {
-      'name': 'CloudPolicyOverridesMachinePolicy',
+      'name': 'CloudPolicyOverridesPlatformPolicy',
       'type': 'main',
       'schema': { 'type': 'boolean'},
-      'supported_on': ['chrome.*:62-'],
+      'supported_on': ['chrome.*:65-'],
       'features': {
         'dynamic_refresh': False,
         'per_profile': False,
       },
       'example_value': False,
       'id': 381,
-      'caption': '''<ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> cloud policy overrides Machine policy.''',
+      'caption': '''<ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> cloud policy overrides Platform policy.''',
       'tags': [],
       'future': True,
       'desc': '''
-      If the policy is set to true, cloud  policy takes precedence if it conflicts with machine policy.
-      If the policy is set to false or not configured, machine policy takes precedence if it conflicts with cloud policy.
-      For more details about policy priority, please visit: https://support.google.com/chrome?p=set_chrome_policies_for_devices
+      If the policy is set to true, cloud  policy takes precedence if it conflicts with platform policy.
+      If the policy is set to false or not configured, platform policy takes precedence if it conflicts with cloud policy.
 
-      This policy is available only on Windows instances that are joined to a <ph name="MS_AD_NAME">Microsoft® Active Directory®</ph> domain. or Windows 10 Pro or Enterprise instances that enrolled for device management.''',
+      This policy is only available as a platform.
+      ''',
     },
     {
       'name': 'PromptForDownloadLocation',
@@ -14387,7 +14388,7 @@
 
       When this policy is left unset, Internet Explorer will auto-detect <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>'s own executable path when launching <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> from Internet Explorer.
 
-      When this policy is set, it will be used to launch <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> when switching launching <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> from Internet Explorer.
+      When this policy is set, it will be used to launch <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> when launching <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> from Internet Explorer.
 
       This policy can be set to an executable file path, or ${chrome} to auto-detect Chrome's install location.''',
     },
diff --git a/components/signin/core/browser/account_tracker_service.h b/components/signin/core/browser/account_tracker_service.h
index 3e81b78..5bf928b49 100644
--- a/components/signin/core/browser/account_tracker_service.h
+++ b/components/signin/core/browser/account_tracker_service.h
@@ -34,7 +34,16 @@
 }
 
 namespace identity {
-class IdentityTestEnvironment;
+class IdentityManager;
+void SimulateSuccessfulFetchOfAccountInfo(IdentityManager*,
+                                          const std::string&,
+                                          const std::string&,
+                                          const std::string&,
+                                          const std::string&,
+                                          const std::string&,
+                                          const std::string&,
+                                          const std::string&,
+                                          const std::string&);
 }
 
 // AccountTrackerService is a KeyedService that retrieves and caches GAIA
@@ -137,7 +146,16 @@
 
  private:
   friend class AccountFetcherService;
-  friend class identity::IdentityTestEnvironment;
+  friend void identity::SimulateSuccessfulFetchOfAccountInfo(
+      identity::IdentityManager*,
+      const std::string&,
+      const std::string&,
+      const std::string&,
+      const std::string&,
+      const std::string&,
+      const std::string&,
+      const std::string&,
+      const std::string&);
 
   void NotifyAccountUpdated(const AccountInfo& account_info);
   void NotifyAccountUpdateFailed(const std::string& account_id);
diff --git a/components/sync/engine_impl/net/server_connection_manager.h b/components/sync/engine_impl/net/server_connection_manager.h
index cba2b8ad..18b4905 100644
--- a/components/sync/engine_impl/net/server_connection_manager.h
+++ b/components/sync/engine_impl/net/server_connection_manager.h
@@ -115,10 +115,6 @@
                       const std::string& payload,
                       HttpResponse* response) = 0;
 
-    // Immediately abandons a pending HTTP POST request and unblocks caller
-    // in Init.
-    virtual void Abort() = 0;
-
     bool ReadBufferResponse(std::string* buffer_out,
                             HttpResponse* response,
                             bool require_response);
diff --git a/components/sync/engine_impl/net/sync_server_connection_manager.cc b/components/sync/engine_impl/net/sync_server_connection_manager.cc
index c6c0e1b8..07fe6b7 100644
--- a/components/sync/engine_impl/net/sync_server_connection_manager.cc
+++ b/components/sync/engine_impl/net/sync_server_connection_manager.cc
@@ -93,11 +93,6 @@
   return true;
 }
 
-void SyncBridgedConnection::Abort() {
-  DCHECK(post_provider_);
-  post_provider_->Abort();
-}
-
 void SyncBridgedConnection::OnSignalReceived() {
   DCHECK(post_provider_);
   post_provider_->Abort();
diff --git a/components/sync/engine_impl/net/sync_server_connection_manager.h b/components/sync/engine_impl/net/sync_server_connection_manager.h
index 76190e11..1848b67 100644
--- a/components/sync/engine_impl/net/sync_server_connection_manager.h
+++ b/components/sync/engine_impl/net/sync_server_connection_manager.h
@@ -34,8 +34,6 @@
             const std::string& payload,
             HttpResponse* response) override;
 
-  void Abort() override;
-
   void OnSignalReceived() override;
 
  private:
diff --git a/components/sync/test/fake_server/fake_server_http_post_provider.cc b/components/sync/test/fake_server/fake_server_http_post_provider.cc
index 42f316b..75b12d9 100644
--- a/components/sync/test/fake_server/fake_server_http_post_provider.cc
+++ b/components/sync/test/fake_server/fake_server_http_post_provider.cc
@@ -19,21 +19,6 @@
 // static
 bool FakeServerHttpPostProvider::network_enabled_ = true;
 
-namespace {
-
-void HandleCommandOnFakeServerThread(base::WeakPtr<FakeServer> fake_server,
-                                     const std::string& request,
-                                     int* http_status_code,
-                                     std::string* response,
-                                     base::WaitableEvent* completion_event) {
-  if (fake_server) {
-    *http_status_code = fake_server->HandleCommand(request, response);
-  }
-  completion_event->Signal();
-}
-
-}  // namespace
-
 FakeServerHttpPostProviderFactory::FakeServerHttpPostProviderFactory(
     const base::WeakPtr<FakeServer>& fake_server,
     scoped_refptr<base::SequencedTaskRunner> fake_server_task_runner)
@@ -62,7 +47,11 @@
     const base::WeakPtr<FakeServer>& fake_server,
     scoped_refptr<base::SequencedTaskRunner> fake_server_task_runner)
     : fake_server_(fake_server),
-      fake_server_task_runner_(fake_server_task_runner) {}
+      fake_server_task_runner_(fake_server_task_runner),
+      synchronous_post_completion_(
+          base::WaitableEvent::ResetPolicy::AUTOMATIC,
+          base::WaitableEvent::InitialState::NOT_SIGNALED),
+      aborted_(false) {}
 
 FakeServerHttpPostProvider::~FakeServerHttpPostProvider() {}
 
@@ -93,20 +82,19 @@
     return false;
   }
 
+  synchronous_post_completion_.Reset();
+  aborted_ = false;
+
   // It is assumed that a POST is being made to /command.
   int post_status_code = -1;
   std::string post_response;
 
-  base::WaitableEvent post_complete(
-      base::WaitableEvent::ResetPolicy::AUTOMATIC,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-
   bool result = fake_server_task_runner_->PostTask(
       FROM_HERE,
-      base::BindOnce(&HandleCommandOnFakeServerThread, fake_server_,
-                     request_content_, base::Unretained(&post_status_code),
-                     base::Unretained(&post_response),
-                     base::Unretained(&post_complete)));
+      base::BindOnce(
+          &FakeServerHttpPostProvider::HandleCommandOnFakeServerThread,
+          base::RetainedRef(this), base::Unretained(&post_status_code),
+          base::Unretained(&post_response)));
 
   if (!result) {
     response_.clear();
@@ -115,14 +103,10 @@
     return false;
   }
 
-  // Note: This is a potential deadlock. Here we're on the sync thread, and
-  // we're waiting for something to happen on the UI thread (where the
-  // FakeServer lives). If at the same time, ProfileSyncService is trying to
-  // Stop() the sync thread, we're deadlocked. For a lack of better ideas, let's
-  // just give up after a few seconds.
-  // TODO(crbug.com/869404): Maybe the FakeServer should live on its own thread.
-  if (!post_complete.TimedWait(base::TimeDelta::FromSeconds(5))) {
-    *net_error_code = net::ERR_TIMED_OUT;
+  synchronous_post_completion_.Wait();
+
+  if (aborted_) {
+    *net_error_code = net::ERR_ABORTED;
     return false;
   }
 
@@ -147,7 +131,14 @@
   return std::string();
 }
 
-void FakeServerHttpPostProvider::Abort() {}
+void FakeServerHttpPostProvider::Abort() {
+  // The sync thread could be blocked in MakeSynchronousPost(), waiting
+  // for HandleCommandOnFakeServerThread() to be processed and completed.
+  // This causes an immediate unblocking which will be returned as
+  // net::ERR_ABORTED.
+  aborted_ = true;
+  synchronous_post_completion_.Signal();
+}
 
 void FakeServerHttpPostProvider::DisableNetwork() {
   network_enabled_ = false;
@@ -157,4 +148,18 @@
   network_enabled_ = true;
 }
 
+void FakeServerHttpPostProvider::HandleCommandOnFakeServerThread(
+    int* http_status_code,
+    std::string* response) {
+  DCHECK(fake_server_task_runner_->RunsTasksInCurrentSequence());
+
+  if (!fake_server_ || aborted_) {
+    // Command explicitly aborted or server destroyed.
+    return;
+  }
+
+  *http_status_code = fake_server_->HandleCommand(request_content_, response);
+  synchronous_post_completion_.Signal();
+}
+
 }  // namespace fake_server
diff --git a/components/sync/test/fake_server/fake_server_http_post_provider.h b/components/sync/test/fake_server/fake_server_http_post_provider.h
index f7092dd3..ea8ed50 100644
--- a/components/sync/test/fake_server/fake_server_http_post_provider.h
+++ b/components/sync/test/fake_server/fake_server_http_post_provider.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_SYNC_TEST_FAKE_SERVER_FAKE_SERVER_HTTP_POST_PROVIDER_H_
 #define COMPONENTS_SYNC_TEST_FAKE_SERVER_FAKE_SERVER_HTTP_POST_PROVIDER_H_
 
+#include <atomic>
 #include <string>
 
 #include "base/callback.h"
@@ -54,6 +55,9 @@
  private:
   friend class base::RefCountedThreadSafe<FakeServerHttpPostProvider>;
 
+  void HandleCommandOnFakeServerThread(int* http_status_code,
+                                       std::string* response);
+
   static bool network_enabled_;
 
   // |fake_server_| should only be dereferenced on the same thread as
@@ -61,6 +65,9 @@
   base::WeakPtr<FakeServer> fake_server_;
   scoped_refptr<base::SequencedTaskRunner> fake_server_task_runner_;
 
+  base::WaitableEvent synchronous_post_completion_;
+  std::atomic_bool aborted_;
+
   std::string response_;
   std::string request_url_;
   int request_port_;
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc
index 8b9c8ff..6d52f86 100644
--- a/components/translate/core/browser/translate_prefs.cc
+++ b/components/translate/core/browser/translate_prefs.cc
@@ -193,6 +193,7 @@
   prefs_->ClearPref(kPrefTranslateDeniedCount);
   prefs_->ClearPref(kPrefTranslateIgnoredCount);
   prefs_->ClearPref(kPrefTranslateAcceptedCount);
+  prefs_->ClearPref(kPrefTranslateRecentTarget);
 
 #if defined(OS_ANDROID) || defined(OS_IOS)
   prefs_->ClearPref(kPrefTranslateAutoAlwaysCount);
diff --git a/components/viz/common/switches.cc b/components/viz/common/switches.cc
index 5d36551..0c9d3c1 100644
--- a/components/viz/common/switches.cc
+++ b/components/viz/common/switches.cc
@@ -15,6 +15,12 @@
 const char kDeadlineToSynchronizeSurfaces[] =
     "deadline-to-synchronize-surfaces";
 
+// Enable compositing individual elements via hardware overlays when
+// permitted by device.
+// Setting the flag to "single-fullscreen" will try to promote a single
+// fullscreen overlay and use it as main framebuffer where possible.
+const char kEnableHardwareOverlays[] = "enable-hardware-overlays";
+
 // Enables multi-client Surface synchronization. In practice, this indicates
 // that LayerTreeHost expects to be given a valid viz::LocalSurfaceId provided
 // by the parent compositor.
diff --git a/components/viz/common/switches.h b/components/viz/common/switches.h
index ed0d8d41..4757fd8 100644
--- a/components/viz/common/switches.h
+++ b/components/viz/common/switches.h
@@ -15,6 +15,7 @@
 
 // Keep list in alphabetical order.
 VIZ_COMMON_EXPORT extern const char kDeadlineToSynchronizeSurfaces[];
+VIZ_COMMON_EXPORT extern const char kEnableHardwareOverlays[];
 VIZ_COMMON_EXPORT extern const char kEnableSurfaceSynchronization[];
 VIZ_COMMON_EXPORT extern const char kEnableVizDevTools[];
 VIZ_COMMON_EXPORT extern const char kEnableVizHitTestDebug[];
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index e90f38a4..b98613d0 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -585,6 +585,8 @@
     "cache_storage/cache_storage_scheduler.cc",
     "cache_storage/cache_storage_scheduler.h",
     "cache_storage/cache_storage_scheduler_types.h",
+    "cache_storage/cache_storage_trace_utils.cc",
+    "cache_storage/cache_storage_trace_utils.h",
     "child_process_launcher.cc",
     "child_process_launcher.h",
     "child_process_launcher_helper.cc",
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index db93f53d..c5070575 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -683,7 +683,7 @@
                                                       VARIANT* anchor) {
   WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ANCHOR);
   AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-  if (!owner() || !IsHyperlink())
+  if (!owner() || !IsEmbeddedByParentObjectHypertext())
     return E_FAIL;
 
   // IA2 text links can have only one anchor, that is the text inside them.
@@ -709,7 +709,7 @@
     VARIANT* anchor_target) {
   WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ANCHOR_TARGET);
   AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-  if (!owner() || !IsHyperlink())
+  if (!owner() || !IsEmbeddedByParentObjectHypertext())
     return E_FAIL;
 
   // IA2 text links can have at most one target, that is when they represent an
@@ -738,7 +738,7 @@
 IFACEMETHODIMP BrowserAccessibilityComWin::get_startIndex(LONG* index) {
   WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_START_INDEX);
   AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes);
-  if (!owner() || !IsHyperlink())
+  if (!owner() || !IsEmbeddedByParentObjectHypertext())
     return E_FAIL;
 
   if (!index)
@@ -784,10 +784,10 @@
   if (!n_actions)
     return E_INVALIDARG;
 
-  // |IsHyperlink| is required for |IAccessibleHyperlink::anchor/anchorTarget|
-  // to work properly because the |IAccessibleHyperlink| interface inherits from
-  // |IAccessibleAction|.
-  if (IsHyperlink() ||
+  // |IsEmbeddedByParentObjectHypertext| is required for
+  // |IAccessibleHyperlink::anchor/anchorTarget| to work properly because the
+  // |IAccessibleHyperlink| interface inherits from |IAccessibleAction|.
+  if (IsEmbeddedByParentObjectHypertext() ||
       owner()->HasIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb)) {
     *n_actions = 1;
   } else {
@@ -1602,7 +1602,7 @@
       return E_NOINTERFACE;
     }
   } else if (iid == IID_IAccessibleHyperlink) {
-    if (!accessibility || !accessibility->IsHyperlink()) {
+    if (!accessibility || !accessibility->IsEmbeddedByParentObjectHypertext()) {
       *object = nullptr;
       return E_NOINTERFACE;
     }
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
index 8b623f1a..76bb4f8 100644
--- a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -115,6 +115,13 @@
   BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
 
   switch (event_type) {
+    case ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED: {
+      int32_t focus_id = GetTreeData().sel_focus_object_id;
+      BrowserAccessibility* focus_object = GetFromID(focus_id);
+      if (focus_object)
+        FireEvent(focus_object, ax::mojom::Event::kTextSelectionChanged);
+      break;
+    }
     case ui::AXEventGenerator::Event::CHECKED_STATE_CHANGED:
       FireEvent(node, ax::mojom::Event::kCheckedStateChanged);
       break;
diff --git a/content/browser/appcache/appcache.cc b/content/browser/appcache/appcache.cc
index 3f52f7ff..42878e6 100644
--- a/content/browser/appcache/appcache.cc
+++ b/content/browser/appcache/appcache.cc
@@ -174,7 +174,7 @@
   cache_record->group_id = group->group_id();
   cache_record->online_wildcard = online_whitelist_all_;
   cache_record->update_time = update_time_;
-  cache_record->cache_size = 0;
+  cache_record->cache_size = cache_size_;
 
   for (const auto& pair : entries_) {
     entries->push_back(AppCacheDatabase::EntryRecord());
@@ -184,7 +184,6 @@
     record.flags = pair.second.types();
     record.response_id = pair.second.response_id();
     record.response_size = pair.second.response_size();
-    cache_record->cache_size += record.response_size;
   }
 
   const url::Origin origin = url::Origin::Create(group->manifest_url());
diff --git a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
index cfd83ab8..dcc13b2 100644
--- a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
@@ -455,6 +455,7 @@
             origin(), CacheStorageOwner::kBackgroundFetch);
     cache_storage.value()->HasCache(
         cache_name,
+        /* trace_id= */ 0,
         base::BindOnce(&BackgroundFetchDataManagerTest::DidFindCache,
                        base::Unretained(this), run_loop.QuitClosure(),
                        &result));
@@ -476,6 +477,7 @@
     cache_storage.value()->MatchCache(
         kExampleUniqueId, BackgroundFetchSettledFetch::CloneRequest(request),
         std::move(match_options),
+        /* trace_id= */ 0,
         base::BindOnce(&BackgroundFetchDataManagerTest::DidMatchCache,
                        base::Unretained(this), run_loop.QuitClosure(),
                        &result));
@@ -493,6 +495,7 @@
               origin(), CacheStorageOwner::kBackgroundFetch);
       cache_storage.value()->OpenCache(
           /* cache_name= */ kExampleUniqueId,
+          /* trace_id= */ 0,
           base::BindOnce(&BackgroundFetchDataManagerTest::DidOpenCache,
                          base::Unretained(this), run_loop.QuitClosure(),
                          &handle));
@@ -514,6 +517,7 @@
       operation_ptr_vec[0]->match_options->ignore_search = true;
       handle.value()->BatchOperation(
           std::move(operation_ptr_vec), /* fail_on_duplicates= */ true,
+          /* trace_id= */ 0,
           base::BindOnce(&BackgroundFetchDataManagerTest::DidDeleteFromCache,
                          base::Unretained(this), run_loop.QuitClosure()),
           base::DoNothing());
@@ -532,6 +536,7 @@
               origin(), CacheStorageOwner::kBackgroundFetch);
       cache_storage.value()->OpenCache(
           /* cache_name= */ kExampleUniqueId,
+          /* trace_id= */ 0,
           base::BindOnce(&BackgroundFetchDataManagerTest::DidOpenCache,
                          base::Unretained(this), run_loop.QuitClosure(),
                          &handle));
@@ -550,6 +555,7 @@
       operation_ptr_vec[0]->response = std::move(response);
       handle.value()->BatchOperation(
           std::move(operation_ptr_vec), /* fail_on_duplicates= */ true,
+          /* trace_id= */ 0,
           base::BindOnce(&BackgroundFetchDataManagerTest::DidDeleteFromCache,
                          base::Unretained(this), run_loop.QuitClosure()),
           base::DoNothing());
diff --git a/content/browser/background_fetch/storage/cache_entry_handler_impl.cc b/content/browser/background_fetch/storage/cache_entry_handler_impl.cc
index bd6a046..b9f2178 100644
--- a/content/browser/background_fetch/storage/cache_entry_handler_impl.cc
+++ b/content/browser/background_fetch/storage/cache_entry_handler_impl.cc
@@ -21,7 +21,8 @@
 
 std::unique_ptr<PutContext> CacheEntryHandlerImpl::CreatePutContext(
     blink::mojom::FetchAPIRequestPtr request,
-    blink::mojom::FetchAPIResponsePtr response) {
+    blink::mojom::FetchAPIResponsePtr response,
+    int64_t trace_id) {
   blink::mojom::BlobPtr response_blob;
   uint64_t response_blob_size = blink::BlobUtils::kUnknownSize;
   blink::mojom::BlobPtr request_blob;
@@ -38,7 +39,7 @@
 
   return std::make_unique<PutContext>(
       std::move(request), std::move(response), std::move(response_blob),
-      response_blob_size, std::move(request_blob), request_blob_size);
+      response_blob_size, std::move(request_blob), request_blob_size, trace_id);
 }
 
 void CacheEntryHandlerImpl::PopulateBody(
@@ -85,4 +86,4 @@
 }
 
 }  // namespace background_fetch
-}  // namespace content
\ No newline at end of file
+}  // namespace content
diff --git a/content/browser/background_fetch/storage/cache_entry_handler_impl.h b/content/browser/background_fetch/storage/cache_entry_handler_impl.h
index 89156eb..7f98dbf 100644
--- a/content/browser/background_fetch/storage/cache_entry_handler_impl.h
+++ b/content/browser/background_fetch/storage/cache_entry_handler_impl.h
@@ -22,7 +22,8 @@
   // CacheStorageCacheEntryHandler implementation:
   std::unique_ptr<PutContext> CreatePutContext(
       blink::mojom::FetchAPIRequestPtr request,
-      blink::mojom::FetchAPIResponsePtr response) override;
+      blink::mojom::FetchAPIResponsePtr response,
+      int64_t trace_id) override;
   void PopulateResponseBody(scoped_refptr<BlobDataHandle> data_handle,
                             blink::mojom::FetchAPIResponse* response) override;
   void PopulateRequestBody(scoped_refptr<BlobDataHandle> data_handle,
diff --git a/content/browser/background_fetch/storage/create_metadata_task.cc b/content/browser/background_fetch/storage/create_metadata_task.cc
index fdf6fae2..50eeb213 100644
--- a/content/browser/background_fetch/storage/create_metadata_task.cc
+++ b/content/browser/background_fetch/storage/create_metadata_task.cc
@@ -21,6 +21,7 @@
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/common/background_fetch/background_fetch_types.h"
 #include "content/common/service_worker/service_worker_utils.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
 
@@ -354,6 +355,11 @@
 
 void CreateMetadataTask::DidStoreMetadata(
     blink::ServiceWorkerStatusCode status) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageMigrationTask::DidStoreMetadata",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   switch (ToDatabaseStatus(status)) {
     case DatabaseStatus::kOk:
       break;
@@ -367,13 +373,19 @@
   // Create cache entries.
   CacheStorageHandle cache_storage = GetOrOpenCacheStorage(registration_id_);
   cache_storage.value()->OpenCache(
-      /* cache_name= */ registration_id_.unique_id(),
+      /* cache_name= */ registration_id_.unique_id(), trace_id,
       base::BindOnce(&CreateMetadataTask::DidOpenCache,
-                     weak_factory_.GetWeakPtr()));
+                     weak_factory_.GetWeakPtr(), trace_id));
 }
 
-void CreateMetadataTask::DidOpenCache(CacheStorageCacheHandle handle,
+void CreateMetadataTask::DidOpenCache(int64_t trace_id,
+                                      CacheStorageCacheHandle handle,
                                       blink::mojom::CacheStorageError error) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageMigrationTask::DidReopenCache",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (error != blink::mojom::CacheStorageError::kSuccess) {
     SetStorageErrorAndFinish(BackgroundFetchStorageError::kCacheStorageError);
     return;
@@ -396,7 +408,7 @@
   }
 
   handle.value()->BatchOperation(
-      std::move(operations), /* fail_on_duplicates= */ false,
+      std::move(operations), /* fail_on_duplicates= */ false, trace_id,
       base::BindOnce(&CreateMetadataTask::DidStoreRequests,
                      weak_factory_.GetWeakPtr(), handle.Clone()),
       base::DoNothing());
diff --git a/content/browser/background_fetch/storage/create_metadata_task.h b/content/browser/background_fetch/storage/create_metadata_task.h
index f93e1a7e..4b44a54 100644
--- a/content/browser/background_fetch/storage/create_metadata_task.h
+++ b/content/browser/background_fetch/storage/create_metadata_task.h
@@ -59,7 +59,8 @@
 
   void InitializeMetadataProto();
 
-  void DidOpenCache(CacheStorageCacheHandle handle,
+  void DidOpenCache(int64_t trace_id,
+                    CacheStorageCacheHandle handle,
                     blink::mojom::CacheStorageError error);
 
   void DidStoreRequests(CacheStorageCacheHandle handle,
diff --git a/content/browser/background_fetch/storage/delete_registration_task.cc b/content/browser/background_fetch/storage/delete_registration_task.cc
index 07af620..c6e4e061 100644
--- a/content/browser/background_fetch/storage/delete_registration_task.cc
+++ b/content/browser/background_fetch/storage/delete_registration_task.cc
@@ -13,6 +13,7 @@
 #include "content/browser/background_fetch/storage/database_helpers.h"
 #include "content/browser/cache_storage/cache_storage_manager.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 
 namespace content {
 
@@ -57,6 +58,10 @@
 DeleteRegistrationTask::~DeleteRegistrationTask() = default;
 
 void DeleteRegistrationTask::Start() {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "DeleteRegistrationTask::Start",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   base::RepeatingClosure barrier_closure = base::BarrierClosure(
       2u, base::BindOnce(&DeleteRegistrationTask::FinishWithError,
                          weak_factory_.GetWeakPtr(),
@@ -74,9 +79,9 @@
 
   CacheStorageHandle cache_storage = GetOrOpenCacheStorage(origin_, unique_id_);
   cache_storage.value()->DoomCache(
-      /* cache_name= */ unique_id_,
+      /* cache_name= */ unique_id_, trace_id,
       base::BindOnce(&DeleteRegistrationTask::DidDeleteCache,
-                     weak_factory_.GetWeakPtr(), barrier_closure));
+                     weak_factory_.GetWeakPtr(), barrier_closure, trace_id));
 }
 
 void DeleteRegistrationTask::DidGetRegistration(
@@ -132,7 +137,11 @@
 
 void DeleteRegistrationTask::DidDeleteCache(
     base::OnceClosure done_closure,
+    int64_t trace_id,
     blink::mojom::CacheStorageError error) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "DeleteRegistrationTask::DidDeleteCache",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN);
   if (error != blink::mojom::CacheStorageError::kSuccess &&
       error != blink::mojom::CacheStorageError::kErrorNotFound) {
     SetStorageError(BackgroundFetchStorageError::kCacheStorageError);
diff --git a/content/browser/background_fetch/storage/delete_registration_task.h b/content/browser/background_fetch/storage/delete_registration_task.h
index b4b3fe0..e083f9e 100644
--- a/content/browser/background_fetch/storage/delete_registration_task.h
+++ b/content/browser/background_fetch/storage/delete_registration_task.h
@@ -39,6 +39,7 @@
                              blink::ServiceWorkerStatusCode status);
 
   void DidDeleteCache(base::OnceClosure done_closure,
+                      int64_t trace_id,
                       blink::mojom::CacheStorageError error);
 
   void FinishWithError(blink::mojom::BackgroundFetchError error) override;
diff --git a/content/browser/background_fetch/storage/get_request_blob_task.cc b/content/browser/background_fetch/storage/get_request_blob_task.cc
index 9535a35f..5cb25dd 100644
--- a/content/browser/background_fetch/storage/get_request_blob_task.cc
+++ b/content/browser/background_fetch/storage/get_request_blob_task.cc
@@ -7,6 +7,7 @@
 #include "content/browser/background_fetch/background_fetch_request_match_params.h"
 #include "content/browser/background_fetch/storage/database_helpers.h"
 #include "content/common/background_fetch/background_fetch_types.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 
 namespace content {
 namespace background_fetch {
@@ -25,15 +26,22 @@
 GetRequestBlobTask::~GetRequestBlobTask() = default;
 
 void GetRequestBlobTask::Start() {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "GetRequestBlobTask::Start",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
   CacheStorageHandle cache_storage = GetOrOpenCacheStorage(registration_id_);
   cache_storage.value()->OpenCache(
-      /* cache_name= */ registration_id_.unique_id(),
+      /* cache_name= */ registration_id_.unique_id(), trace_id,
       base::BindOnce(&GetRequestBlobTask::DidOpenCache,
-                     weak_factory_.GetWeakPtr()));
+                     weak_factory_.GetWeakPtr(), trace_id));
 }
 
-void GetRequestBlobTask::DidOpenCache(CacheStorageCacheHandle handle,
+void GetRequestBlobTask::DidOpenCache(int64_t trace_id,
+                                      CacheStorageCacheHandle handle,
                                       blink::mojom::CacheStorageError error) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "GetRequestBlobTask::DidOpenCache",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   if (error != blink::mojom::CacheStorageError::kSuccess) {
     SetStorageErrorAndFinish(BackgroundFetchStorageError::kCacheStorageError);
     return;
@@ -46,15 +54,19 @@
                                     request_info_->request_index());
 
   handle.value()->GetAllMatchedEntries(
-      std::move(request), /* match_options= */ nullptr,
+      std::move(request), /* match_options= */ nullptr, trace_id,
       base::BindOnce(&GetRequestBlobTask::DidMatchRequest,
-                     weak_factory_.GetWeakPtr(), handle.Clone()));
+                     weak_factory_.GetWeakPtr(), handle.Clone(), trace_id));
 }
 
 void GetRequestBlobTask::DidMatchRequest(
     CacheStorageCacheHandle handle,
+    int64_t trace_id,
     blink::mojom::CacheStorageError error,
     std::vector<CacheStorageCache::CacheEntry> entries) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "GetRequestBlobTask::DidMatchRequest",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN);
+
   if (error != blink::mojom::CacheStorageError::kSuccess || entries.empty()) {
     SetStorageErrorAndFinish(BackgroundFetchStorageError::kCacheStorageError);
     return;
diff --git a/content/browser/background_fetch/storage/get_request_blob_task.h b/content/browser/background_fetch/storage/get_request_blob_task.h
index 1dd98e8..2a295af 100644
--- a/content/browser/background_fetch/storage/get_request_blob_task.h
+++ b/content/browser/background_fetch/storage/get_request_blob_task.h
@@ -33,10 +33,12 @@
   void Start() override;
 
  private:
-  void DidOpenCache(CacheStorageCacheHandle handle,
+  void DidOpenCache(int64_t trace_id,
+                    CacheStorageCacheHandle handle,
                     blink::mojom::CacheStorageError error);
 
   void DidMatchRequest(CacheStorageCacheHandle handle,
+                       int64_t trace_id,
                        blink::mojom::CacheStorageError error,
                        std::vector<CacheStorageCache::CacheEntry> entries);
 
diff --git a/content/browser/background_fetch/storage/mark_request_complete_task.cc b/content/browser/background_fetch/storage/mark_request_complete_task.cc
index b8821a56..e117216 100644
--- a/content/browser/background_fetch/storage/mark_request_complete_task.cc
+++ b/content/browser/background_fetch/storage/mark_request_complete_task.cc
@@ -18,6 +18,7 @@
 #include "content/common/service_worker/service_worker_utils.h"
 #include "services/network/public/cpp/cors/cors.h"
 #include "storage/browser/blob/blob_impl.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 #include "third_party/blink/public/mojom/blob/blob.mojom.h"
 
 namespace content {
@@ -107,6 +108,11 @@
 void MarkRequestCompleteTask::DidGetIsQuotaAvailable(
     base::OnceClosure done_closure,
     bool is_available) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "MarkRequestCompleteTask::DidGetIsQuotaAvailable",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (!is_available) {
     FinishWithError(blink::mojom::BackgroundFetchError::QUOTA_EXCEEDED);
     return;
@@ -114,9 +120,10 @@
 
   CacheStorageHandle cache_storage = GetOrOpenCacheStorage(registration_id_);
   cache_storage.value()->OpenCache(
-      /* cache_name= */ registration_id_.unique_id(),
+      /* cache_name= */ registration_id_.unique_id(), trace_id,
       base::BindOnce(&MarkRequestCompleteTask::DidOpenCache,
-                     weak_factory_.GetWeakPtr(), std::move(done_closure)));
+                     weak_factory_.GetWeakPtr(), std::move(done_closure),
+                     trace_id));
 }
 
 void MarkRequestCompleteTask::PopulateResponseBody(
@@ -144,8 +151,13 @@
 
 void MarkRequestCompleteTask::DidOpenCache(
     base::OnceClosure done_closure,
+    int64_t trace_id,
     CacheStorageCacheHandle handle,
     blink::mojom::CacheStorageError error) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "MarkRequestCompleteTask::DidOpenCache",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   if (error != blink::mojom::CacheStorageError::kSuccess) {
     SetStorageError(BackgroundFetchStorageError::kCacheStorageError);
     CreateAndStoreCompletedRequest(std::move(done_closure));
@@ -165,6 +177,7 @@
   // overwritten here, it should be written back.
   handle.value()->Put(
       std::move(request), BackgroundFetchSettledFetch::CloneResponse(response_),
+      trace_id,
       base::BindOnce(&MarkRequestCompleteTask::DidWriteToCache,
                      weak_factory_.GetWeakPtr(), std::move(handle),
                      std::move(done_closure)));
diff --git a/content/browser/background_fetch/storage/mark_request_complete_task.h b/content/browser/background_fetch/storage/mark_request_complete_task.h
index 8d4bb259..a4993873 100644
--- a/content/browser/background_fetch/storage/mark_request_complete_task.h
+++ b/content/browser/background_fetch/storage/mark_request_complete_task.h
@@ -44,6 +44,7 @@
                               bool is_available);
 
   void DidOpenCache(base::OnceClosure done_closure,
+                    int64_t trace_id,
                     CacheStorageCacheHandle handle,
                     blink::mojom::CacheStorageError error);
 
diff --git a/content/browser/background_fetch/storage/match_requests_task.cc b/content/browser/background_fetch/storage/match_requests_task.cc
index 974b212f..54d2153 100644
--- a/content/browser/background_fetch/storage/match_requests_task.cc
+++ b/content/browser/background_fetch/storage/match_requests_task.cc
@@ -14,6 +14,7 @@
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/common/service_worker/service_worker_utils.h"
 #include "services/network/public/cpp/cors/cors.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
 
 namespace content {
@@ -34,15 +35,23 @@
 MatchRequestsTask::~MatchRequestsTask() = default;
 
 void MatchRequestsTask::Start() {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "MatchRequestsTask::Start",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
   CacheStorageHandle cache_storage = GetOrOpenCacheStorage(registration_id_);
   cache_storage.value()->OpenCache(
-      /* cache_name= */ registration_id_.unique_id(),
+      /* cache_name= */ registration_id_.unique_id(), trace_id,
       base::BindOnce(&MatchRequestsTask::DidOpenCache,
-                     weak_factory_.GetWeakPtr()));
+                     weak_factory_.GetWeakPtr(), trace_id));
 }
 
-void MatchRequestsTask::DidOpenCache(CacheStorageCacheHandle handle,
+void MatchRequestsTask::DidOpenCache(int64_t trace_id,
+                                     CacheStorageCacheHandle handle,
                                      blink::mojom::CacheStorageError error) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "MatchRequestsTask::DidOpenCache",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (error != blink::mojom::CacheStorageError::kSuccess) {
     SetStorageErrorAndFinish(BackgroundFetchStorageError::kCacheStorageError);
     return;
@@ -72,14 +81,19 @@
   query_options->ignore_method = true;
 
   handle_.value()->GetAllMatchedEntries(
-      std::move(request), std::move(query_options),
+      std::move(request), std::move(query_options), trace_id,
       base::BindOnce(&MatchRequestsTask::DidGetAllMatchedEntries,
-                     weak_factory_.GetWeakPtr()));
+                     weak_factory_.GetWeakPtr(), trace_id));
 }
 
 void MatchRequestsTask::DidGetAllMatchedEntries(
+    int64_t trace_id,
     blink::mojom::CacheStorageError error,
     std::vector<CacheStorageCache::CacheEntry> entries) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "MatchRequestsTask::DidGetAllMatchedEntries",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN);
+
   if (error != blink::mojom::CacheStorageError::kSuccess) {
     SetStorageErrorAndFinish(BackgroundFetchStorageError::kCacheStorageError);
     return;
diff --git a/content/browser/background_fetch/storage/match_requests_task.h b/content/browser/background_fetch/storage/match_requests_task.h
index aa073833..9be00f6 100644
--- a/content/browser/background_fetch/storage/match_requests_task.h
+++ b/content/browser/background_fetch/storage/match_requests_task.h
@@ -42,10 +42,12 @@
   void Start() override;
 
  private:
-  void DidOpenCache(CacheStorageCacheHandle handle,
+  void DidOpenCache(int64_t trace_id,
+                    CacheStorageCacheHandle handle,
                     blink::mojom::CacheStorageError error);
 
   void DidGetAllMatchedEntries(
+      int64_t trace_id,
       blink::mojom::CacheStorageError error,
       std::vector<CacheStorageCache::CacheEntry> entries);
 
diff --git a/content/browser/cache_storage/cache_storage.cc b/content/browser/cache_storage/cache_storage.cc
index 9e0249a6..647e4e5 100644
--- a/content/browser/cache_storage/cache_storage.cc
+++ b/content/browser/cache_storage/cache_storage.cc
@@ -28,6 +28,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/traced_value.h"
 #include "content/browser/cache_storage/cache_storage.pb.h"
 #include "content/browser/cache_storage/cache_storage_cache.h"
 #include "content/browser/cache_storage/cache_storage_cache_handle.h"
@@ -36,6 +38,7 @@
 #include "content/browser/cache_storage/cache_storage_manager.h"
 #include "content/browser/cache_storage/cache_storage_quota_client.h"
 #include "content/browser/cache_storage/cache_storage_scheduler.h"
+#include "content/browser/cache_storage/cache_storage_trace_utils.h"
 #include "content/common/background_fetch/background_fetch_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "crypto/symmetric_key.h"
@@ -596,6 +599,7 @@
 }
 
 void CacheStorage::OpenCache(const std::string& cache_name,
+                             int64_t trace_id,
                              CacheAndErrorCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -613,11 +617,12 @@
   scheduler_->ScheduleOperation(
       CacheStorageSchedulerOp::kOpen,
       base::BindOnce(&CacheStorage::OpenCacheImpl, weak_factory_.GetWeakPtr(),
-                     cache_name,
+                     cache_name, trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
 void CacheStorage::HasCache(const std::string& cache_name,
+                            int64_t trace_id,
                             BoolAndErrorCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -631,11 +636,12 @@
   scheduler_->ScheduleOperation(
       CacheStorageSchedulerOp::kHas,
       base::BindOnce(&CacheStorage::HasCacheImpl, weak_factory_.GetWeakPtr(),
-                     cache_name,
+                     cache_name, trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
 void CacheStorage::DoomCache(const std::string& cache_name,
+                             int64_t trace_id,
                              ErrorCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -649,11 +655,11 @@
   scheduler_->ScheduleOperation(
       CacheStorageSchedulerOp::kDelete,
       base::BindOnce(&CacheStorage::DoomCacheImpl, weak_factory_.GetWeakPtr(),
-                     cache_name,
+                     cache_name, trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
-void CacheStorage::EnumerateCaches(IndexCallback callback) {
+void CacheStorage::EnumerateCaches(int64_t trace_id, IndexCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   if (!initialized_)
@@ -666,13 +672,14 @@
   scheduler_->ScheduleOperation(
       CacheStorageSchedulerOp::kKeys,
       base::BindOnce(&CacheStorage::EnumerateCachesImpl,
-                     weak_factory_.GetWeakPtr(),
+                     weak_factory_.GetWeakPtr(), trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
 void CacheStorage::MatchCache(const std::string& cache_name,
                               blink::mojom::FetchAPIRequestPtr request,
                               blink::mojom::CacheQueryOptionsPtr match_options,
+                              int64_t trace_id,
                               CacheStorageCache::ResponseCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -687,12 +694,14 @@
       CacheStorageSchedulerOp::kMatch,
       base::BindOnce(&CacheStorage::MatchCacheImpl, weak_factory_.GetWeakPtr(),
                      cache_name, std::move(request), std::move(match_options),
+                     trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
 void CacheStorage::MatchAllCaches(
     blink::mojom::FetchAPIRequestPtr request,
     blink::mojom::CacheQueryOptionsPtr match_options,
+    int64_t trace_id,
     CacheStorageCache::ResponseCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -707,13 +716,14 @@
       CacheStorageSchedulerOp::kMatchAll,
       base::BindOnce(&CacheStorage::MatchAllCachesImpl,
                      weak_factory_.GetWeakPtr(), std::move(request),
-                     std::move(match_options),
+                     std::move(match_options), trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
 void CacheStorage::WriteToCache(const std::string& cache_name,
                                 blink::mojom::FetchAPIRequestPtr request,
                                 blink::mojom::FetchAPIResponsePtr response,
+                                int64_t trace_id,
                                 CacheStorage::ErrorCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -728,7 +738,7 @@
       CacheStorageSchedulerOp::kPut,
       base::BindOnce(&CacheStorage::WriteToCacheImpl,
                      weak_factory_.GetWeakPtr(), cache_name, std::move(request),
-                     std::move(response),
+                     std::move(response), trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
@@ -873,7 +883,12 @@
 }
 
 void CacheStorage::OpenCacheImpl(const std::string& cache_name,
+                                 int64_t trace_id,
                                  CacheAndErrorCallback callback) {
+  TRACE_EVENT_WITH_FLOW1("CacheStorage", "CacheStorage::OpenCacheImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "cache_name", cache_name);
   CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_name);
   if (cache_handle.value()) {
     std::move(callback).Run(std::move(cache_handle),
@@ -884,15 +899,21 @@
   cache_loader_->PrepareNewCacheDestination(
       cache_name, base::BindOnce(&CacheStorage::CreateCacheDidCreateCache,
                                  weak_factory_.GetWeakPtr(), cache_name,
-                                 std::move(callback)));
+                                 trace_id, std::move(callback)));
 }
 
 void CacheStorage::CreateCacheDidCreateCache(
     const std::string& cache_name,
+    int64_t trace_id,
     CacheAndErrorCallback callback,
     std::unique_ptr<CacheStorageCache> cache) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorage::CreateCacheDidCreateCache",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   UMA_HISTOGRAM_BOOLEAN("ServiceWorkerCache.CreateCacheStorageResult",
                         static_cast<bool>(cache));
 
@@ -915,7 +936,7 @@
       *cache_index_,
       base::BindOnce(&CacheStorage::CreateCacheDidWriteIndex,
                      weak_factory_.GetWeakPtr(), std::move(callback),
-                     cache_ptr->CreateHandle()));
+                     cache_ptr->CreateHandle(), trace_id));
 
   cache_loader_->NotifyCacheCreated(cache_name, std::move(handle));
   if (cache_storage_manager_)
@@ -925,23 +946,39 @@
 void CacheStorage::CreateCacheDidWriteIndex(
     CacheAndErrorCallback callback,
     CacheStorageCacheHandle cache_handle,
+    int64_t trace_id,
     bool success) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(cache_handle.value());
 
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorage::CreateCacheDidWriteIndex",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   // TODO(jkarlin): Handle !success.
 
   std::move(callback).Run(std::move(cache_handle), CacheStorageError::kSuccess);
 }
 
 void CacheStorage::HasCacheImpl(const std::string& cache_name,
+                                int64_t trace_id,
                                 BoolAndErrorCallback callback) {
+  TRACE_EVENT_WITH_FLOW1("CacheStorage", "CacheStorage::HasCacheImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "cache_name", cache_name);
   bool has_cache = base::ContainsKey(cache_map_, cache_name);
   std::move(callback).Run(has_cache, CacheStorageError::kSuccess);
 }
 
 void CacheStorage::DoomCacheImpl(const std::string& cache_name,
+                                 int64_t trace_id,
                                  ErrorCallback callback) {
+  TRACE_EVENT_WITH_FLOW1("CacheStorage", "CacheStorage::DoomCacheImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "cache_name", cache_name);
   CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_name);
   if (!cache_handle.value()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -956,15 +993,21 @@
       *cache_index_,
       base::BindOnce(&CacheStorage::DeleteCacheDidWriteIndex,
                      weak_factory_.GetWeakPtr(), std::move(cache_handle),
-                     std::move(callback)));
+                     std::move(callback), trace_id));
 }
 
 void CacheStorage::DeleteCacheDidWriteIndex(
     CacheStorageCacheHandle cache_handle,
     ErrorCallback callback,
+    int64_t trace_id,
     bool success) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorage::DeleteCacheDidWriteIndex",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (!success) {
     // Undo any changes if the index couldn't be written to disk.
     cache_index_->RestoreDoomedCache();
@@ -1010,7 +1053,11 @@
   doomed_caches_.erase(doomed_caches_iter);
 }
 
-void CacheStorage::EnumerateCachesImpl(IndexCallback callback) {
+void CacheStorage::EnumerateCachesImpl(int64_t trace_id,
+                                       IndexCallback callback) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorage::EnumerateCachesImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   std::move(callback).Run(*cache_index_);
 }
 
@@ -1018,7 +1065,13 @@
     const std::string& cache_name,
     blink::mojom::FetchAPIRequestPtr request,
     blink::mojom::CacheQueryOptionsPtr match_options,
+    int64_t trace_id,
     CacheStorageCache::ResponseCallback callback) {
+  TRACE_EVENT_WITH_FLOW2(
+      "CacheStorage", "CacheStorage::MatchCacheImpl", TRACE_ID_GLOBAL(trace_id),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "cache_name",
+      cache_name, "request", CacheStorageTracedValue(request));
+
   CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_name);
 
   if (!cache_handle.value()) {
@@ -1031,32 +1084,41 @@
   // match is done.
   CacheStorageCache* cache_ptr = cache_handle.value();
   cache_ptr->Match(
-      std::move(request), std::move(match_options),
+      std::move(request), std::move(match_options), trace_id,
       base::BindOnce(&CacheStorage::MatchCacheDidMatch,
                      weak_factory_.GetWeakPtr(), std::move(cache_handle),
-                     std::move(callback)));
+                     trace_id, std::move(callback)));
 }
 
 void CacheStorage::MatchCacheDidMatch(
     CacheStorageCacheHandle cache_handle,
+    int64_t trace_id,
     CacheStorageCache::ResponseCallback callback,
     CacheStorageError error,
     blink::mojom::FetchAPIResponsePtr response) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorage::MatchCacheDidMatch",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   std::move(callback).Run(error, std::move(response));
 }
 
 void CacheStorage::MatchAllCachesImpl(
     blink::mojom::FetchAPIRequestPtr request,
     blink::mojom::CacheQueryOptionsPtr match_options,
+    int64_t trace_id,
     CacheStorageCache::ResponseCallback callback) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorage::MatchAllCachesImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   std::vector<CacheMatchResponse>* match_responses =
       new std::vector<CacheMatchResponse>(cache_index_->num_entries());
 
   base::RepeatingClosure barrier_closure = base::BarrierClosure(
       cache_index_->num_entries(),
-      base::BindOnce(&CacheStorage::MatchAllCachesDidMatchAll,
-                     weak_factory_.GetWeakPtr(),
-                     base::WrapUnique(match_responses), std::move(callback)));
+      base::BindOnce(
+          &CacheStorage::MatchAllCachesDidMatchAll, weak_factory_.GetWeakPtr(),
+          base::WrapUnique(match_responses), trace_id, std::move(callback)));
 
   size_t idx = 0;
   for (const auto& cache_metadata : cache_index_->ordered_cache_metadata()) {
@@ -1066,10 +1128,10 @@
     CacheStorageCache* cache_ptr = cache_handle.value();
     cache_ptr->Match(
         BackgroundFetchSettledFetch::CloneRequest(request),
-        match_options ? match_options->Clone() : nullptr,
+        match_options ? match_options->Clone() : nullptr, trace_id,
         base::BindOnce(&CacheStorage::MatchAllCachesDidMatch,
                        weak_factory_.GetWeakPtr(), std::move(cache_handle),
-                       &match_responses->at(idx), barrier_closure));
+                       &match_responses->at(idx), barrier_closure, trace_id));
     idx++;
   }
 }
@@ -1078,8 +1140,12 @@
     CacheStorageCacheHandle cache_handle,
     CacheMatchResponse* out_match_response,
     const base::RepeatingClosure& barrier_closure,
+    int64_t trace_id,
     CacheStorageError error,
     blink::mojom::FetchAPIResponsePtr response) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorage::MatchAllCachesDidMatch",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   out_match_response->error = error;
   out_match_response->response = std::move(response);
   barrier_closure.Run();
@@ -1087,7 +1153,12 @@
 
 void CacheStorage::MatchAllCachesDidMatchAll(
     std::unique_ptr<std::vector<CacheMatchResponse>> match_responses,
+    int64_t trace_id,
     CacheStorageCache::ResponseCallback callback) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorage::MatchAllCachesDidMatchAll",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   for (CacheMatchResponse& match_response : *match_responses) {
     if (match_response.error == CacheStorageError::kErrorNotFound)
       continue;
@@ -1101,7 +1172,14 @@
 void CacheStorage::WriteToCacheImpl(const std::string& cache_name,
                                     blink::mojom::FetchAPIRequestPtr request,
                                     blink::mojom::FetchAPIResponsePtr response,
+                                    int64_t trace_id,
                                     CacheStorage::ErrorCallback callback) {
+  TRACE_EVENT_WITH_FLOW2("CacheStorage", "CacheStorage::WriteToCacheImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "cache_name", cache_name, "request",
+                         CacheStorageTracedValue(request));
+
   CacheStorageCacheHandle cache_handle = GetLoadedCache(cache_name);
 
   if (!cache_handle.value()) {
@@ -1112,7 +1190,8 @@
   CacheStorageCache* cache_ptr = cache_handle.value();
   DCHECK(cache_ptr);
 
-  cache_ptr->Put(std::move(request), std::move(response), std::move(callback));
+  cache_ptr->Put(std::move(request), std::move(response), trace_id,
+                 std::move(callback));
 }
 
 CacheStorageCacheHandle CacheStorage::GetLoadedCache(
diff --git a/content/browser/cache_storage/cache_storage.h b/content/browser/cache_storage/cache_storage.h
index 2f4c7f5..06bb6740 100644
--- a/content/browser/cache_storage/cache_storage.h
+++ b/content/browser/cache_storage/cache_storage.h
@@ -102,25 +102,32 @@
   // of the cache. Once all handles to a cache are deleted the cache is deleted.
   // The cache will also be deleted in the CacheStorage's destructor so be sure
   // to check the handle's value before using it.
-  void OpenCache(const std::string& cache_name, CacheAndErrorCallback callback);
+  void OpenCache(const std::string& cache_name,
+                 int64_t trace_id,
+                 CacheAndErrorCallback callback);
 
   // Calls the callback with whether or not the cache exists.
-  void HasCache(const std::string& cache_name, BoolAndErrorCallback callback);
+  void HasCache(const std::string& cache_name,
+                int64_t trace_id,
+                BoolAndErrorCallback callback);
 
   // Deletes the cache if it exists. If it doesn't exist,
   // blink::mojom::CacheStorageError::kErrorNotFound is returned. Any
   // existing CacheStorageCacheHandle(s) to the cache will remain valid but
   // future CacheStorage operations won't be able to access the cache. The cache
   // isn't actually erased from disk until the last handle is dropped.
-  void DoomCache(const std::string& cache_name, ErrorCallback callback);
+  void DoomCache(const std::string& cache_name,
+                 int64_t trace_id,
+                 ErrorCallback callback);
 
   // Calls the callback with the cache index.
-  void EnumerateCaches(IndexCallback callback);
+  void EnumerateCaches(int64_t trace_id, IndexCallback callback);
 
   // Calls match on the cache with the given |cache_name|.
   void MatchCache(const std::string& cache_name,
                   blink::mojom::FetchAPIRequestPtr request,
                   blink::mojom::CacheQueryOptionsPtr match_options,
+                  int64_t trace_id,
                   CacheStorageCache::ResponseCallback callback);
 
   // Calls match on all of the caches in parallel, calling |callback| with the
@@ -129,12 +136,14 @@
   // blink::mojom::CacheStorageError::kErrorNotFound.
   void MatchAllCaches(blink::mojom::FetchAPIRequestPtr request,
                       blink::mojom::CacheQueryOptionsPtr match_options,
+                      int64_t trace_id,
                       CacheStorageCache::ResponseCallback callback);
 
   // Puts the request/response pair in the cache.
   void WriteToCache(const std::string& cache_name,
                     blink::mojom::FetchAPIRequestPtr request,
                     blink::mojom::FetchAPIResponsePtr response,
+                    int64_t trace_id,
                     CacheStorage::ErrorCallback callback);
 
   // Sums the sizes of each cache and closes them. Runs |callback| with the
@@ -195,22 +204,29 @@
 
   // The Open and CreateCache callbacks are below.
   void OpenCacheImpl(const std::string& cache_name,
+                     int64_t trace_id,
                      CacheAndErrorCallback callback);
   void CreateCacheDidCreateCache(const std::string& cache_name,
+                                 int64_t trace_id,
                                  CacheAndErrorCallback callback,
                                  std::unique_ptr<CacheStorageCache> cache);
   void CreateCacheDidWriteIndex(CacheAndErrorCallback callback,
                                 CacheStorageCacheHandle cache_handle,
+                                int64_t trace_id,
                                 bool success);
 
   // The HasCache callbacks are below.
   void HasCacheImpl(const std::string& cache_name,
+                    int64_t trace_id,
                     BoolAndErrorCallback callback);
 
   // The DeleteCache callbacks are below.
-  void DoomCacheImpl(const std::string& cache_name, ErrorCallback callback);
+  void DoomCacheImpl(const std::string& cache_name,
+                     int64_t trace_id,
+                     ErrorCallback callback);
   void DeleteCacheDidWriteIndex(CacheStorageCacheHandle cache_handle,
                                 ErrorCallback callback,
+                                int64_t trace_id,
                                 bool success);
   void DeleteCacheFinalize(CacheStorageCache* doomed_cache);
   void DeleteCacheDidGetSize(CacheStorageCache* doomed_cache,
@@ -218,14 +234,16 @@
   void DeleteCacheDidCleanUp(bool success);
 
   // The EnumerateCache callbacks are below.
-  void EnumerateCachesImpl(IndexCallback callback);
+  void EnumerateCachesImpl(int64_t trace_id, IndexCallback callback);
 
   // The MatchCache callbacks are below.
   void MatchCacheImpl(const std::string& cache_name,
                       blink::mojom::FetchAPIRequestPtr request,
                       blink::mojom::CacheQueryOptionsPtr match_options,
+                      int64_t trace_id,
                       CacheStorageCache::ResponseCallback callback);
   void MatchCacheDidMatch(CacheStorageCacheHandle cache_handle,
+                          int64_t trace_id,
                           CacheStorageCache::ResponseCallback callback,
                           blink::mojom::CacheStorageError error,
                           blink::mojom::FetchAPIResponsePtr response);
@@ -233,20 +251,24 @@
   // The MatchAllCaches callbacks are below.
   void MatchAllCachesImpl(blink::mojom::FetchAPIRequestPtr request,
                           blink::mojom::CacheQueryOptionsPtr match_options,
+                          int64_t trace_id,
                           CacheStorageCache::ResponseCallback callback);
   void MatchAllCachesDidMatch(CacheStorageCacheHandle cache_handle,
                               CacheMatchResponse* out_match_response,
                               const base::RepeatingClosure& barrier_closure,
+                              int64_t trace_id,
                               blink::mojom::CacheStorageError error,
                               blink::mojom::FetchAPIResponsePtr response);
   void MatchAllCachesDidMatchAll(
       std::unique_ptr<std::vector<CacheMatchResponse>> match_responses,
+      int64_t trace_id,
       CacheStorageCache::ResponseCallback callback);
 
   // WriteToCache callbacks.
   void WriteToCacheImpl(const std::string& cache_name,
                         blink::mojom::FetchAPIRequestPtr request,
                         blink::mojom::FetchAPIResponsePtr response,
+                        int64_t trace_id,
                         CacheStorage::ErrorCallback callback);
 
   void GetSizeThenCloseAllCachesImpl(SizeCallback callback);
diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc
index 75d3e74..45f29af 100644
--- a/content/browser/cache_storage/cache_storage_cache.cc
+++ b/content/browser/cache_storage/cache_storage_cache.cc
@@ -26,6 +26,8 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/traced_value.h"
 #include "content/browser/cache_storage/cache_storage.pb.h"
 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h"
 #include "content/browser/cache_storage/cache_storage_cache_entry_handler.h"
@@ -35,6 +37,7 @@
 #include "content/browser/cache_storage/cache_storage_manager.h"
 #include "content/browser/cache_storage/cache_storage_quota_client.h"
 #include "content/browser/cache_storage/cache_storage_scheduler.h"
+#include "content/browser/cache_storage/cache_storage_trace_utils.h"
 #include "content/common/background_fetch/background_fetch_types.h"
 #include "content/common/service_worker/service_worker_utils.h"
 #include "content/public/browser/browser_thread.h"
@@ -546,6 +549,7 @@
 
 void CacheStorageCache::Match(blink::mojom::FetchAPIRequestPtr request,
                               blink::mojom::CacheQueryOptionsPtr match_options,
+                              int64_t trace_id,
                               ResponseCallback callback) {
   if (backend_state_ == BACKEND_CLOSED) {
     std::move(callback).Run(
@@ -557,13 +561,14 @@
       CacheStorageSchedulerOp::kMatch,
       base::BindOnce(&CacheStorageCache::MatchImpl,
                      weak_ptr_factory_.GetWeakPtr(), std::move(request),
-                     std::move(match_options),
+                     std::move(match_options), trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
 void CacheStorageCache::MatchAll(
     blink::mojom::FetchAPIRequestPtr request,
     blink::mojom::CacheQueryOptionsPtr match_options,
+    int64_t trace_id,
     ResponsesCallback callback) {
   if (backend_state_ == BACKEND_CLOSED) {
     std::move(callback).Run(
@@ -576,13 +581,14 @@
       CacheStorageSchedulerOp::kMatchAll,
       base::BindOnce(&CacheStorageCache::MatchAllImpl,
                      weak_ptr_factory_.GetWeakPtr(), std::move(request),
-                     std::move(match_options),
+                     std::move(match_options), trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
 void CacheStorageCache::WriteSideData(ErrorCallback callback,
                                       const GURL& url,
                                       base::Time expected_response_time,
+                                      int64_t trace_id,
                                       scoped_refptr<net::IOBuffer> buffer,
                                       int buf_len) {
   if (backend_state_ == BACKEND_CLOSED) {
@@ -601,12 +607,13 @@
       blink::mojom::StorageType::kTemporary,
       base::BindOnce(&CacheStorageCache::WriteSideDataDidGetQuota,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback), url,
-                     expected_response_time, buffer, buf_len));
+                     expected_response_time, trace_id, buffer, buf_len));
 }
 
 void CacheStorageCache::BatchOperation(
     std::vector<blink::mojom::BatchOperationPtr> operations,
     bool fail_on_duplicates,
+    int64_t trace_id,
     VerboseErrorCallback callback,
     BadMessageCallback bad_message_callback) {
   // This method may produce a warning message that should be returned in the
@@ -701,12 +708,13 @@
         blink::mojom::StorageType::kTemporary,
         base::BindOnce(&CacheStorageCache::BatchDidGetUsageAndQuota,
                        weak_ptr_factory_.GetWeakPtr(), std::move(operations),
-                       std::move(callback), std::move(bad_message_callback),
-                       std::move(message), space_required, side_data_size));
+                       trace_id, std::move(callback),
+                       std::move(bad_message_callback), std::move(message),
+                       space_required, side_data_size));
     return;
   }
 
-  BatchDidGetUsageAndQuota(std::move(operations), std::move(callback),
+  BatchDidGetUsageAndQuota(std::move(operations), trace_id, std::move(callback),
                            std::move(bad_message_callback), std::move(message),
                            0 /* space_required */, 0 /* side_data_size */,
                            blink::mojom::QuotaStatusCode::kOk, 0 /* usage */,
@@ -715,6 +723,7 @@
 
 void CacheStorageCache::BatchDidGetUsageAndQuota(
     std::vector<blink::mojom::BatchOperationPtr> operations,
+    int64_t trace_id,
     VerboseErrorCallback callback,
     BadMessageCallback bad_message_callback,
     base::Optional<std::string> message,
@@ -723,6 +732,11 @@
     blink::mojom::QuotaStatusCode status_code,
     int64_t usage,
     int64_t quota) {
+  TRACE_EVENT_WITH_FLOW1("CacheStorage",
+                         "CacheStorageCache::BatchDidGetUsageAndQuota",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "operations", CacheStorageTracedValue(operations));
   base::CheckedNumeric<uint64_t> safe_space_required = space_required;
   base::CheckedNumeric<uint64_t> safe_space_required_with_side_data;
   safe_space_required += usage;
@@ -760,10 +774,12 @@
   auto barrier_closure = base::BarrierClosure(
       operations.size(),
       base::BindOnce(&CacheStorageCache::BatchDidAllOperations,
-                     weak_ptr_factory_.GetWeakPtr(), callback_copy, message));
+                     weak_ptr_factory_.GetWeakPtr(), callback_copy, message,
+                     trace_id));
   auto completion_callback = base::BindRepeating(
       &CacheStorageCache::BatchDidOneOperation, weak_ptr_factory_.GetWeakPtr(),
-      std::move(barrier_closure), std::move(callback_copy), std::move(message));
+      std::move(barrier_closure), std::move(callback_copy), std::move(message),
+      trace_id);
 
   // Operations may synchronously invoke |callback| which could release the
   // last reference to this instance. Hold a handle for the duration of this
@@ -776,9 +792,9 @@
       case blink::mojom::OperationType::kPut:
         if (skip_side_data) {
           operation->response->side_data_blob = nullptr;
-          Put(std::move(operation), completion_callback);
+          Put(std::move(operation), trace_id, completion_callback);
         } else {
-          Put(std::move(operation), completion_callback);
+          Put(std::move(operation), trace_id, completion_callback);
         }
         break;
       case blink::mojom::OperationType::kDelete:
@@ -800,7 +816,12 @@
     base::OnceClosure completion_closure,
     VerboseErrorCallback error_callback,
     base::Optional<std::string> message,
+    int64_t trace_id,
     CacheStorageError error) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::BatchDidOneOperation",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   if (error != CacheStorageError::kSuccess) {
     // This relies on |callback| being created by AdaptCallbackForRepeating
     // and ignoring anything but the first invocation.
@@ -813,7 +834,12 @@
 
 void CacheStorageCache::BatchDidAllOperations(
     VerboseErrorCallback callback,
-    base::Optional<std::string> message) {
+    base::Optional<std::string> message,
+    int64_t trace_id) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::BatchDidAllOperations",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   // This relies on |callback| being created by AdaptCallbackForRepeating
   // and ignoring anything but the first invocation.
   std::move(callback).Run(CacheStorageVerboseError::New(
@@ -822,6 +848,7 @@
 
 void CacheStorageCache::Keys(blink::mojom::FetchAPIRequestPtr request,
                              blink::mojom::CacheQueryOptionsPtr options,
+                             int64_t trace_id,
                              RequestsCallback callback) {
   if (backend_state_ == BACKEND_CLOSED) {
     std::move(callback).Run(
@@ -833,7 +860,7 @@
       CacheStorageSchedulerOp::kKeys,
       base::BindOnce(&CacheStorageCache::KeysImpl,
                      weak_ptr_factory_.GetWeakPtr(), std::move(request),
-                     std::move(options),
+                     std::move(options), trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
@@ -1237,9 +1264,10 @@
 void CacheStorageCache::MatchImpl(
     blink::mojom::FetchAPIRequestPtr request,
     blink::mojom::CacheQueryOptionsPtr match_options,
+    int64_t trace_id,
     ResponseCallback callback) {
   MatchAllImpl(
-      std::move(request), std::move(match_options),
+      std::move(request), std::move(match_options), trace_id,
       base::BindOnce(&CacheStorageCache::MatchDidMatchAll,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
@@ -1264,8 +1292,14 @@
 
 void CacheStorageCache::MatchAllImpl(blink::mojom::FetchAPIRequestPtr request,
                                      blink::mojom::CacheQueryOptionsPtr options,
+                                     int64_t trace_id,
                                      ResponsesCallback callback) {
   DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
+  TRACE_EVENT_WITH_FLOW2("CacheStorage", "CacheStorageCache::MatchAllImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "request", CacheStorageTracedValue(request), "options",
+                         CacheStorageTracedValue(options));
   if (backend_state_ != BACKEND_OPEN) {
     std::move(callback).Run(
         MakeErrorStorage(ErrorStorageType::kStorageMatchAllBackendClosed),
@@ -1273,17 +1307,23 @@
     return;
   }
 
-  QueryCache(
-      std::move(request), std::move(options),
-      QUERY_CACHE_REQUESTS | QUERY_CACHE_RESPONSES_WITH_BODIES,
-      base::BindOnce(&CacheStorageCache::MatchAllDidQueryCache,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  QueryCache(std::move(request), std::move(options),
+             QUERY_CACHE_REQUESTS | QUERY_CACHE_RESPONSES_WITH_BODIES,
+             base::BindOnce(&CacheStorageCache::MatchAllDidQueryCache,
+                            weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                            trace_id));
 }
 
 void CacheStorageCache::MatchAllDidQueryCache(
     ResponsesCallback callback,
+    int64_t trace_id,
     CacheStorageError error,
     std::unique_ptr<QueryCacheResults> query_cache_results) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::MatchAllDidQueryCache",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (error != CacheStorageError::kSuccess) {
     std::move(callback).Run(error,
                             std::vector<blink::mojom::FetchAPIResponsePtr>());
@@ -1305,11 +1345,17 @@
     ErrorCallback callback,
     const GURL& url,
     base::Time expected_response_time,
+    int64_t trace_id,
     scoped_refptr<net::IOBuffer> buffer,
     int buf_len,
     blink::mojom::QuotaStatusCode status_code,
     int64_t usage,
     int64_t quota) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::WriteSideDataDidGetQuota",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (status_code != blink::mojom::QuotaStatusCode::kOk ||
       (buf_len > quota - usage)) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -1323,15 +1369,20 @@
       base::BindOnce(&CacheStorageCache::WriteSideDataImpl,
                      weak_ptr_factory_.GetWeakPtr(),
                      scheduler_->WrapCallbackToRunNext(std::move(callback)),
-                     url, expected_response_time, buffer, buf_len));
+                     url, expected_response_time, trace_id, buffer, buf_len));
 }
 
 void CacheStorageCache::WriteSideDataImpl(ErrorCallback callback,
                                           const GURL& url,
                                           base::Time expected_response_time,
+                                          int64_t trace_id,
                                           scoped_refptr<net::IOBuffer> buffer,
                                           int buf_len) {
   DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
+  TRACE_EVENT_WITH_FLOW1("CacheStorage", "CacheStorageCache::WriteSideDataImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "url", url.spec());
   if (backend_state_ != BACKEND_OPEN) {
     std::move(callback).Run(
         MakeErrorStorage(ErrorStorageType::kWriteSideDataImplBackendClosed));
@@ -1344,7 +1395,7 @@
   net::CompletionCallback open_entry_callback = base::AdaptCallbackForRepeating(
       base::BindOnce(&CacheStorageCache::WriteSideDataDidOpenEntry,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback),
-                     expected_response_time, buffer, buf_len,
+                     expected_response_time, trace_id, buffer, buf_len,
                      std::move(scoped_entry_ptr)));
 
   // Use LOWEST priority here as writing side data is less important than
@@ -1358,10 +1409,15 @@
 void CacheStorageCache::WriteSideDataDidOpenEntry(
     ErrorCallback callback,
     base::Time expected_response_time,
+    int64_t trace_id,
     scoped_refptr<net::IOBuffer> buffer,
     int buf_len,
     std::unique_ptr<disk_cache::Entry*> entry_ptr,
     int rv) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::WriteSideDataDidOpenEntry",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   if (rv != net::OK) {
     std::move(callback).Run(CacheStorageError::kErrorNotFound);
     return;
@@ -1372,16 +1428,21 @@
                base::BindOnce(&CacheStorageCache::WriteSideDataDidReadMetaData,
                               weak_ptr_factory_.GetWeakPtr(),
                               std::move(callback), expected_response_time,
-                              buffer, buf_len, std::move(entry)));
+                              trace_id, buffer, buf_len, std::move(entry)));
 }
 
 void CacheStorageCache::WriteSideDataDidReadMetaData(
     ErrorCallback callback,
     base::Time expected_response_time,
+    int64_t trace_id,
     scoped_refptr<net::IOBuffer> buffer,
     int buf_len,
     disk_cache::ScopedEntryPtr entry,
     std::unique_ptr<proto::CacheMetadata> headers) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::WriteSideDataDidReadMetaData",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   if (!headers || headers->response().response_time() !=
                       expected_response_time.ToInternalValue()) {
     std::move(callback).Run(CacheStorageError::kErrorNotFound);
@@ -1401,7 +1462,7 @@
       base::AdaptCallbackForRepeating(base::BindOnce(
           &CacheStorageCache::WriteSideDataDidWrite,
           weak_ptr_factory_.GetWeakPtr(), std::move(callback), std::move(entry),
-          buf_len, std::move(response), side_data_size_before_write));
+          buf_len, std::move(response), side_data_size_before_write, trace_id));
 
   int rv = temp_entry_ptr->WriteData(
       INDEX_SIDE_DATA, 0 /* offset */, buffer.get(), buf_len,
@@ -1417,7 +1478,11 @@
     int expected_bytes,
     std::unique_ptr<::content::proto::CacheResponse> response,
     int side_data_size_before_write,
+    int64_t trace_id,
     int rv) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::WriteSideDataDidWrite",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN);
   if (rv != expected_bytes) {
     entry->Doom();
     UpdateCacheSize(
@@ -1441,15 +1506,17 @@
 }
 
 void CacheStorageCache::Put(blink::mojom::BatchOperationPtr operation,
+                            int64_t trace_id,
                             ErrorCallback callback) {
   DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
   DCHECK_EQ(blink::mojom::OperationType::kPut, operation->operation_type);
-  Put(std::move(operation->request), std::move(operation->response),
+  Put(std::move(operation->request), std::move(operation->response), trace_id,
       std::move(callback));
 }
 
 void CacheStorageCache::Put(blink::mojom::FetchAPIRequestPtr request,
                             blink::mojom::FetchAPIResponsePtr response,
+                            int64_t trace_id,
                             ErrorCallback callback) {
   DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
 
@@ -1457,7 +1524,7 @@
                             response->response_type);
 
   auto put_context = cache_entry_handler_->CreatePutContext(
-      std::move(request), std::move(response));
+      std::move(request), std::move(response), trace_id);
   put_context->callback =
       scheduler_->WrapCallbackToRunNext(std::move(callback));
 
@@ -1469,6 +1536,12 @@
 
 void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) {
   DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
+  TRACE_EVENT_WITH_FLOW2(
+      "CacheStorage", "CacheStorageCache::PutImpl",
+      TRACE_ID_GLOBAL(put_context->trace_id),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "request",
+      CacheStorageTracedValue(put_context->request), "response",
+      CacheStorageTracedValue(put_context->response));
   if (backend_state_ != BACKEND_OPEN) {
     std::move(put_context->callback)
         .Run(MakeErrorStorage(ErrorStorageType::kPutImplBackendClosed));
@@ -1500,6 +1573,9 @@
 void CacheStorageCache::PutDidDeleteEntry(
     std::unique_ptr<PutContext> put_context,
     CacheStorageError error) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorageCache::PutDidDeleteEntry",
+                         TRACE_ID_GLOBAL(put_context->trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   if (backend_state_ != BACKEND_OPEN) {
     std::move(put_context->callback)
         .Run(MakeErrorStorage(
@@ -1535,6 +1611,10 @@
     std::unique_ptr<disk_cache::Entry*> entry_ptr,
     std::unique_ptr<PutContext> put_context,
     int rv) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorageCache::PutDidCreateEntry",
+                         TRACE_ID_GLOBAL(put_context->trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   put_context->cache_entry.reset(*entry_ptr);
 
   if (rv != net::OK) {
@@ -1606,6 +1686,11 @@
     std::unique_ptr<PutContext> put_context,
     int expected_bytes,
     int rv) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::PutDidWriteHeaders",
+                         TRACE_ID_GLOBAL(put_context->trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (rv != expected_bytes) {
     put_context->cache_entry->Doom();
     std::move(put_context->callback)
@@ -1645,6 +1730,11 @@
   DCHECK(disk_cache_body_index == INDEX_RESPONSE_BODY ||
          disk_cache_body_index == INDEX_SIDE_DATA);
 
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::PutWriteBlobToCache",
+                         TRACE_ID_GLOBAL(put_context->trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   blink::mojom::BlobPtr blob = disk_cache_body_index == INDEX_RESPONSE_BODY
                                    ? std::move(put_context->blob)
                                    : std::move(put_context->side_data_blob);
@@ -1675,6 +1765,11 @@
     disk_cache::ScopedEntryPtr entry,
     bool success) {
   DCHECK(entry);
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::PutDidWriteBlobToCache",
+                         TRACE_ID_GLOBAL(put_context->trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   put_context->cache_entry = std::move(entry);
 
   active_blob_to_disk_cache_writers_.Remove(blob_to_cache_key);
@@ -1788,6 +1883,7 @@
 void CacheStorageCache::GetAllMatchedEntries(
     blink::mojom::FetchAPIRequestPtr request,
     blink::mojom::CacheQueryOptionsPtr options,
+    int64_t trace_id,
     CacheEntriesCallback callback) {
   if (backend_state_ == BACKEND_CLOSED) {
     std::move(callback).Run(
@@ -1799,15 +1895,22 @@
       CacheStorageSchedulerOp::kGetAllMatched,
       base::BindOnce(&CacheStorageCache::GetAllMatchedEntriesImpl,
                      weak_ptr_factory_.GetWeakPtr(), std::move(request),
-                     std::move(options),
+                     std::move(options), trace_id,
                      scheduler_->WrapCallbackToRunNext(std::move(callback))));
 }
 
 void CacheStorageCache::GetAllMatchedEntriesImpl(
     blink::mojom::FetchAPIRequestPtr request,
     blink::mojom::CacheQueryOptionsPtr options,
+    int64_t trace_id,
     CacheEntriesCallback callback) {
   DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
+  TRACE_EVENT_WITH_FLOW2("CacheStorage",
+                         "CacheStorageCache::GetAllMatchedEntriesImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "request", CacheStorageTracedValue(request), "options",
+                         CacheStorageTracedValue(options));
   if (backend_state_ != BACKEND_OPEN) {
     std::move(callback).Run(
         MakeErrorStorage(
@@ -1820,13 +1923,20 @@
       std::move(request), std::move(options),
       QUERY_CACHE_REQUESTS | QUERY_CACHE_RESPONSES_WITH_BODIES,
       base::BindOnce(&CacheStorageCache::GetAllMatchedEntriesDidQueryCache,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+                     weak_ptr_factory_.GetWeakPtr(), trace_id,
+                     std::move(callback)));
 }
 
 void CacheStorageCache::GetAllMatchedEntriesDidQueryCache(
+    int64_t trace_id,
     CacheEntriesCallback callback,
     blink::mojom::CacheStorageError error,
     std::unique_ptr<QueryCacheResults> query_cache_results) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "CacheStorageCache::GetAllMatchedEntriesDidQueryCache",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (error != CacheStorageError::kSuccess) {
     std::move(callback).Run(error, {});
     return;
@@ -1910,24 +2020,36 @@
 
 void CacheStorageCache::KeysImpl(blink::mojom::FetchAPIRequestPtr request,
                                  blink::mojom::CacheQueryOptionsPtr options,
+                                 int64_t trace_id,
                                  RequestsCallback callback) {
   DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
+  TRACE_EVENT_WITH_FLOW2("CacheStorage", "CacheStorageCache::KeysImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                         "request", CacheStorageTracedValue(request), "options",
+                         CacheStorageTracedValue(options));
+
   if (backend_state_ != BACKEND_OPEN) {
     std::move(callback).Run(
         MakeErrorStorage(ErrorStorageType::kKeysImplBackendClosed), nullptr);
     return;
   }
 
-  QueryCache(
-      std::move(request), std::move(options), QUERY_CACHE_REQUESTS,
-      base::BindOnce(&CacheStorageCache::KeysDidQueryCache,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  QueryCache(std::move(request), std::move(options), QUERY_CACHE_REQUESTS,
+             base::BindOnce(&CacheStorageCache::KeysDidQueryCache,
+                            weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                            trace_id));
 }
 
 void CacheStorageCache::KeysDidQueryCache(
     RequestsCallback callback,
+    int64_t trace_id,
     CacheStorageError error,
     std::unique_ptr<QueryCacheResults> query_cache_results) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorageCache::KeysDidQueryCache",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (error != CacheStorageError::kSuccess) {
     std::move(callback).Run(error, nullptr);
     return;
diff --git a/content/browser/cache_storage/cache_storage_cache.h b/content/browser/cache_storage/cache_storage_cache.h
index 9d5c76d..e961209 100644
--- a/content/browser/cache_storage/cache_storage_cache.h
+++ b/content/browser/cache_storage/cache_storage_cache.h
@@ -116,6 +116,7 @@
   // Returns ERROR_TYPE_NOT_FOUND if not found.
   void Match(blink::mojom::FetchAPIRequestPtr request,
              blink::mojom::CacheQueryOptionsPtr match_options,
+             int64_t trace_id,
              ResponseCallback callback);
 
   // Returns blink::mojom::CacheStorageError::kSuccess and matched
@@ -123,6 +124,7 @@
   // blink::mojom::CacheStorageError::kSuccess and an empty vector.
   void MatchAll(blink::mojom::FetchAPIRequestPtr request,
                 blink::mojom::CacheQueryOptionsPtr match_options,
+                int64_t trace_id,
                 ResponsesCallback callback);
 
   // Writes the side data (ex: V8 code cache) for the specified cache entry.
@@ -134,6 +136,7 @@
   void WriteSideData(CacheStorageCache::ErrorCallback callback,
                      const GURL& url,
                      base::Time expected_response_time,
+                     int64_t trace_id,
                      scoped_refptr<net::IOBuffer> buffer,
                      int buf_len);
 
@@ -152,10 +155,12 @@
   // http://crbug.com/486637
   void BatchOperation(std::vector<blink::mojom::BatchOperationPtr> operations,
                       bool fail_on_duplicates,
+                      int64_t trace_id,
                       VerboseErrorCallback callback,
                       BadMessageCallback bad_message_callback);
   void BatchDidGetUsageAndQuota(
       std::vector<blink::mojom::BatchOperationPtr> operations,
+      int64_t trace_id,
       VerboseErrorCallback callback,
       BadMessageCallback bad_message_callback,
       base::Optional<std::string> message,
@@ -170,16 +175,19 @@
   void BatchDidOneOperation(base::OnceClosure completion_closure,
                             VerboseErrorCallback error_callback,
                             base::Optional<std::string> message,
+                            int64_t trace_id,
                             blink::mojom::CacheStorageError error);
   // Callback invoked once all BatchDidOneOperation() calls have run.
   // Invokes |error_callback|.
   void BatchDidAllOperations(VerboseErrorCallback error_callback,
-                             base::Optional<std::string> message);
+                             base::Optional<std::string> message,
+                             int64_t trace_id);
 
   // Returns blink::mojom::CacheStorageError::kSuccess and a vector of
   // requests if there are no errors.
   void Keys(blink::mojom::FetchAPIRequestPtr request,
             blink::mojom::CacheQueryOptionsPtr options,
+            int64_t trace_id,
             RequestsCallback callback);
 
   // Closes the backend. Future operations that require the backend
@@ -199,11 +207,13 @@
   // in the dispatcher.
   void Put(blink::mojom::FetchAPIRequestPtr request,
            blink::mojom::FetchAPIResponsePtr response,
+           int64_t trace_id,
            ErrorCallback callback);
 
   // Similar to MatchAll, but returns the associated requests as well.
   void GetAllMatchedEntries(blink::mojom::FetchAPIRequestPtr request,
                             blink::mojom::CacheQueryOptionsPtr match_options,
+                            int64_t trace_id,
                             CacheEntriesCallback callback);
 
   // Async operations in progress will cancel and not run their callbacks.
@@ -317,6 +327,7 @@
   // Match callbacks
   void MatchImpl(blink::mojom::FetchAPIRequestPtr request,
                  blink::mojom::CacheQueryOptionsPtr match_options,
+                 int64_t trace_id,
                  ResponseCallback callback);
   void MatchDidMatchAll(
       ResponseCallback callback,
@@ -326,9 +337,11 @@
   // MatchAll callbacks
   void MatchAllImpl(blink::mojom::FetchAPIRequestPtr request,
                     blink::mojom::CacheQueryOptionsPtr options,
+                    int64_t trace_id,
                     ResponsesCallback callback);
   void MatchAllDidQueryCache(
       ResponsesCallback callback,
+      int64_t trace_id,
       blink::mojom::CacheStorageError error,
       std::unique_ptr<QueryCacheResults> query_cache_results);
 
@@ -336,6 +349,7 @@
   void WriteSideDataDidGetQuota(ErrorCallback callback,
                                 const GURL& url,
                                 base::Time expected_response_time,
+                                int64_t trace_id,
                                 scoped_refptr<net::IOBuffer> buffer,
                                 int buf_len,
                                 blink::mojom::QuotaStatusCode status_code,
@@ -345,12 +359,14 @@
   void WriteSideDataImpl(ErrorCallback callback,
                          const GURL& url,
                          base::Time expected_response_time,
+                         int64_t trace_id,
                          scoped_refptr<net::IOBuffer> buffer,
                          int buf_len);
   void WriteSideDataDidGetUsageAndQuota(
       ErrorCallback callback,
       const GURL& url,
       base::Time expected_response_time,
+      int64_t trace_id,
       scoped_refptr<net::IOBuffer> buffer,
       int buf_len,
       blink::mojom::QuotaStatusCode status_code,
@@ -358,6 +374,7 @@
       int64_t quota);
   void WriteSideDataDidOpenEntry(ErrorCallback callback,
                                  base::Time expected_response_time,
+                                 int64_t trace_id,
                                  scoped_refptr<net::IOBuffer> buffer,
                                  int buf_len,
                                  std::unique_ptr<disk_cache::Entry*> entry_ptr,
@@ -365,6 +382,7 @@
   void WriteSideDataDidReadMetaData(
       ErrorCallback callback,
       base::Time expected_response_time,
+      int64_t trace_id,
       scoped_refptr<net::IOBuffer> buffer,
       int buf_len,
       disk_cache::ScopedEntryPtr entry,
@@ -375,12 +393,15 @@
       int expected_bytes,
       std::unique_ptr<content::proto::CacheResponse> response,
       int side_data_size_before_write,
+      int64_t trace_id,
       int rv);
 
   // Puts the request and response object in the cache. The response body (if
   // present) is stored in the cache, but not the request body. Returns OK on
   // success.
-  void Put(blink::mojom::BatchOperationPtr operation, ErrorCallback callback);
+  void Put(blink::mojom::BatchOperationPtr operation,
+           int64_t trace_id,
+           ErrorCallback callback);
   void PutImpl(std::unique_ptr<PutContext> put_context);
   void PutDidDeleteEntry(std::unique_ptr<PutContext> put_context,
                          blink::mojom::CacheStorageError error);
@@ -412,8 +433,10 @@
   // GetAllMatchedEntries callbacks.
   void GetAllMatchedEntriesImpl(blink::mojom::FetchAPIRequestPtr request,
                                 blink::mojom::CacheQueryOptionsPtr options,
+                                int64_t trace_id,
                                 CacheEntriesCallback callback);
   void GetAllMatchedEntriesDidQueryCache(
+      int64_t trace_id,
       CacheEntriesCallback callback,
       blink::mojom::CacheStorageError error,
       std::unique_ptr<QueryCacheResults> query_cache_results);
@@ -432,9 +455,11 @@
   // Keys callbacks.
   void KeysImpl(blink::mojom::FetchAPIRequestPtr request,
                 blink::mojom::CacheQueryOptionsPtr options,
+                int64_t trace_id,
                 RequestsCallback callback);
   void KeysDidQueryCache(
       RequestsCallback callback,
+      int64_t trace_id,
       blink::mojom::CacheStorageError error,
       std::unique_ptr<QueryCacheResults> query_cache_results);
 
diff --git a/content/browser/cache_storage/cache_storage_cache_entry_handler.cc b/content/browser/cache_storage/cache_storage_cache_entry_handler.cc
index 3cc348b8..febe5a2b 100644
--- a/content/browser/cache_storage/cache_storage_cache_entry_handler.cc
+++ b/content/browser/cache_storage/cache_storage_cache_entry_handler.cc
@@ -44,13 +44,15 @@
                        blink::mojom::BlobPtr blob,
                        uint64_t blob_size,
                        blink::mojom::BlobPtr side_data_blob,
-                       uint64_t side_data_blob_size)
+                       uint64_t side_data_blob_size,
+                       int64_t trace_id)
     : request(std::move(request)),
       response(std::move(response)),
       blob(std::move(blob)),
       blob_size(blob_size),
       side_data_blob(std::move(side_data_blob)),
-      side_data_blob_size(side_data_blob_size) {}
+      side_data_blob_size(side_data_blob_size),
+      trace_id(trace_id) {}
 
 PutContext::~PutContext() = default;
 
@@ -65,7 +67,8 @@
 
   std::unique_ptr<PutContext> CreatePutContext(
       blink::mojom::FetchAPIRequestPtr request,
-      blink::mojom::FetchAPIResponsePtr response) override {
+      blink::mojom::FetchAPIResponsePtr response,
+      int64_t trace_id) override {
     blink::mojom::BlobPtr blob;
     uint64_t blob_size = blink::BlobUtils::kUnknownSize;
     blink::mojom::BlobPtr side_data_blob;
@@ -82,7 +85,7 @@
 
     return std::make_unique<PutContext>(
         std::move(request), std::move(response), std::move(blob), blob_size,
-        std::move(side_data_blob), side_data_blob_size);
+        std::move(side_data_blob), side_data_blob_size, trace_id);
   }
 
   void PopulateResponseBody(scoped_refptr<BlobDataHandle> data_handle,
diff --git a/content/browser/cache_storage/cache_storage_cache_entry_handler.h b/content/browser/cache_storage/cache_storage_cache_entry_handler.h
index fd6723b..358835d 100644
--- a/content/browser/cache_storage/cache_storage_cache_entry_handler.h
+++ b/content/browser/cache_storage/cache_storage_cache_entry_handler.h
@@ -35,7 +35,8 @@
              blink::mojom::BlobPtr blob,
              uint64_t blob_size,
              blink::mojom::BlobPtr side_data_blob,
-             uint64_t side_data_blob_size);
+             uint64_t side_data_blob_size,
+             int64_t trace_id);
 
   ~PutContext();
 
@@ -46,6 +47,7 @@
   uint64_t blob_size;
   blink::mojom::BlobPtr side_data_blob;
   uint64_t side_data_blob_size;
+  int64_t trace_id;
 
   // Provided while writing to the cache.
   ErrorCallback callback;
@@ -89,7 +91,8 @@
 
   virtual std::unique_ptr<PutContext> CreatePutContext(
       blink::mojom::FetchAPIRequestPtr request,
-      blink::mojom::FetchAPIResponsePtr response) = 0;
+      blink::mojom::FetchAPIResponsePtr response,
+      int64_t trace_id) = 0;
   virtual void PopulateResponseBody(
       scoped_refptr<BlobDataHandle> data_handle,
       blink::mojom::FetchAPIResponse* response) = 0;
diff --git a/content/browser/cache_storage/cache_storage_cache_unittest.cc b/content/browser/cache_storage/cache_storage_cache_unittest.cc
index 8ddbfa2..eb7331a 100644
--- a/content/browser/cache_storage/cache_storage_cache_unittest.cc
+++ b/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -521,6 +521,7 @@
 
     cache_->BatchOperation(
         std::move(operations), fail_on_duplicates,
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageCacheTest::VerboseErrorTypeCallback,
                        base::Unretained(this), base::Unretained(loop.get())),
         base::BindOnce(&OnBadMessage, base::Unretained(&bad_message_reason_)));
@@ -565,6 +566,7 @@
 
     cache_->Match(
         CopyFetchRequest(request), std::move(match_options),
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageCacheTest::ResponseAndErrorCallback,
                        base::Unretained(this), base::Unretained(loop.get())));
     loop->Run();
@@ -580,6 +582,7 @@
     base::RunLoop loop;
     cache_->MatchAll(
         CopyFetchRequest(request), std::move(match_options),
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageCacheTest::ResponsesAndErrorCallback,
                        base::Unretained(this), loop.QuitClosure(), responses));
     loop.Run();
@@ -593,6 +596,7 @@
     base::RunLoop loop;
     cache_->GetAllMatchedEntries(
         nullptr /* request */, nullptr /* options */,
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageCacheTest::CacheEntriesAndErrorCallback,
                        base::Unretained(this), loop.QuitClosure(),
                        cache_entries));
@@ -629,6 +633,7 @@
 
     cache_->Keys(
         CopyFetchRequest(request), std::move(match_options),
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageCacheTest::RequestsCallback,
                        base::Unretained(this), base::Unretained(loop.get())));
     loop->Run();
@@ -659,7 +664,7 @@
     cache_->WriteSideData(
         base::BindOnce(&CacheStorageCacheTest::ErrorTypeCallback,
                        base::Unretained(this), base::Unretained(&run_loop)),
-        url, expected_response_time, buffer, buf_len);
+        url, expected_response_time, /* trace_id = */ 0, buffer, buf_len);
     run_loop.Run();
     if (callback_error_ == CacheStorageError::kSuccess)
       CheckOpHistograms(histogram_tester, "WriteSideData");
@@ -991,6 +996,7 @@
   std::unique_ptr<base::RunLoop> loop(new base::RunLoop());
   cache_->BatchOperation(
       std::move(operations), true /* fail_on_duplicate */,
+      /* trace_id = */ 0,
       base::BindOnce(&CacheStorageCacheTestP::VerboseErrorTypeCallback,
                      base::Unretained(this), base::Unretained(loop.get())),
       CacheStorageCache::BadMessageCallback());
@@ -2253,6 +2259,7 @@
   operations1.emplace_back(std::move(operation1));
   cache_->BatchOperation(
       std::move(operations1), true /* fail_on_duplicate */,
+      /* trace_id = */ 0,
       base::BindOnce(&CacheStorageCacheTest::SequenceCallback,
                      base::Unretained(this), 1, &sequence_out,
                      close_loop1.get()),
@@ -2274,6 +2281,7 @@
   operations2.emplace_back(std::move(operation2));
   cache_->BatchOperation(
       std::move(operations2), true /* fail_on_duplicate */,
+      /* trace_id = */ 0,
       base::BindOnce(&CacheStorageCacheTest::SequenceCallback,
                      base::Unretained(this), 2, &sequence_out,
                      close_loop2.get()),
diff --git a/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
index e4ab063..8c0003f4 100644
--- a/content/browser/cache_storage/cache_storage_dispatcher_host.cc
+++ b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -18,11 +18,13 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
+#include "base/trace_event/traced_value.h"
 #include "content/browser/cache_storage/cache_storage_cache.h"
 #include "content/browser/cache_storage/cache_storage_cache_handle.h"
 #include "content/browser/cache_storage/cache_storage_context_impl.h"
 #include "content/browser/cache_storage/cache_storage_histogram_utils.h"
 #include "content/browser/cache_storage/cache_storage_manager.h"
+#include "content/browser/cache_storage/cache_storage_trace_utils.h"
 #include "content/common/background_fetch/background_fetch_types.h"
 #include "content/common/service_worker/service_worker_utils.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -31,6 +33,7 @@
 #include "content/public/common/origin_util.h"
 #include "content/public/common/referrer_type_converters.h"
 #include "mojo/public/cpp/bindings/message.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
 #include "url/gurl.h"
@@ -90,9 +93,17 @@
   // blink::mojom::CacheStorageCache implementation:
   void Match(blink::mojom::FetchAPIRequestPtr request,
              blink::mojom::CacheQueryOptionsPtr match_options,
+             int64_t trace_id,
              MatchCallback callback) override {
+    TRACE_EVENT_WITH_FLOW2("CacheStorage",
+                           "CacheStorageDispatchHost::CacheImpl::Match",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                           "request", CacheStorageTracedValue(request),
+                           "options", CacheStorageTracedValue(match_options));
+
     auto cb = base::BindOnce(
-        [](base::TimeTicks start_time, bool ignore_search,
+        [](base::TimeTicks start_time, bool ignore_search, int64_t trace_id,
            blink::mojom::CacheStorageCache::MatchCallback callback,
            blink::mojom::CacheStorageError error,
            blink::mojom::FetchAPIResponsePtr response) {
@@ -108,16 +119,28 @@
                 "ServiceWorkerCache.Cache.Browser.Match.Miss", elapsed);
           }
           if (error != CacheStorageError::kSuccess) {
+            TRACE_EVENT_WITH_FLOW1(
+                "CacheStorage",
+                "CacheStorageDispatchHost::CacheImpl::Match::Callback",
+                TRACE_ID_GLOBAL(trace_id),
+                TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
+                CacheStorageTracedValue(error));
             std::move(callback).Run(
                 blink::mojom::MatchResult::NewStatus(error));
             return;
           }
           UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Browser.Match.Hit",
                                    elapsed);
+          TRACE_EVENT_WITH_FLOW1(
+              "CacheStorage",
+              "CacheStorageDispatchHost::CacheImpl::Match::Callback",
+              TRACE_ID_GLOBAL(trace_id),
+              TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "response",
+              CacheStorageTracedValue(response));
           std::move(callback).Run(
               blink::mojom::MatchResult::NewResponse(std::move(response)));
         },
-        base::TimeTicks::Now(), match_options->ignore_search,
+        base::TimeTicks::Now(), match_options->ignore_search, trace_id,
         std::move(callback));
 
     content::CacheStorageCache* cache = cache_handle_.value();
@@ -126,14 +149,23 @@
       return;
     }
 
-    cache->Match(std::move(request), std::move(match_options), std::move(cb));
+    cache->Match(std::move(request), std::move(match_options), trace_id,
+                 std::move(cb));
   }
 
   void MatchAll(blink::mojom::FetchAPIRequestPtr request,
                 blink::mojom::CacheQueryOptionsPtr match_options,
+                int64_t trace_id,
                 MatchAllCallback callback) override {
+    TRACE_EVENT_WITH_FLOW2("CacheStorage",
+                           "CacheStorageDispatchHost::CacheImpl::MatchAll",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                           "request", CacheStorageTracedValue(request),
+                           "options", CacheStorageTracedValue(match_options));
+
     auto cb = base::BindOnce(
-        [](base::TimeTicks start_time,
+        [](base::TimeTicks start_time, int64_t trace_id,
            blink::mojom::CacheStorageCache::MatchAllCallback callback,
            blink::mojom::CacheStorageError error,
            std::vector<blink::mojom::FetchAPIResponsePtr> responses) {
@@ -142,14 +174,26 @@
                                    elapsed);
           if (error != CacheStorageError::kSuccess &&
               error != CacheStorageError::kErrorNotFound) {
+            TRACE_EVENT_WITH_FLOW1(
+                "CacheStorage",
+                "CacheStorageDispatchHost::CacheImpl::MatchAll::Callback",
+                TRACE_ID_GLOBAL(trace_id),
+                TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
+                CacheStorageTracedValue(error));
             std::move(callback).Run(
                 blink::mojom::MatchAllResult::NewStatus(error));
             return;
           }
+          TRACE_EVENT_WITH_FLOW1(
+              "CacheStorage",
+              "CacheStorageDispatchHost::CacheImpl::MatchAll::Callback",
+              TRACE_ID_GLOBAL(trace_id),
+              TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+              "response_list", CacheStorageTracedValue(responses));
           std::move(callback).Run(
               blink::mojom::MatchAllResult::NewResponses(std::move(responses)));
         },
-        base::TimeTicks::Now(), std::move(callback));
+        base::TimeTicks::Now(), trace_id, std::move(callback));
 
     content::CacheStorageCache* cache = cache_handle_.value();
     if (!cache) {
@@ -158,21 +202,35 @@
       return;
     }
 
-    cache->MatchAll(std::move(request), std::move(match_options),
+    cache->MatchAll(std::move(request), std::move(match_options), trace_id,
                     std::move(cb));
   }
 
   void Keys(blink::mojom::FetchAPIRequestPtr request,
             blink::mojom::CacheQueryOptionsPtr match_options,
+            int64_t trace_id,
             KeysCallback callback) override {
+    TRACE_EVENT_WITH_FLOW2("CacheStorage",
+                           "CacheStorageDispatchHost::CacheImpl::Keys",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                           "request", CacheStorageTracedValue(request),
+                           "options", CacheStorageTracedValue(match_options));
+
     auto cb = base::BindOnce(
-        [](base::TimeTicks start_time,
+        [](base::TimeTicks start_time, int64_t trace_id,
            blink::mojom::CacheStorageCache::KeysCallback callback,
            blink::mojom::CacheStorageError error,
            std::unique_ptr<content::CacheStorageCache::Requests> requests) {
           UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Browser.Keys",
                                    base::TimeTicks::Now() - start_time);
           if (error != CacheStorageError::kSuccess) {
+            TRACE_EVENT_WITH_FLOW1(
+                "CacheStorage",
+                "CacheStorageDispatchHost::CacheImpl::Keys::Callback",
+                TRACE_ID_GLOBAL(trace_id),
+                TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
+                CacheStorageTracedValue(error));
             std::move(callback).Run(
                 blink::mojom::CacheKeysResult::NewStatus(error));
             return;
@@ -183,10 +241,17 @@
                 BackgroundFetchSettledFetch::CloneRequest(request));
           }
 
+          TRACE_EVENT_WITH_FLOW1(
+              "CacheStorage",
+              "CacheStorageDispatchHost::CacheImpl::Keys::Callback",
+              TRACE_ID_GLOBAL(trace_id),
+              TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+              "request_list", CacheStorageTracedValue(requests_));
+
           std::move(callback).Run(
               blink::mojom::CacheKeysResult::NewKeys(std::move(requests_)));
         },
-        base::TimeTicks::Now(), std::move(callback));
+        base::TimeTicks::Now(), trace_id, std::move(callback));
 
     content::CacheStorageCache* cache = cache_handle_.value();
     if (!cache) {
@@ -194,12 +259,20 @@
       return;
     }
 
-    cache->Keys(std::move(request), std::move(match_options), std::move(cb));
+    cache->Keys(std::move(request), std::move(match_options), trace_id,
+                std::move(cb));
   }
 
   void Batch(std::vector<blink::mojom::BatchOperationPtr> batch_operations,
              bool fail_on_duplicates,
+             int64_t trace_id,
              BatchCallback callback) override {
+    TRACE_EVENT_WITH_FLOW1(
+        "CacheStorage", "CacheStorageDispatchHost::CacheImpl::Batch",
+        TRACE_ID_GLOBAL(trace_id),
+        TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "operation_list",
+        CacheStorageTracedValue(batch_operations));
+
     if (!ValidBatchOperations(batch_operations)) {
       mojo::ReportBadMessage("CSDH_UNEXPECTED_OPERATION");
       return;
@@ -213,9 +286,16 @@
     auto cb = base::BindOnce(
         [](base::TimeTicks start_time,
            blink::mojom::OperationType operation_type, int operation_count,
+           int64_t trace_id,
            blink::mojom::CacheStorageCache::BatchCallback callback,
            blink::mojom::CacheStorageVerboseErrorPtr error) {
           base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
+          TRACE_EVENT_WITH_FLOW1(
+              "CacheStorage",
+              "CacheStorageDispatchHost::CacheImpl::Batch::Callback",
+              TRACE_ID_GLOBAL(trace_id),
+              TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
+              CacheStorageTracedValue(error->value));
           if (operation_type == blink::mojom::OperationType::kDelete) {
             DCHECK_EQ(operation_count, 1);
             UMA_HISTOGRAM_LONG_TIMES(
@@ -231,7 +311,7 @@
           }
           std::move(callback).Run(std::move(error));
         },
-        base::TimeTicks::Now(), operation_type, operation_count,
+        base::TimeTicks::Now(), operation_type, operation_count, trace_id,
         std::move(callback));
 
     content::CacheStorageCache* cache = cache_handle_.value();
@@ -242,7 +322,8 @@
     }
 
     cache->BatchOperation(
-        std::move(batch_operations), fail_on_duplicates, std::move(cb),
+        std::move(batch_operations), fail_on_duplicates, trace_id,
+        std::move(cb),
         base::BindOnce(
             [](mojo::ReportBadMessageCallback bad_message_callback) {
               std::move(bad_message_callback).Run("CSDH_UNEXPECTED_OPERATION");
@@ -253,7 +334,13 @@
   void SetSideData(const GURL& url,
                    base::Time response_time,
                    const std::vector<uint8_t>& side_data,
+                   int64_t trace_id,
                    SetSideDataCallback callback) override {
+    TRACE_EVENT_WITH_FLOW1("CacheStorage",
+                           "CacheStorageDispatcherHost::CacheImpl::SetSideData",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                           "url", url.spec());
     content::CacheStorageCache* cache = cache_handle_.value();
     if (!cache) {
       std::move(callback).Run(blink::mojom::CacheStorageError::kErrorNotFound);
@@ -263,7 +350,7 @@
         base::MakeRefCounted<net::IOBuffer>(side_data.size());
     if (!side_data.empty())
       memcpy(buffer->data(), &side_data.front(), side_data.size());
-    cache->WriteSideData(std::move(callback), url, response_time,
+    cache->WriteSideData(std::move(callback), url, response_time, trace_id,
                          std::move(buffer), side_data.size());
   }
 
@@ -288,9 +375,15 @@
   ~CacheStorageImpl() override = default;
 
   // Mojo CacheStorage Interface implementation:
-  void Keys(blink::mojom::CacheStorage::KeysCallback callback) override {
+  void Keys(int64_t trace_id,
+            blink::mojom::CacheStorage::KeysCallback callback) override {
+    TRACE_EVENT_WITH_FLOW0(
+        "CacheStorage", "CacheStorageDispatchHost::CacheStorageImpl::Keys",
+        TRACE_ID_GLOBAL(trace_id),
+        TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
     auto cb = base::BindOnce(
-        [](base::TimeTicks start_time,
+        [](base::TimeTicks start_time, int64_t trace_id,
            blink::mojom::CacheStorage::KeysCallback callback,
            const CacheStorageIndex& cache_index) {
           std::vector<base::string16> string16s;
@@ -300,9 +393,15 @@
           UMA_HISTOGRAM_LONG_TIMES(
               "ServiceWorkerCache.CacheStorage.Browser.Keys",
               base::TimeTicks::Now() - start_time);
+          TRACE_EVENT_WITH_FLOW1(
+              "CacheStorage",
+              "CacheStorageDispatchHost::CacheStorageImpl::Keys::Callback",
+              TRACE_ID_GLOBAL(trace_id),
+              TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "key_list",
+              CacheStorageTracedValue(string16s));
           std::move(callback).Run(string16s);
         },
-        base::TimeTicks::Now(), std::move(callback));
+        base::TimeTicks::Now(), trace_id, std::move(callback));
 
     content::CacheStorage* cache_storage = GetOrCreateCacheStorage();
     if (!cache_storage) {
@@ -310,21 +409,35 @@
       return;
     }
 
-    cache_storage->EnumerateCaches(std::move(cb));
+    cache_storage->EnumerateCaches(trace_id, std::move(cb));
   }
 
   void Delete(const base::string16& cache_name,
+              int64_t trace_id,
               blink::mojom::CacheStorage::DeleteCallback callback) override {
+    std::string utf8_cache_name = base::UTF16ToUTF8(cache_name);
+    TRACE_EVENT_WITH_FLOW1("CacheStorage",
+                           "CacheStorageDispatchHost::CacheStorageImpl::Delete",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                           "cache_name", utf8_cache_name);
+
     auto cb = base::BindOnce(
-        [](base::TimeTicks start_time,
+        [](base::TimeTicks start_time, int64_t trace_id,
            blink::mojom::CacheStorage::DeleteCallback callback,
            CacheStorageError error) {
           UMA_HISTOGRAM_LONG_TIMES(
               "ServiceWorkerCache.CacheStorage.Browser.Delete",
               base::TimeTicks::Now() - start_time);
+          TRACE_EVENT_WITH_FLOW1(
+              "CacheStorage",
+              "CacheStorageDispatchHost::CacheStorageImpl::Delete::Callback",
+              TRACE_ID_GLOBAL(trace_id),
+              TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
+              CacheStorageTracedValue(error));
           std::move(callback).Run(error);
         },
-        base::TimeTicks::Now(), std::move(callback));
+        base::TimeTicks::Now(), trace_id, std::move(callback));
 
     content::CacheStorage* cache_storage = GetOrCreateCacheStorage();
     if (!cache_storage) {
@@ -332,23 +445,37 @@
       return;
     }
 
-    cache_storage->DoomCache(base::UTF16ToUTF8(cache_name), std::move(cb));
+    cache_storage->DoomCache(utf8_cache_name, trace_id, std::move(cb));
   }
 
   void Has(const base::string16& cache_name,
+           int64_t trace_id,
            blink::mojom::CacheStorage::HasCallback callback) override {
+    std::string utf8_cache_name = base::UTF16ToUTF8(cache_name);
+    TRACE_EVENT_WITH_FLOW1("CacheStorage",
+                           "CacheStorageDispatchHost::CacheStorageImpl::Has",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                           "cache_name", utf8_cache_name);
+
     auto cb = base::BindOnce(
-        [](base::TimeTicks start_time,
+        [](base::TimeTicks start_time, int64_t trace_id,
            blink::mojom::CacheStorage::HasCallback callback, bool has_cache,
            CacheStorageError error) {
           if (!has_cache)
             error = CacheStorageError::kErrorNotFound;
+          TRACE_EVENT_WITH_FLOW1(
+              "CacheStorage",
+              "CacheStorageDispatchHost::CacheStorageImpl::Has::Callback",
+              TRACE_ID_GLOBAL(trace_id),
+              TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
+              CacheStorageTracedValue(error));
           UMA_HISTOGRAM_LONG_TIMES(
               "ServiceWorkerCache.CacheStorage.Browser.Has",
               base::TimeTicks::Now() - start_time);
           std::move(callback).Run(error);
         },
-        base::TimeTicks::Now(), std::move(callback));
+        base::TimeTicks::Now(), trace_id, std::move(callback));
 
     content::CacheStorage* cache_storage = GetOrCreateCacheStorage();
     if (!cache_storage) {
@@ -357,14 +484,22 @@
       return;
     }
 
-    cache_storage->HasCache(base::UTF16ToUTF8(cache_name), std::move(cb));
+    cache_storage->HasCache(utf8_cache_name, trace_id, std::move(cb));
   }
 
   void Match(blink::mojom::FetchAPIRequestPtr request,
              blink::mojom::MultiCacheQueryOptionsPtr match_options,
+             int64_t trace_id,
              blink::mojom::CacheStorage::MatchCallback callback) override {
+    TRACE_EVENT_WITH_FLOW2("CacheStorage",
+                           "CacheStorageDispatchHost::CacheStorageImpl::Match",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                           "request", CacheStorageTracedValue(request),
+                           "options", CacheStorageTracedValue(match_options));
+
     auto cb = BindOnce(
-        [](base::TimeTicks start_time, bool match_all_caches,
+        [](base::TimeTicks start_time, bool match_all_caches, int64_t trace_id,
            blink::mojom::CacheStorage::MatchCallback callback,
            CacheStorageError error,
            blink::mojom::FetchAPIResponsePtr response) {
@@ -379,14 +514,26 @@
                 elapsed);
           }
           if (error != CacheStorageError::kSuccess) {
+            TRACE_EVENT_WITH_FLOW1(
+                "CacheStorage",
+                "CacheStorageDispatchHost::CacheStorageImpl::Match::Callback",
+                TRACE_ID_GLOBAL(trace_id),
+                TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
+                CacheStorageTracedValue(error));
             std::move(callback).Run(
                 blink::mojom::MatchResult::NewStatus(error));
             return;
           }
+          TRACE_EVENT_WITH_FLOW1(
+              "CacheStorage",
+              "CacheStorageDispatchHost::CacheStorageImpl::Match::Callback",
+              TRACE_ID_GLOBAL(trace_id),
+              TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "response",
+              CacheStorageTracedValue(response));
           std::move(callback).Run(
               blink::mojom::MatchResult::NewResponse(std::move(response)));
         },
-        base::TimeTicks::Now(), !match_options->cache_name,
+        base::TimeTicks::Now(), !match_options->cache_name, trace_id,
         std::move(callback));
 
     content::CacheStorage* cache_storage = GetOrCreateCacheStorage();
@@ -398,21 +545,29 @@
     if (!match_options->cache_name) {
       cache_storage->MatchAllCaches(std::move(request),
                                     std::move(match_options->query_options),
-                                    std::move(cb));
+                                    trace_id, std::move(cb));
       return;
     }
     std::string cache_name = base::UTF16ToUTF8(*match_options->cache_name);
     cache_storage->MatchCache(std::move(cache_name), std::move(request),
-                              std::move(match_options->query_options),
+                              std::move(match_options->query_options), trace_id,
                               std::move(cb));
   }
 
   void Open(const base::string16& cache_name,
+            int64_t trace_id,
             blink::mojom::CacheStorage::OpenCallback callback) override {
+    std::string utf8_cache_name = base::UTF16ToUTF8(cache_name);
+    TRACE_EVENT_WITH_FLOW1("CacheStorage",
+                           "CacheStorageDispatchHost::CacheStorageImpl::Open",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                           "cache_name", utf8_cache_name);
     content::CacheStorage* cache_storage = GetOrCreateCacheStorage();
     auto cb =
         base::BindOnce(
             [](base::WeakPtr<CacheStorageImpl> self, base::TimeTicks start_time,
+               int64_t trace_id,
                blink::mojom::CacheStorage::OpenCallback callback,
                CacheStorageCacheHandle cache_handle, CacheStorageError error) {
               if (!self)
@@ -422,6 +577,13 @@
                   "ServiceWorkerCache.CacheStorage.Browser.Open",
                   base::TimeTicks::Now() - start_time);
 
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage",
+                  "CacheStorageDispatchHost::CacheStorageImpl::Open::Callback",
+                  TRACE_ID_GLOBAL(trace_id),
+                  TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+                  "status", CacheStorageTracedValue(error));
+
               if (error != CacheStorageError::kSuccess) {
                 std::move(callback).Run(
                     blink::mojom::OpenResult::NewStatus(error));
@@ -438,7 +600,7 @@
               std::move(callback).Run(
                   blink::mojom::OpenResult::NewCache(std::move(ptr_info)));
             },
-            weak_factory_.GetWeakPtr(), base::TimeTicks::Now(),
+            weak_factory_.GetWeakPtr(), base::TimeTicks::Now(), trace_id,
             std::move(callback));
 
     if (!cache_storage) {
@@ -447,7 +609,7 @@
       return;
     }
 
-    cache_storage->OpenCache(base::UTF16ToUTF8(cache_name), std::move(cb));
+    cache_storage->OpenCache(utf8_cache_name, trace_id, std::move(cb));
   }
 
  private:
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc
index df91843a..a0ca265a9 100644
--- a/content/browser/cache_storage/cache_storage_manager_unittest.cc
+++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -334,7 +334,7 @@
     CacheStorageHandle cache_storage =
         cache_manager_->OpenCacheStorage(origin, owner);
     cache_storage.value()->OpenCache(
-        cache_name,
+        cache_name, /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::CacheAndErrorCallback,
                        base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
@@ -357,7 +357,7 @@
     CacheStorageHandle cache_storage =
         cache_manager_->OpenCacheStorage(origin, owner);
     cache_storage.value()->HasCache(
-        cache_name,
+        cache_name, /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::BoolAndErrorCallback,
                        base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
@@ -373,7 +373,7 @@
     CacheStorageHandle cache_storage =
         cache_manager_->OpenCacheStorage(origin, owner);
     cache_storage.value()->DoomCache(
-        cache_name,
+        cache_name, /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::ErrorCallback,
                        base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
@@ -388,6 +388,7 @@
     CacheStorageHandle cache_storage =
         cache_manager_->OpenCacheStorage(origin, owner);
     cache_storage.value()->EnumerateCaches(
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::CacheMetadataCallback,
                        base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
@@ -418,6 +419,7 @@
         cache_manager_->OpenCacheStorage(origin, owner);
     cache_storage.value()->MatchCache(
         cache_name, std::move(request), std::move(match_options),
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback,
                        base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
@@ -447,6 +449,7 @@
         cache_manager_->OpenCacheStorage(origin, owner);
     cache_storage.value()->MatchAllCaches(
         std::move(request), std::move(match_options),
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback,
                        base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
@@ -467,6 +470,7 @@
         cache_manager_->OpenCacheStorage(origin, owner);
     cache_storage.value()->WriteToCache(
         cache_name, std::move(request), blink::mojom::FetchAPIResponse::New(),
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::ErrorCallback,
                        base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
@@ -534,6 +538,7 @@
     base::RunLoop loop;
     cache->BatchOperation(
         std::move(operations), true /* fail_on_duplicate */,
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::CachePutCallback,
                        base::Unretained(this), base::Unretained(&loop)),
         CacheStorageCache::BadMessageCallback());
@@ -557,6 +562,7 @@
     base::RunLoop loop;
     cache->BatchOperation(
         std::move(operations), true /* fail_on_duplicate */,
+        /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::CacheDeleteCallback,
                        base::Unretained(this), base::Unretained(&loop)),
         CacheStorageCache::BadMessageCallback());
@@ -570,7 +576,7 @@
     request->url = url;
     base::RunLoop loop;
     cache->Match(
-        std::move(request), nullptr,
+        std::move(request), nullptr, /* trace_id = */ 0,
         base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback,
                        base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
@@ -1403,7 +1409,7 @@
 
   base::RunLoop open_loop;
   cache_storage.value()->OpenCache(
-      "foo",
+      "foo", /* trace_id = */ 0,
       base::BindOnce(&CacheStorageManagerTest::CacheAndErrorCallback,
                      base::Unretained(this), base::Unretained(&open_loop)));
 
diff --git a/content/browser/cache_storage/cache_storage_trace_utils.cc b/content/browser/cache_storage/cache_storage_trace_utils.cc
new file mode 100644
index 0000000..966dc20e
--- /dev/null
+++ b/content/browser/cache_storage/cache_storage_trace_utils.cc
@@ -0,0 +1,131 @@
+// 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 "content/browser/cache_storage/cache_storage_trace_utils.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "base/trace_event/traced_value.h"
+#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h"
+
+namespace content {
+
+namespace {
+
+template <typename T>
+std::string MojoEnumToString(T value) {
+  std::ostringstream oss;
+  oss << value;
+  return oss.str();
+}
+
+}  // namespace
+
+using base::trace_event::TracedValue;
+
+std::string CacheStorageTracedValue(blink::mojom::CacheStorageError error) {
+  return MojoEnumToString(error);
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const blink::mojom::FetchAPIRequestPtr& request) {
+  std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
+  if (request) {
+    value->SetString("url", request->url.spec());
+    value->SetString("method", MojoEnumToString(request->method));
+    value->SetString("mode", MojoEnumToString(request->mode));
+  }
+  return value;
+}
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const std::vector<blink::mojom::FetchAPIRequestPtr>& request_list) {
+  std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
+  value->SetInteger("count", request_list.size());
+  if (!request_list.empty()) {
+    value->SetValue("first",
+                    CacheStorageTracedValue(request_list.front()).get());
+  }
+  return value;
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const blink::mojom::FetchAPIResponsePtr& response) {
+  std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
+  if (response) {
+    if (!response->url_list.empty())
+      value->SetString("url", response->url_list.back().spec());
+    value->SetString("type", MojoEnumToString(response->response_type));
+  }
+  return value;
+}
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const std::vector<blink::mojom::FetchAPIResponsePtr>& response_list) {
+  std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
+  value->SetInteger("count", response_list.size());
+  if (!response_list.empty()) {
+    value->SetValue("first",
+                    CacheStorageTracedValue(response_list.front()).get());
+  }
+  return value;
+}
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const blink::mojom::CacheQueryOptionsPtr& options) {
+  std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
+  if (options) {
+    value->SetBoolean("ignore_method", options->ignore_method);
+    value->SetBoolean("ignore_search", options->ignore_search);
+    value->SetBoolean("ignore_vary", options->ignore_vary);
+  }
+  return value;
+}
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const blink::mojom::MultiCacheQueryOptionsPtr& options) {
+  if (!options)
+    return std::make_unique<TracedValue>();
+  std::unique_ptr<TracedValue> value =
+      CacheStorageTracedValue(options->query_options);
+  if (options->cache_name) {
+    value->SetString("cache_name", base::UTF16ToUTF8(*options->cache_name));
+  }
+  return value;
+}
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const blink::mojom::BatchOperationPtr& op) {
+  std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
+  if (op) {
+    value->SetString("operation_type", MojoEnumToString(op->operation_type));
+    value->SetValue("request", CacheStorageTracedValue(op->request).get());
+    value->SetValue("response", CacheStorageTracedValue(op->response).get());
+    value->SetValue("options",
+                    CacheStorageTracedValue(op->match_options).get());
+  }
+  return value;
+}
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const std::vector<blink::mojom::BatchOperationPtr>& operation_list) {
+  std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
+  value->SetInteger("count", operation_list.size());
+  if (!operation_list.empty()) {
+    value->SetValue("first",
+                    CacheStorageTracedValue(operation_list.front()).get());
+  }
+  return value;
+}
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const std::vector<base::string16> string_list) {
+  std::unique_ptr<TracedValue> value = std::make_unique<TracedValue>();
+  value->SetInteger("count", string_list.size());
+  if (!string_list.empty()) {
+    value->SetString("first", base::UTF16ToUTF8(string_list.front()));
+  }
+  return value;
+}
+
+}  // namespace content
diff --git a/content/browser/cache_storage/cache_storage_trace_utils.h b/content/browser/cache_storage/cache_storage_trace_utils.h
new file mode 100644
index 0000000..0b71c744
--- /dev/null
+++ b/content/browser/cache_storage/cache_storage_trace_utils.h
@@ -0,0 +1,62 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_TRACE_UTILS_H_
+#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_TRACE_UTILS_H_
+
+#include <memory>
+#include <vector>
+
+#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-forward.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-forward.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-forward.h"
+
+namespace base {
+namespace trace_event {
+class TracedValue;
+}  // namespace trace_event
+}  // namespace base
+
+namespace content {
+
+// The following are a set of helper functions to convert a cache_storage
+// related value into something that can be passed to the TRACE_EVENT*
+// macros.
+//
+// Note, these are designed to use content mojo types and base::TracedValue.
+// Unforfortunately these types are not usable in blink, so these routines
+// must be duplicated there as well.
+
+std::string CacheStorageTracedValue(blink::mojom::CacheStorageError error);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const blink::mojom::FetchAPIRequestPtr& request);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const std::vector<blink::mojom::FetchAPIRequestPtr>& request_list);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const blink::mojom::FetchAPIResponsePtr& response);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const std::vector<blink::mojom::FetchAPIResponsePtr>& response_list);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const blink::mojom::CacheQueryOptionsPtr& options);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const blink::mojom::MultiCacheQueryOptionsPtr& options);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const blink::mojom::BatchOperationPtr& op);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const std::vector<blink::mojom::BatchOperationPtr>& operation_list);
+
+std::unique_ptr<base::trace_event::TracedValue> CacheStorageTracedValue(
+    const std::vector<base::string16> string_list);
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_TRACE_UTILS_H_
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 4768ac1..7a93a9a3 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -67,7 +67,6 @@
 #include "ui/base/ui_base_features.h"
 #include "ui/base/ui_base_switches_util.h"
 #include "ui/compositor/compositor.h"
-#include "ui/compositor/compositor_switches.h"
 #include "ui/compositor/host/external_begin_frame_controller_client_impl.h"
 #include "ui/compositor/layer.h"
 #include "ui/display/display_switches.h"
diff --git a/content/browser/frame_host/OWNERS b/content/browser/frame_host/OWNERS
index 6065db2c..66f5ba1 100644
--- a/content/browser/frame_host/OWNERS
+++ b/content/browser/frame_host/OWNERS
@@ -1,4 +1,5 @@
 # COMPONENT: Internals>Sandbox>SiteIsolation
+arthursonzogni@chromium.org
 
 # For surface ID propagation and synchronization
 per-file render_widget_host_view_guest*=fsamuel@chromium.org
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc
index 1e91218..6b7853d 100644
--- a/content/browser/frame_host/navigation_handle_impl.cc
+++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -4,7 +4,9 @@
 
 #include "content/browser/frame_host/navigation_handle_impl.h"
 
+#include "base/bind.h"
 #include "base/debug/dump_without_crashing.h"
+#include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "content/browser/appcache/appcache_navigation_handle.h"
 #include "content/browser/appcache/appcache_service_impl.h"
@@ -12,13 +14,22 @@
 #include "content/browser/devtools/devtools_instrumentation.h"
 #include "content/browser/frame_host/debug_urls.h"
 #include "content/browser/frame_host/navigation_controller_impl.h"
+#include "content/browser/frame_host/navigation_entry_impl.h"
 #include "content/browser/frame_host/navigator.h"
+#include "content/browser/frame_host/navigator_delegate.h"
 #include "content/browser/loader/resource_dispatcher_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/service_worker/service_worker_navigation_handle.h"
 #include "content/common/frame_messages.h"
+#include "content/public/browser/navigation_ui_data.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/child_process_host.h"
+#include "content/public/common/content_client.h"
+#include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
+#include "net/base/net_errors.h"
+#include "services/network/public/cpp/resource_request_body.h"
 
 namespace content {
 
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h
index 53cf57aa..8af1a46 100644
--- a/content/browser/frame_host/navigation_handle_impl.h
+++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -51,6 +51,7 @@
 class NavigatorDelegate;
 class ServiceWorkerContextWrapper;
 class ServiceWorkerNavigationHandle;
+class SiteInstanceImpl;
 
 // This class keeps track of a single navigation. It is created after the
 // BeforeUnload for the navigation has run. It is then owned by the
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index bdeb6ef..06188ffa 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -944,7 +944,7 @@
   // For now, DevTools needs the POST data sent to the renderer process even if
   // it is no longer a POST after the redirect.
   if (redirect_info.new_method != "POST")
-    common_params_.post_data = nullptr;
+    common_params_.post_data.reset();
 
   // Mark time for the Navigation Timing API.
   if (commit_params_.navigation_timing.redirect_start.is_null()) {
@@ -1055,7 +1055,7 @@
     base::Optional<SubresourceLoaderParams> subresource_loader_params) {
   // The |loader_|'s job is finished. It must not call the NavigationRequest
   // anymore from now.
-  loader_ = nullptr;
+  loader_.reset();
   is_download_ = is_download && IsNavigationDownloadAllowed(download_policy);
   is_stream_ = is_stream;
   request_id_ = request_id;
@@ -1286,7 +1286,7 @@
 
   // The |loader_|'s job is finished. It must not call the NavigationRequest
   // anymore from now.
-  loader_ = nullptr;
+  loader_.reset();
 
   bool collapse_frame =
       status.extended_error_code ==
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 2ee25ad..3dbf8d3 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -918,15 +918,24 @@
     if (!IsURLHandledByNetworkService(resource_request_->url)) {
       if (known_schemes_.find(resource_request_->url.scheme()) ==
           known_schemes_.end()) {
+        network::mojom::URLLoaderFactory* external_protocol_factory = nullptr;
         bool handled = GetContentClient()->browser()->HandleExternalProtocol(
             resource_request_->url, web_contents_getter_,
             ChildProcessHost::kInvalidUniqueID, navigation_ui_data_.get(),
             resource_request_->resource_type == RESOURCE_TYPE_MAIN_FRAME,
             static_cast<ui::PageTransition>(resource_request_->transition_type),
             resource_request_->has_user_gesture, resource_request_->method,
-            resource_request_->headers);
-        factory = base::MakeRefCounted<SingleRequestURLLoaderFactory>(
-            base::BindOnce(UnknownSchemeCallback, handled));
+            resource_request_->headers, &proxied_factory_request_,
+            external_protocol_factory);
+
+        if (external_protocol_factory) {
+          factory =
+              base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+                  external_protocol_factory);
+        } else {
+          factory = base::MakeRefCounted<SingleRequestURLLoaderFactory>(
+              base::BindOnce(UnknownSchemeCallback, handled));
+        }
       } else {
         network::mojom::URLLoaderFactoryPtr& non_network_factory =
             non_network_url_loader_factories_[resource_request_->url.scheme()];
@@ -1000,7 +1009,7 @@
         &should_clear_upload);
     if (should_clear_upload) {
       // The request body is no longer applicable.
-      resource_request_->request_body = nullptr;
+      resource_request_->request_body.reset();
       blob_handles_.clear();
     }
 
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 2247abad..d3f372e 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -629,11 +629,13 @@
   if (!url.is_valid() || job_factory->IsHandledProtocol(url.scheme()))
     return false;
 
+  network::mojom::URLLoaderFactory* dummy = nullptr;
+
   return GetContentClient()->browser()->HandleExternalProtocol(
       url, info->GetWebContentsGetterForRequest(), info->GetChildID(),
       info->GetNavigationUIData(), info->IsMainFrame(),
       info->GetPageTransition(), info->HasUserGesture(), url_request->method(),
-      url_request->extra_request_headers());
+      url_request->extra_request_headers(), nullptr, dummy);
 }
 
 void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) {
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index 03398a09..70c6784e 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -2185,7 +2185,9 @@
       ui::PageTransition page_transition,
       bool has_user_gesture,
       const std::string& method,
-      const net::HttpRequestHeaders& headers) override {
+      const net::HttpRequestHeaders& headers,
+      network::mojom::URLLoaderFactoryRequest* factory_request,
+      network::mojom::URLLoaderFactory*& out_factory) override {
     return false;
   }
 
diff --git a/content/browser/net/reporting_service_proxy.cc b/content/browser/net/reporting_service_proxy.cc
index 1e59afac..a252306 100644
--- a/content/browser/net/reporting_service_proxy.cc
+++ b/content/browser/net/reporting_service_proxy.cc
@@ -18,7 +18,6 @@
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "net/reporting/reporting_report.h"
 #include "net/reporting/reporting_service.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "services/network/public/mojom/network_context.mojom.h"
diff --git a/content/browser/renderer_host/code_cache_host_impl.cc b/content/browser/renderer_host/code_cache_host_impl.cc
index 63a98701..b40aafd 100644
--- a/content/browser/renderer_host/code_cache_host_impl.cc
+++ b/content/browser/renderer_host/code_cache_host_impl.cc
@@ -25,6 +25,7 @@
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "net/base/features.h"
 #include "net/base/io_buffer.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -202,6 +203,12 @@
     const std::vector<uint8_t>& data,
     const url::Origin& cache_storage_origin,
     const std::string& cache_storage_cache_name) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW1(
+      "CacheStorage",
+      "CodeCacheHostImpl::DidGenerateCacheableMetadataInCacheStorage",
+      TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT, "url", url.spec());
+
   if (!cache_storage_context_->cache_manager())
     return;
 
@@ -214,10 +221,10 @@
       cache_storage_context_->cache_manager()->OpenCacheStorage(
           cache_storage_origin, CacheStorageOwner::kCacheAPI);
   cache_storage.value()->OpenCache(
-      cache_storage_cache_name,
+      cache_storage_cache_name, trace_id,
       base::BindOnce(&CodeCacheHostImpl::OnCacheStorageOpenCallback,
                      weak_ptr_factory_.GetWeakPtr(), url,
-                     expected_response_time, buf, data.size()));
+                     expected_response_time, trace_id, buf, data.size()));
 }
 
 GeneratedCodeCache* CodeCacheHostImpl::GetCodeCache(
@@ -243,16 +250,21 @@
 void CodeCacheHostImpl::OnCacheStorageOpenCallback(
     const GURL& url,
     base::Time expected_response_time,
+    int64_t trace_id,
     scoped_refptr<net::IOBuffer> buf,
     int buf_len,
     CacheStorageCacheHandle cache_handle,
     CacheStorageError error) {
+  TRACE_EVENT_WITH_FLOW1(
+      "CacheStorage", "CodeCacheHostImpl::OnCacheStorageOpenCallback",
+      TRACE_ID_GLOBAL(trace_id),
+      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "url", url.spec());
   if (error != CacheStorageError::kSuccess || !cache_handle.value())
     return;
   CacheStorageCache* cache = cache_handle.value();
   cache->WriteSideData(
       base::BindOnce(&NoOpCacheStorageErrorCallback, std::move(cache_handle)),
-      url, expected_response_time, buf, buf_len);
+      url, expected_response_time, trace_id, buf, buf_len);
 }
 
 // static
diff --git a/content/browser/renderer_host/code_cache_host_impl.h b/content/browser/renderer_host/code_cache_host_impl.h
index f48ff405..368f888 100644
--- a/content/browser/renderer_host/code_cache_host_impl.h
+++ b/content/browser/renderer_host/code_cache_host_impl.h
@@ -77,6 +77,7 @@
                            const std::vector<uint8_t>& data);
   void OnCacheStorageOpenCallback(const GURL& url,
                                   base::Time expected_response_time,
+                                  int64_t trace_id,
                                   scoped_refptr<net::IOBuffer> buf,
                                   int buf_len,
                                   CacheStorageCacheHandle cache_handle,
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index 09e5c2a..636a733 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -3185,8 +3185,9 @@
         cache_storage_context_->cache_manager()->OpenCacheStorage(
             url::Origin::Create(origin_), CacheStorageOwner::kCacheAPI);
     cache_storage.value()->OpenCache(
-        cache_name_, base::BindOnce(&self::OnCacheStorageOpenCallback, this,
-                                    result, std::move(continuation)));
+        cache_name_, /* trace_id = */ 0,
+        base::BindOnce(&self::OnCacheStorageOpenCallback, this, result,
+                       std::move(continuation)));
   }
 
   void OnCacheStorageOpenCallback(int* result,
@@ -3198,7 +3199,7 @@
     scoped_request->url = url_;
     CacheStorageCache* cache = cache_handle.value();
     cache->Match(
-        std::move(scoped_request), nullptr,
+        std::move(scoped_request), nullptr, /* trace_id = */ 0,
         base::BindOnce(&self::OnCacheStorageCacheMatchCallback, this, result,
                        std::move(continuation), std::move(cache_handle)));
   }
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 9ad7688..38fc0c8 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1789,13 +1789,11 @@
   if (GetRenderViewHost()->SuddenTerminationAllowed())
     return false;
 
-  // TODO(alexmos): This checks for both beforeunload and unload handlers from
-  // the whole main frame process.  Remove this and explicitly check whether
-  // the main frame has each of these handlers. This can be done for
-  // beforeunload via RenderFrameHostImpl::ShouldDispatchBeforeUnload(), and
-  // something similar is needed for unload.
-  if (!GetMainFrame()->GetProcess()->SuddenTerminationAllowed())
+  // Check whether the main frame needs to run beforeunload or unload handlers.
+  if (GetMainFrame()->GetSuddenTerminationDisablerState(
+          blink::kBeforeUnloadHandler | blink::kUnloadHandler)) {
     return true;
+  }
 
   // Check whether any subframes need to run beforeunload handlers.
   //
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index d0e1df7..82fffbc8 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -1810,6 +1810,8 @@
   NavigateToURL(shell, GURL("data:text/html," + html));
   RenderFrameHostImpl* rfh =
       static_cast<RenderFrameHostImpl*>(shell->web_contents()->GetMainFrame());
+  EXPECT_EQ(expect_onunload || expect_onbeforeunload,
+            shell->web_contents()->NeedToFireBeforeUnload());
   EXPECT_EQ(expect_onunload,
             rfh->GetSuddenTerminationDisablerState(blink::kUnloadHandler));
   EXPECT_EQ(expect_onbeforeunload, rfh->GetSuddenTerminationDisablerState(
@@ -1824,6 +1826,22 @@
                                                   false, false);
 }
 
+IN_PROC_BROWSER_TEST_F(
+    WebContentsImplBrowserTest,
+    SuddenTerminationDisablerNoneProcessTerminationDisallowed) {
+  const std::string NO_HANDLERS_HTML = "<html><body>foo</body></html>";
+  // The WebContents termination disabler should be independent of the
+  // RenderProcessHost termination disabler, as process termination can depend
+  // on more than the presence of a beforeunload/unload handler.
+  shell()
+      ->web_contents()
+      ->GetMainFrame()
+      ->GetProcess()
+      ->SetSuddenTerminationAllowed(false);
+  NavigateToDataURLAndCheckForTerminationDisabler(shell(), NO_HANDLERS_HTML,
+                                                  false, false);
+}
+
 IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                        SuddenTerminationDisablerOnUnload) {
   const std::string UNLOAD_HTML =
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 12f1bca6..4cd2de4 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -307,7 +307,7 @@
   if (base::FeatureList::IsEnabled(features::kGenericSensorExtraClasses))
     WebRuntimeFeatures::EnableGenericSensorExtraClasses(true);
 
-  if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCors))
+  if (network::features::ShouldEnableOutOfBlinkCors())
     WebRuntimeFeatures::EnableOutOfBlinkCors(true);
 
   WebRuntimeFeatures::EnableMediaCastOverlayButton(
diff --git a/content/common/content_param_traits.cc b/content/common/content_param_traits.cc
index ef41ec4e7..e2e33fa 100644
--- a/content/common/content_param_traits.cc
+++ b/content/common/content_param_traits.cc
@@ -264,6 +264,7 @@
   WriteParam(m, p->data.stream_channels);
   WriteParam(m, p->data.has_user_gesture);
   WriteParam(m, !!p->data.user_activation);
+  WriteParam(m, p->data.transfer_user_activation);
   if (p->data.user_activation) {
     WriteParam(m, p->data.user_activation->has_been_active);
     WriteParam(m, p->data.user_activation->was_active);
@@ -294,7 +295,8 @@
       !ReadParam(m, iter, &(*r)->data.ports) ||
       !ReadParam(m, iter, &(*r)->data.stream_channels) ||
       !ReadParam(m, iter, &(*r)->data.has_user_gesture) ||
-      !ReadParam(m, iter, &has_activation)) {
+      !ReadParam(m, iter, &has_activation) ||
+      !ReadParam(m, iter, &(*r)->data.transfer_user_activation)) {
     return false;
   }
 
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index b37de5f..7709ade 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -880,7 +880,9 @@
     ui::PageTransition page_transition,
     bool has_user_gesture,
     const std::string& method,
-    const net::HttpRequestHeaders& headers) {
+    const net::HttpRequestHeaders& headers,
+    network::mojom::URLLoaderFactoryRequest* factory_request,
+    network::mojom::URLLoaderFactory*& out_factory) {
   return true;
 }
 
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 7fc0a70..bdd985c 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -1422,7 +1422,9 @@
       ui::PageTransition page_transition,
       bool has_user_gesture,
       const std::string& method,
-      const net::HttpRequestHeaders& headers);
+      const net::HttpRequestHeaders& headers,
+      network::mojom::URLLoaderFactoryRequest* factory_request,
+      network::mojom::URLLoaderFactory*& out_factory);
 
   // Creates an OverlayWindow to be used for Picture-in-Picture. This window
   // will house the content shown when in Picture-in-Picture mode. This will
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 1b364a7..420e9d3 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -483,6 +483,11 @@
 const char kSkipBrowserTouchFilterTypeParamValueDiscrete[] = "discrete";
 const char kSkipBrowserTouchFilterTypeParamValueAll[] = "all";
 
+// Allows developers transfer user activation state to any target window in the
+// frame tree.
+const base::Feature kUserActivationDelegation{
+    "UserActivationDelegation", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Allows user activation propagation to all frames having the same origin as
 // the activation notifier frame.  This is an intermediate measure before we
 // have an iframe attribute to declaratively allow user activation propagation
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index c47e085..044f2bfcf 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -116,6 +116,7 @@
 CONTENT_EXPORT extern const base::Feature kTimerThrottlingForHiddenFrames;
 CONTENT_EXPORT extern const base::Feature kTouchpadAsyncPinchEvents;
 CONTENT_EXPORT extern const base::Feature kTouchpadOverscrollHistoryNavigation;
+CONTENT_EXPORT extern const base::Feature kUserActivationDelegation;
 CONTENT_EXPORT extern const base::Feature kUserActivationSameOriginVisibility;
 CONTENT_EXPORT extern const base::Feature kUserActivationV2;
 CONTENT_EXPORT extern const base::Feature kUserAgentClientHint;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index ebd6c06..7d2d0cb 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -264,20 +264,12 @@
     "media/stream/media_stream_audio_level_calculator.h",
     "media/stream/media_stream_audio_processor.cc",
     "media/stream/media_stream_audio_processor.h",
-    "media/stream/media_stream_audio_processor_options.cc",
-    "media/stream/media_stream_audio_processor_options.h",
     "media/stream/media_stream_center.cc",
     "media/stream/media_stream_center.h",
-    "media/stream/media_stream_constraints_util.cc",
-    "media/stream/media_stream_constraints_util.h",
     "media/stream/media_stream_constraints_util_audio.cc",
     "media/stream/media_stream_constraints_util_audio.h",
-    "media/stream/media_stream_constraints_util_sets.cc",
-    "media/stream/media_stream_constraints_util_sets.h",
     "media/stream/media_stream_constraints_util_video_content.cc",
     "media/stream/media_stream_constraints_util_video_content.h",
-    "media/stream/media_stream_constraints_util_video_device.cc",
-    "media/stream/media_stream_constraints_util_video_device.h",
     "media/stream/media_stream_device_observer.cc",
     "media/stream/media_stream_device_observer.h",
     "media/stream/media_stream_dispatcher_eventhandler.h",
@@ -287,10 +279,6 @@
     "media/stream/media_stream_video_capturer_source.h",
     "media/stream/media_stream_video_renderer_sink.cc",
     "media/stream/media_stream_video_renderer_sink.h",
-    "media/stream/media_stream_video_source.cc",
-    "media/stream/media_stream_video_source.h",
-    "media/stream/media_stream_video_track.cc",
-    "media/stream/media_stream_video_track.h",
     "media/stream/processed_local_audio_source.cc",
     "media/stream/processed_local_audio_source.h",
     "media/stream/remote_media_stream_track_adapter.cc",
@@ -301,8 +289,6 @@
     "media/stream/user_media_client_impl.h",
     "media/stream/user_media_processor.cc",
     "media/stream/user_media_processor.h",
-    "media/stream/video_track_adapter.cc",
-    "media/stream/video_track_adapter.h",
     "media/stream/webaudio_media_stream_source.cc",
     "media/stream/webaudio_media_stream_source.h",
     "media/stream/webmediaplayer_ms.cc",
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc
index 4ecbd4a..741fc65 100644
--- a/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -518,6 +518,8 @@
   std::set<int32_t> already_serialized_ids;
   for (size_t i = 0; i < dirty_objects.size(); i++) {
     auto obj = dirty_objects[i].obj;
+    if (obj.IsDetached())
+      continue;
     if (already_serialized_ids.find(obj.AxID()) != already_serialized_ids.end())
       continue;
 
diff --git a/content/renderer/media/stream/apply_constraints_processor.cc b/content/renderer/media/stream/apply_constraints_processor.cc
index bd631d5f..ca11019 100644
--- a/content/renderer/media/stream/apply_constraints_processor.cc
+++ b/content/renderer/media/stream/apply_constraints_processor.cc
@@ -15,13 +15,13 @@
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "content/renderer/media/stream/media_stream_constraints_util_audio.h"
 #include "content/renderer/media/stream/media_stream_constraints_util_video_content.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_video_device.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 
 namespace content {
 namespace {
@@ -85,7 +85,7 @@
     return;
   }
 
-  AudioCaptureSettings settings =
+  blink::AudioCaptureSettings settings =
       SelectSettingsAudioCapture(audio_source, current_request_.Constraints());
   if (settings.HasValue()) {
     ApplyConstraintsSucceeded();
@@ -143,7 +143,7 @@
   if (AbortIfVideoRequestStateInvalid())
     return;
 
-  VideoCaptureSettings settings = SelectVideoSettings(formats);
+  blink::VideoCaptureSettings settings = SelectVideoSettings(formats);
   if (!settings.HasValue()) {
     ApplyConstraintsFailed(settings.failed_constraint_name());
     return;
@@ -161,17 +161,17 @@
 }
 
 void ApplyConstraintsProcessor::MaybeSourceStoppedForRestart(
-    MediaStreamVideoSource::RestartResult result) {
+    blink::MediaStreamVideoSource::RestartResult result) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (AbortIfVideoRequestStateInvalid())
     return;
 
-  if (result == MediaStreamVideoSource::RestartResult::IS_RUNNING) {
+  if (result == blink::MediaStreamVideoSource::RestartResult::IS_RUNNING) {
     FinalizeVideoRequest();
     return;
   }
 
-  DCHECK_EQ(result, MediaStreamVideoSource::RestartResult::IS_STOPPED);
+  DCHECK_EQ(result, blink::MediaStreamVideoSource::RestartResult::IS_STOPPED);
   GetMediaDevicesDispatcher()->GetAvailableVideoInputDeviceFormats(
       video_source_->device().id,
       base::BindOnce(&ApplyConstraintsProcessor::FindNewFormatAndRestart,
@@ -184,7 +184,7 @@
   if (AbortIfVideoRequestStateInvalid())
     return;
 
-  VideoCaptureSettings settings = SelectVideoSettings(formats);
+  blink::VideoCaptureSettings settings = SelectVideoSettings(formats);
   DCHECK(video_source_->GetCurrentFormat());
   // |settings| should have a value. If it does not due to some unexpected
   // reason (perhaps a race with another renderer process), restart the source
@@ -197,15 +197,15 @@
 }
 
 void ApplyConstraintsProcessor::MaybeSourceRestarted(
-    MediaStreamVideoSource::RestartResult result) {
+    blink::MediaStreamVideoSource::RestartResult result) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (AbortIfVideoRequestStateInvalid())
     return;
 
-  if (result == MediaStreamVideoSource::RestartResult::IS_RUNNING) {
+  if (result == blink::MediaStreamVideoSource::RestartResult::IS_RUNNING) {
     FinalizeVideoRequest();
   } else {
-    DCHECK_EQ(result, MediaStreamVideoSource::RestartResult::IS_STOPPED);
+    DCHECK_EQ(result, blink::MediaStreamVideoSource::RestartResult::IS_STOPPED);
     CannotApplyConstraints("Source failed to restart");
     video_source_->StopSource();
   }
@@ -222,7 +222,7 @@
   } else {
     format = GetCurrentVideoTrack()->GetComputedSourceFormat();
   }
-  VideoCaptureSettings settings = SelectVideoSettings({format});
+  blink::VideoCaptureSettings settings = SelectVideoSettings({format});
 
   if (settings.HasValue()) {
     video_source_->ReconfigureTrack(GetCurrentVideoTrack(),
@@ -233,7 +233,7 @@
   }
 }
 
-VideoCaptureSettings ApplyConstraintsProcessor::SelectVideoSettings(
+blink::VideoCaptureSettings ApplyConstraintsProcessor::SelectVideoSettings(
     media::VideoCaptureFormats formats) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!current_request_.IsNull());
@@ -242,7 +242,7 @@
   DCHECK(request_completed_cb_);
   DCHECK_GT(formats.size(), 0U);
 
-  VideoInputDeviceCapabilities device_capabilities;
+  blink::VideoInputDeviceCapabilities device_capabilities;
   device_capabilities.device_id =
       current_request_.Track().Source().Id().Ascii();
   device_capabilities.group_id =
@@ -252,7 +252,7 @@
                               : media::MEDIA_VIDEO_FACING_NONE;
   device_capabilities.formats = std::move(formats);
 
-  VideoDeviceCaptureCapabilities video_capabilities;
+  blink::VideoDeviceCaptureCapabilities video_capabilities;
   video_capabilities.noise_reduction_capabilities.push_back(
       GetCurrentVideoTrack()->noise_reduction());
   video_capabilities.device_capabilities.push_back(
@@ -263,9 +263,9 @@
   // fallback in case GetSettings returns nothing and leaves |settings|
   // unmodified.
   blink::WebMediaStreamTrack::Settings settings;
-  settings.width = MediaStreamVideoSource::kDefaultWidth;
-  settings.height = MediaStreamVideoSource::kDefaultHeight;
-  settings.frame_rate = MediaStreamVideoSource::kDefaultFrameRate;
+  settings.width = blink::MediaStreamVideoSource::kDefaultWidth;
+  settings.height = blink::MediaStreamVideoSource::kDefaultHeight;
+  settings.frame_rate = blink::MediaStreamVideoSource::kDefaultFrameRate;
   GetCurrentVideoTrack()->GetSettings(settings);
 
   return SelectSettingsVideoDeviceCapture(
@@ -280,15 +280,17 @@
   return blink::MediaStreamAudioSource::From(current_request_.Track().Source());
 }
 
-MediaStreamVideoTrack* ApplyConstraintsProcessor::GetCurrentVideoTrack() {
+blink::MediaStreamVideoTrack*
+ApplyConstraintsProcessor::GetCurrentVideoTrack() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  MediaStreamVideoTrack* track =
-      MediaStreamVideoTrack::GetVideoTrack(current_request_.Track());
+  blink::MediaStreamVideoTrack* track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(current_request_.Track());
   DCHECK(track);
   return track;
 }
 
-MediaStreamVideoSource* ApplyConstraintsProcessor::GetCurrentVideoSource() {
+blink::MediaStreamVideoSource*
+ApplyConstraintsProcessor::GetCurrentVideoSource() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return GetCurrentVideoTrack()->source();
 }
diff --git a/content/renderer/media/stream/apply_constraints_processor.h b/content/renderer/media/stream/apply_constraints_processor.h
index 1638461..1907819 100644
--- a/content/renderer/media/stream/apply_constraints_processor.h
+++ b/content/renderer/media/stream/apply_constraints_processor.h
@@ -11,21 +11,20 @@
 #include "base/sequence_checker.h"
 #include "base/single_thread_task_runner.h"
 #include "content/common/content_export.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "media/capture/video_capture_types.h"
 #include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 #include "third_party/blink/public/web/web_apply_constraints_request.h"
 
 namespace blink {
 class MediaStreamAudioSource;
+class MediaStreamVideoSource;
+class MediaStreamVideoTrack;
 class WebString;
 }
 
 namespace content {
 
-class MediaStreamVideoSource;
-class MediaStreamVideoTrack;
-
 // ApplyConstraintsProcessor is responsible for processing applyConstraints()
 // requests. Only one applyConstraints() request can be processed at a time.
 // ApplyConstraintsProcessor must be created, called and destroyed on the main
@@ -51,16 +50,18 @@
   void ProcessVideoDeviceRequest();
   void MaybeStopSourceForRestart(const media::VideoCaptureFormats& formats);
   void MaybeSourceStoppedForRestart(
-      MediaStreamVideoSource::RestartResult result);
+      blink::MediaStreamVideoSource::RestartResult result);
   void FindNewFormatAndRestart(const media::VideoCaptureFormats& formats);
-  void MaybeSourceRestarted(MediaStreamVideoSource::RestartResult result);
+  void MaybeSourceRestarted(
+      blink::MediaStreamVideoSource::RestartResult result);
 
   // Helpers for all video requests.
   void ProcessVideoRequest();
-  MediaStreamVideoTrack* GetCurrentVideoTrack();
-  MediaStreamVideoSource* GetCurrentVideoSource();
+  blink::MediaStreamVideoTrack* GetCurrentVideoTrack();
+  blink::MediaStreamVideoSource* GetCurrentVideoSource();
   bool AbortIfVideoRequestStateInvalid();  // Returns true if aborted.
-  VideoCaptureSettings SelectVideoSettings(media::VideoCaptureFormats formats);
+  blink::VideoCaptureSettings SelectVideoSettings(
+      media::VideoCaptureFormats formats);
   void FinalizeVideoRequest();
 
   // Helpers for audio requests.
@@ -80,7 +81,7 @@
   // |video_source_| and |request_completed_cb_| are the video source and
   // reply callback for the current request.
   blink::WebApplyConstraintsRequest current_request_;
-  MediaStreamVideoSource* video_source_ = nullptr;
+  blink::MediaStreamVideoSource* video_source_ = nullptr;
   base::OnceClosure request_completed_cb_;
 
   MediaDevicesDispatcherCallback media_devices_dispatcher_cb_;
diff --git a/content/renderer/media/stream/media_stream_audio_processor.cc b/content/renderer/media/stream/media_stream_audio_processor.cc
index e171ed9..236ecf7 100644
--- a/content/renderer/media/stream/media_stream_audio_processor.cc
+++ b/content/renderer/media/stream/media_stream_audio_processor.cc
@@ -41,7 +41,8 @@
 
 namespace content {
 
-using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+using EchoCancellationType =
+    blink::AudioProcessingProperties::EchoCancellationType;
 
 namespace {
 
@@ -267,7 +268,7 @@
 };
 
 MediaStreamAudioProcessor::MediaStreamAudioProcessor(
-    const AudioProcessingProperties& properties,
+    const blink::AudioProcessingProperties& properties,
     WebRtcPlayoutDataSource* playout_data_source)
     : render_delay_ms_(0),
       audio_delay_stats_reporter_(kBuffersPerSecond),
@@ -377,7 +378,7 @@
     return;
 
   audio_processing_.get()->UpdateHistogramsOnCallEnd();
-  StopEchoCancellationDump(audio_processing_.get());
+  blink::StopEchoCancellationDump(audio_processing_.get());
   worker_queue_.reset(nullptr);
 
   if (playout_data_source_) {
@@ -409,8 +410,8 @@
     // Here tasks will be posted on the |worker_queue_|. It must be
     // kept alive until StopEchoCancellationDump is called or the
     // webrtc::AudioProcessing instance is destroyed.
-    StartEchoCancellationDump(audio_processing_.get(), std::move(file),
-                              worker_queue_.get());
+    blink::StartEchoCancellationDump(audio_processing_.get(), std::move(file),
+                                     worker_queue_.get());
   } else {
     file.Close();
   }
@@ -419,7 +420,7 @@
 void MediaStreamAudioProcessor::OnDisableAecDump() {
   DCHECK(main_thread_runner_->BelongsToCurrentThread());
   if (audio_processing_)
-    StopEchoCancellationDump(audio_processing_.get());
+    blink::StopEchoCancellationDump(audio_processing_.get());
 
   // Note that deleting an rtc::TaskQueue has to be done from the
   // thread that created it.
@@ -433,7 +434,7 @@
 
 // static
 bool MediaStreamAudioProcessor::WouldModifyAudio(
-    const AudioProcessingProperties& properties) {
+    const blink::AudioProcessingProperties& properties) {
   // Note: This method should by kept in-sync with any changes to the logic in
   // MediaStreamAudioProcessor::InitializeAudioProcessingModule().
 
@@ -524,7 +525,7 @@
 }
 
 void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
-    const AudioProcessingProperties& properties) {
+    const blink::AudioProcessingProperties& properties) {
   DCHECK(main_thread_runner_->BelongsToCurrentThread());
   DCHECK(!audio_processing_);
 
@@ -609,30 +610,32 @@
   }
 
   if (properties.EchoCancellationIsWebRtcProvided()) {
-    EnableEchoCancellation(audio_processing_.get());
+    blink::EnableEchoCancellation(audio_processing_.get());
   }
 
   if (properties.goog_noise_suppression)
-    EnableNoiseSuppression(audio_processing_.get(), NoiseSuppression::kHigh);
+    blink::EnableNoiseSuppression(audio_processing_.get(),
+                                  NoiseSuppression::kHigh);
 
   if (goog_typing_detection) {
     // TODO(xians): Remove this |typing_detector_| after the typing suppression
     // is enabled by default.
     typing_detector_.reset(new webrtc::TypingDetection());
-    EnableTypingDetection(audio_processing_.get(), typing_detector_.get());
+    blink::EnableTypingDetection(audio_processing_.get(),
+                                 typing_detector_.get());
   }
 
   // TODO(saza): When Chrome uses AGC2, handle all JSON config via the
   // webrtc::AudioProcessing::Config, crbug.com/895814.
   base::Optional<double> pre_amplifier_fixed_gain_factor,
       gain_control_compression_gain_db;
-  GetExtraGainConfig(audio_processing_platform_config_json,
-                     &pre_amplifier_fixed_gain_factor,
-                     &gain_control_compression_gain_db);
+  blink::GetExtraGainConfig(audio_processing_platform_config_json,
+                            &pre_amplifier_fixed_gain_factor,
+                            &gain_control_compression_gain_db);
 
   if (properties.goog_auto_gain_control) {
-    EnableAutomaticGainControl(audio_processing_.get(),
-                               gain_control_compression_gain_db);
+    blink::EnableAutomaticGainControl(audio_processing_.get(),
+                                      gain_control_compression_gain_db);
   }
 
   webrtc::AudioProcessing::Config apm_config = audio_processing_->GetConfig();
@@ -659,7 +662,7 @@
           saturation_margin;
     }
   }
-  ConfigPreAmplifier(&apm_config, pre_amplifier_fixed_gain_factor);
+  blink::ConfigPreAmplifier(&apm_config, pre_amplifier_fixed_gain_factor);
   audio_processing_->ApplyConfig(apm_config);
 
   RecordProcessingState(AUDIO_PROCESSING_ENABLED);
@@ -676,8 +679,9 @@
   // either use the input parameters (in which case, audio processing will
   // convert at output) or ideally, have a backchannel from the sink to know
   // what format it would prefer.
-  const int output_sample_rate = audio_processing_ ? kAudioProcessingSampleRate
-                                                   : input_format.sample_rate();
+  const int output_sample_rate = audio_processing_
+                                     ? blink::kAudioProcessingSampleRate
+                                     : input_format.sample_rate();
   media::ChannelLayout output_channel_layout = audio_processing_ ?
       media::GuessChannelLayout(kAudioProcessingNumberOfChannels) :
       input_format.channel_layout();
diff --git a/content/renderer/media/stream/media_stream_audio_processor.h b/content/renderer/media/stream/media_stream_audio_processor.h
index 12884d88..dc200497 100644
--- a/content/renderer/media/stream/media_stream_audio_processor.h
+++ b/content/renderer/media/stream/media_stream_audio_processor.h
@@ -19,11 +19,11 @@
 #include "base/time/time.h"
 #include "content/common/content_export.h"
 #include "content/renderer/media/stream/aec_dump_message_filter.h"
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
 #include "content/renderer/media/webrtc/webrtc_audio_device_impl.h"
 #include "media/base/audio_converter.h"
 #include "media/webrtc/audio_delay_stats_reporter.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
 #include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
 #include "third_party/webrtc/rtc_base/task_queue.h"
@@ -59,7 +59,7 @@
   //
   // Threading note: The constructor assumes it is being run on the main render
   // thread.
-  MediaStreamAudioProcessor(const AudioProcessingProperties& properties,
+  MediaStreamAudioProcessor(const blink::AudioProcessingProperties& properties,
                             WebRtcPlayoutDataSource* playout_data_source);
 
   // Called when the format of the capture data has changed.
@@ -115,7 +115,8 @@
   // based on |properties|. If the audio signal would not be modified, there is
   // no need to instantiate a MediaStreamAudioProcessor and feed audio through
   // it. Doing so would waste a non-trivial amount of memory and CPU resources.
-  static bool WouldModifyAudio(const AudioProcessingProperties& properties);
+  static bool WouldModifyAudio(
+      const blink::AudioProcessingProperties& properties);
 
  protected:
   ~MediaStreamAudioProcessor() override;
@@ -138,7 +139,7 @@
 
   // Helper to initialize the WebRtc AudioProcessing.
   void InitializeAudioProcessingModule(
-      const AudioProcessingProperties& properties);
+      const blink::AudioProcessingProperties& properties);
 
   // Helper to initialize the capture converter.
   void InitializeCaptureFifo(const media::AudioParameters& input_format);
diff --git a/content/renderer/media/stream/media_stream_audio_processor_unittest.cc b/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
index 14b3cb1..662e3b1 100644
--- a/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
+++ b/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
@@ -21,13 +21,13 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "content/renderer/media/stream/media_stream_audio_processor.h"
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
 #include "content/renderer/media/stream/mock_constraint_factory.h"
 #include "media/base/audio_bus.h"
 #include "media/base/audio_parameters.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
@@ -191,7 +191,7 @@
 TEST_F(MediaStreamAudioProcessorTest, MAYBE_WithAudioProcessing) {
   scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
       new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
-  AudioProcessingProperties properties;
+  blink::AudioProcessingProperties properties;
   scoped_refptr<MediaStreamAudioProcessor> audio_processor(
       new rtc::RefCountedObject<MediaStreamAudioProcessor>(
           properties, webrtc_audio_device.get()));
@@ -199,10 +199,9 @@
   audio_processor->OnCaptureFormatChanged(params_);
   VerifyDefaultComponents(audio_processor.get());
 
-  ProcessDataAndVerifyFormat(audio_processor.get(),
-                             kAudioProcessingSampleRate,
-                             kAudioProcessingNumberOfChannel,
-                             kAudioProcessingSampleRate / 100);
+  ProcessDataAndVerifyFormat(
+      audio_processor.get(), blink::kAudioProcessingSampleRate,
+      kAudioProcessingNumberOfChannel, blink::kAudioProcessingSampleRate / 100);
 
   // Stop |audio_processor| so that it removes itself from
   // |webrtc_audio_device| and clears its pointer to it.
@@ -210,7 +209,7 @@
 }
 
 TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) {
-  AudioProcessingProperties properties;
+  blink::AudioProcessingProperties properties;
   // Turn off the default constraints and pass it to MediaStreamAudioProcessor.
   properties.DisableDefaultProperties();
   scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
@@ -240,7 +239,7 @@
 TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
   scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
       new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
-  AudioProcessingProperties properties;
+  blink::AudioProcessingProperties properties;
   scoped_refptr<MediaStreamAudioProcessor> audio_processor(
       new rtc::RefCountedObject<MediaStreamAudioProcessor>(
           properties, webrtc_audio_device.get()));
@@ -257,9 +256,9 @@
     VerifyDefaultComponents(audio_processor.get());
 
     ProcessDataAndVerifyFormat(audio_processor.get(),
-                               kAudioProcessingSampleRate,
+                               blink::kAudioProcessingSampleRate,
                                kAudioProcessingNumberOfChannel,
-                               kAudioProcessingSampleRate / 100);
+                               blink::kAudioProcessingSampleRate / 100);
   }
 
   // Stop |audio_processor| so that it removes itself from
@@ -278,7 +277,7 @@
 
   scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
       new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
-  AudioProcessingProperties properties;
+  blink::AudioProcessingProperties properties;
   scoped_refptr<MediaStreamAudioProcessor> audio_processor(
       new rtc::RefCountedObject<MediaStreamAudioProcessor>(
           properties, webrtc_audio_device.get()));
@@ -293,7 +292,7 @@
 TEST_F(MediaStreamAudioProcessorTest, StartStopAecDump) {
   scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
       new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
-  AudioProcessingProperties properties;
+  blink::AudioProcessingProperties properties;
 
   base::ScopedTempDir temp_directory;
   ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
@@ -327,7 +326,7 @@
 TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
   scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
       new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
-  AudioProcessingProperties properties;
+  blink::AudioProcessingProperties properties;
   // Turn off the audio processing and turn on the stereo channels mirroring.
   properties.DisableDefaultProperties();
   properties.goog_audio_mirroring = true;
@@ -391,7 +390,7 @@
 TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) {
   scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
       new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
-  AudioProcessingProperties properties;
+  blink::AudioProcessingProperties properties;
   scoped_refptr<MediaStreamAudioProcessor> audio_processor(
       new rtc::RefCountedObject<MediaStreamAudioProcessor>(
           properties, webrtc_audio_device.get()));
@@ -402,10 +401,9 @@
                                 48000, 480);
   audio_processor->OnCaptureFormatChanged(params);
 
-  ProcessDataAndVerifyFormat(audio_processor.get(),
-                             kAudioProcessingSampleRate,
-                             kAudioProcessingNumberOfChannel,
-                             kAudioProcessingSampleRate / 100);
+  ProcessDataAndVerifyFormat(
+      audio_processor.get(), blink::kAudioProcessingSampleRate,
+      kAudioProcessingNumberOfChannel, blink::kAudioProcessingSampleRate / 100);
 
   // Stop |audio_processor| so that it removes itself from
   // |webrtc_audio_device| and clears its pointer to it.
@@ -416,9 +414,9 @@
   base::Optional<std::string> audio_processing_platform_config_json;
   base::Optional<double> pre_amplifier_fixed_gain_factor,
       gain_control_compression_gain_db;
-  GetExtraGainConfig(audio_processing_platform_config_json,
-                     &pre_amplifier_fixed_gain_factor,
-                     &gain_control_compression_gain_db);
+  blink::GetExtraGainConfig(audio_processing_platform_config_json,
+                            &pre_amplifier_fixed_gain_factor,
+                            &gain_control_compression_gain_db);
   EXPECT_FALSE(pre_amplifier_fixed_gain_factor);
   EXPECT_FALSE(gain_control_compression_gain_db);
 }
@@ -428,9 +426,9 @@
       "{\"gain_control_compression_gain_db\": 10}";
   base::Optional<double> pre_amplifier_fixed_gain_factor,
       gain_control_compression_gain_db;
-  GetExtraGainConfig(audio_processing_platform_config_json,
-                     &pre_amplifier_fixed_gain_factor,
-                     &gain_control_compression_gain_db);
+  blink::GetExtraGainConfig(audio_processing_platform_config_json,
+                            &pre_amplifier_fixed_gain_factor,
+                            &gain_control_compression_gain_db);
   EXPECT_FALSE(pre_amplifier_fixed_gain_factor);
   EXPECT_TRUE(gain_control_compression_gain_db);
   EXPECT_EQ(gain_control_compression_gain_db.value(), 10);
diff --git a/content/renderer/media/stream/media_stream_center.cc b/content/renderer/media/stream/media_stream_center.cc
index af27d64..28ed50e 100644
--- a/content/renderer/media/stream/media_stream_center.cc
+++ b/content/renderer/media/stream/media_stream_center.cc
@@ -13,8 +13,6 @@
 #include "base/logging.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/renderer/render_thread.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/processed_local_audio_source.h"
 #include "content/renderer/media/stream/webaudio_media_stream_source.h"
 #include "content/renderer/media/webrtc_local_audio_source_provider.h"
@@ -27,6 +25,8 @@
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_frame.h"
 
 using blink::WebFrame;
@@ -77,11 +77,11 @@
   DCHECK(track.GetPlatformTrack() == nullptr);
   blink::WebMediaStreamSource source = track.Source();
   DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeVideo);
-  MediaStreamVideoSource* native_source =
-      MediaStreamVideoSource::GetVideoSource(source);
+  blink::MediaStreamVideoSource* native_source =
+      blink::MediaStreamVideoSource::GetVideoSource(source);
   DCHECK(native_source);
-  track.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
-      native_source, MediaStreamVideoSource::ConstraintsCallback(),
+  track.SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
+      native_source, blink::MediaStreamVideoSource::ConstraintsCallback(),
       track.IsEnabled()));
 }
 
@@ -91,17 +91,17 @@
   DCHECK(!clone.GetPlatformTrack());
   blink::WebMediaStreamSource source = clone.Source();
   DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeVideo);
-  MediaStreamVideoSource* native_source =
-      MediaStreamVideoSource::GetVideoSource(source);
+  blink::MediaStreamVideoSource* native_source =
+      blink::MediaStreamVideoSource::GetVideoSource(source);
   DCHECK(native_source);
-  MediaStreamVideoTrack* original_track =
-      MediaStreamVideoTrack::GetVideoTrack(original);
+  blink::MediaStreamVideoTrack* original_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(original);
   DCHECK(original_track);
-  clone.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
+  clone.SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
       native_source, original_track->adapter_settings(),
       original_track->noise_reduction(), original_track->is_screencast(),
       original_track->min_frame_rate(),
-      MediaStreamVideoSource::ConstraintsCallback(), clone.IsEnabled()));
+      blink::MediaStreamVideoSource::ConstraintsCallback(), clone.IsEnabled()));
 }
 
 }  // namespace
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio.cc b/content/renderer/media/stream/media_stream_constraints_util_audio.cc
index 14a8824..a1045468 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_audio.cc
+++ b/content/renderer/media/stream/media_stream_constraints_util_audio.cc
@@ -13,21 +13,23 @@
 #include "base/strings/string_number_conversions.h"
 #include "build/build_config.h"
 #include "content/public/common/content_features.h"
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
 #include "content/renderer/media/stream/processed_local_audio_source.h"
 #include "media/audio/audio_features.h"
 #include "media/base/audio_parameters.h"
 #include "media/base/limits.h"
 #include "third_party/blink/public/common/mediastream/media_stream_controls.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
 namespace content {
 
+using blink::AudioCaptureSettings;
+using blink::AudioProcessingProperties;
 using ConstraintSet = blink::WebMediaTrackConstraintSet;
 using BooleanConstraint = blink::BooleanConstraint;
 using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
@@ -35,16 +37,16 @@
 using StringConstraint = blink::StringConstraint;
 
 template <class T>
-using NumericRangeSet = media_constraints::NumericRangeSet<T>;
+using NumericRangeSet = blink::media_constraints::NumericRangeSet<T>;
 
 namespace {
 
-using BoolSet = media_constraints::DiscreteSet<bool>;
-using DoubleRangeSet = media_constraints::NumericRangeSet<double>;
+using BoolSet = blink::media_constraints::DiscreteSet<bool>;
+using DoubleRangeSet = blink::media_constraints::NumericRangeSet<double>;
 using EchoCancellationTypeSet =
-    media_constraints::DiscreteSet<EchoCancellationType>;
-using IntRangeSet = media_constraints::NumericRangeSet<int>;
-using StringSet = media_constraints::DiscreteSet<std::string>;
+    blink::media_constraints::DiscreteSet<EchoCancellationType>;
+using IntRangeSet = blink::media_constraints::NumericRangeSet<int>;
+using StringSet = blink::media_constraints::DiscreteSet<std::string>;
 
 // The presence of a MediaStreamAudioSource object indicates whether the source
 // in question is currently in use, or not. This convenience enum helps
@@ -153,7 +155,7 @@
 
   const char* ApplyConstraintSet(const BooleanConstraint& constraint) {
     allowed_values_ = allowed_values_.Intersection(
-        media_constraints::BoolSetFromConstraint(constraint));
+        blink::media_constraints::BoolSetFromConstraint(constraint));
     return allowed_values_.IsEmpty() ? constraint.GetName() : nullptr;
   }
 
@@ -186,7 +188,7 @@
 
   const char* ApplyConstraintSet(const StringConstraint& constraint) {
     allowed_values_ = allowed_values_.Intersection(
-        media_constraints::StringSetFromConstraint(constraint));
+        blink::media_constraints::StringSetFromConstraint(constraint));
     return allowed_values_.IsEmpty() ? constraint.GetName() : nullptr;
   }
 
@@ -252,8 +254,8 @@
         return std::make_tuple(1.0, constraint.Ideal());
 
       T value = SelectClosestValueTo(constraint.Ideal());
-      double fitness =
-          1.0 - NumericConstraintFitnessDistance(value, constraint.Ideal());
+      double fitness = 1.0 - blink::NumericConstraintFitnessDistance(
+                                 value, constraint.Ideal());
       return std::make_tuple(fitness, value);
     }
 
@@ -332,11 +334,11 @@
 
   const char* ApplyConstraintSet(const ConstraintSet& constraint_set) {
     // Convert the constraints into discrete sets.
-    BoolSet ec_set = media_constraints::BoolSetFromConstraint(
+    BoolSet ec_set = blink::media_constraints::BoolSetFromConstraint(
         constraint_set.echo_cancellation);
-    BoolSet goog_ec_set = media_constraints::BoolSetFromConstraint(
+    BoolSet goog_ec_set = blink::media_constraints::BoolSetFromConstraint(
         constraint_set.goog_echo_cancellation);
-    StringSet ec_type_set = media_constraints::StringSetFromConstraint(
+    StringSet ec_type_set = blink::media_constraints::StringSetFromConstraint(
         constraint_set.echo_cancellation_type);
 
     // Apply echoCancellation constraint.
@@ -639,7 +641,7 @@
         IntRangeSet::FromValue(GetSampleSize()), /* sample_size_range */
         IntRangeSet::FromValue(1),               /* channels_range */
         IntRangeSet::FromValue(
-            kAudioProcessingSampleRate), /* sample_rate_range */
+            blink::kAudioProcessingSampleRate), /* sample_rate_range */
         source_info, is_device_capture, device_parameters);
   }
 
@@ -1227,8 +1229,7 @@
         // It is possible, however, that the HW echo canceller is enabled. In
         // such case the property for echo cancellation type should be updated
         // accordingly.
-        if (effects & media::AudioParameters::ECHO_CANCELLER ||
-            effects & media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER) {
+        if (effects & media::AudioParameters::ECHO_CANCELLER) {
           properties.echo_cancellation_type =
               EchoCancellationType::kEchoCancellationSystem;
         }
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio.h b/content/renderer/media/stream/media_stream_constraints_util_audio.h
index 1a089ec0..3c77819 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_audio.h
+++ b/content/renderer/media/stream/media_stream_constraints_util_audio.h
@@ -9,8 +9,8 @@
 #include <vector>
 
 #include "content/common/content_export.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 
 namespace blink {
 class MediaStreamAudioSource;
@@ -117,7 +117,7 @@
 //    whose default value is false only for desktop capture.
 //  * Audio processing. The remaining constraints are used to control audio
 //    processing. This is how audio-processing properties are set for device
-//    capture(see the content::AudioProcessingProperties struct) :
+//    capture(see the blink::AudioProcessingProperties struct) :
 //      - echo_cancellation_type: mapped from the experimental constraint with
 //        the same name. "System" is selected only if the device supports it.
 //        If constraint is not specified, "system" is selected if supported,
@@ -130,7 +130,7 @@
 //    specified, the default value is the same as the final value of the
 //    echo_cancellation constraint.  If the echo_cancellation constraint is
 //    not explicitly specified, the default value is implementation defined
-//    (see content::AudioProcessingProperties).
+//    (see blink::AudioProcessingProperties).
 //    For content capture the rules are the same, but all properties are false
 //    by default, regardless of the value of the echo_cancellation constraint.
 //    Note that it is important to distinguish between audio properties and
@@ -146,7 +146,7 @@
 //    their corresponding constraints.
 // TODO(guidou): Add support for other standard constraints such as sampleRate,
 // channelCount and groupId. https://crbug.com/731170
-AudioCaptureSettings CONTENT_EXPORT
+blink::AudioCaptureSettings CONTENT_EXPORT
 SelectSettingsAudioCapture(const AudioDeviceCaptureCapabilities& capabilities,
                            const blink::WebMediaConstraints& constraints,
                            bool should_disable_hardware_noise_suppression);
@@ -158,7 +158,7 @@
 // different from those of |source| because it is currently not possible to
 // reconfigure audio tracks or sources.
 // TODO(guidou): Allow reconfiguring audio tracks. https://crbug.com/796964
-AudioCaptureSettings CONTENT_EXPORT
+blink::AudioCaptureSettings CONTENT_EXPORT
 SelectSettingsAudioCapture(blink::MediaStreamAudioSource* source,
                            const blink::WebMediaConstraints& constraints);
 
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
index 3bfb113..07cecdce 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
+++ b/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
@@ -25,6 +25,8 @@
 
 namespace content {
 
+using blink::AudioCaptureSettings;
+using blink::AudioProcessingProperties;
 using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
 
 namespace {
@@ -111,7 +113,8 @@
           "8khz_sample_rate_device", "fake_group4",
           media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                                  media::CHANNEL_LAYOUT_STEREO,
-                                 AudioProcessing::kSampleRate8kHz, 1000));
+                                 blink::AudioProcessing::kSampleRate8kHz,
+                                 1000));
 
       default_device_ = &capabilities_[0];
       system_echo_canceller_device_ = &capabilities_[1];
@@ -186,11 +189,18 @@
   std::unique_ptr<LocalMediaStreamAudioSource> GetLocalMediaStreamAudioSource(
       bool enable_system_echo_canceller,
       bool disable_local_echo,
-      bool render_to_associated_sink) {
+      bool render_to_associated_sink,
+      bool enable_experimental_echo_canceller = false) {
     blink::MediaStreamDevice device;
     device.type = GetMediaStreamType();
+
+    int effects = 0;
     if (enable_system_echo_canceller)
-      device.input.set_effects(media::AudioParameters::ECHO_CANCELLER);
+      effects |= media::AudioParameters::ECHO_CANCELLER;
+    if (enable_experimental_echo_canceller)
+      effects |= media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER;
+    device.input.set_effects(effects);
+
     if (render_to_associated_sink)
       device.matched_output_device_id = std::string("some_device_id");
 
@@ -753,19 +763,19 @@
 
 TEST_P(MediaStreamConstraintsUtilAudioTest, SampleRate) {
   AudioCaptureSettings result;
-  int exact_sample_rate = AudioProcessing::kSampleRate8kHz;
-  int min_sample_rate = AudioProcessing::kSampleRate8kHz;
+  int exact_sample_rate = blink::AudioProcessing::kSampleRate8kHz;
+  int min_sample_rate = blink::AudioProcessing::kSampleRate8kHz;
   // |max_sample_rate| is different based on architecture, namely due to a
   // difference on Android.
   int max_sample_rate =
       std::max(static_cast<int>(media::AudioParameters::kAudioCDSampleRate),
-               kAudioProcessingSampleRate);
-  int ideal_sample_rate = AudioProcessing::kSampleRate8kHz;
+               blink::kAudioProcessingSampleRate);
+  int ideal_sample_rate = blink::AudioProcessing::kSampleRate8kHz;
   if (!IsDeviceCapture()) {
     exact_sample_rate = media::AudioParameters::kAudioCDSampleRate;
     min_sample_rate =
         std::min(static_cast<int>(media::AudioParameters::kAudioCDSampleRate),
-                 kAudioProcessingSampleRate);
+                 blink::kAudioProcessingSampleRate);
     ideal_sample_rate = media::AudioParameters::kAudioCDSampleRate;
   }
 
@@ -840,7 +850,7 @@
 
   if (IsDeviceCapture()) {
     constraint_factory_.basic().sample_rate.SetIdeal(
-        AudioProcessing::kSampleRate48kHz + 1000);
+        blink::AudioProcessing::kSampleRate48kHz + 1000);
     result = SelectSettings();
     EXPECT_TRUE(result.HasValue());
     EXPECT_EQ(result.device_id(), "default_device");
@@ -2110,6 +2120,21 @@
   }
 }
 
+TEST_P(MediaStreamConstraintsUtilAudioTest, ExperimetanlEcWithSource) {
+  std::unique_ptr<LocalMediaStreamAudioSource> source =
+      GetLocalMediaStreamAudioSource(
+          false /* enable_system_echo_canceller */,
+          false /* disable_local_echo */, false /* render_to_associated_sink */,
+          true /* enable_experimental_echo_canceller */);
+
+  constraint_factory_.Reset();
+  constraint_factory_.basic().echo_cancellation.SetExact(false);
+
+  auto result = SelectSettingsAudioCapture(
+      source.get(), constraint_factory_.CreateWebMediaConstraints());
+  EXPECT_TRUE(result.HasValue());
+}
+
 INSTANTIATE_TEST_SUITE_P(,
                          MediaStreamConstraintsUtilAudioTest,
                          testing::Values("",
diff --git a/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc
index 81d3bd9f..6541e7f2 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc
+++ b/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h"
 
 #include <cmath>
 #include <string>
@@ -15,8 +15,9 @@
 namespace content {
 namespace media_constraints {
 
+using blink::media_constraints::ResolutionSet;
 using Point = ResolutionSet::Point;
-using BoolSet = DiscreteSet<bool>;
+using BoolSet = blink::media_constraints::DiscreteSet<bool>;
 
 namespace {
 
@@ -1152,7 +1153,7 @@
 }
 
 TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetDouble) {
-  using DoubleRangeSet = NumericRangeSet<double>;
+  using DoubleRangeSet = blink::media_constraints::NumericRangeSet<double>;
   // Open set.
   DoubleRangeSet set;
   EXPECT_FALSE(set.Min().has_value());
@@ -1221,7 +1222,9 @@
   // Exact value translates in a range with a single value.
   blink::LongConstraint constraint = blink::LongConstraint("aConstraint");
   constraint.SetExact(10);
-  NumericRangeSet<int> range = NumericRangeSet<int>::FromConstraint(constraint);
+  blink::media_constraints::NumericRangeSet<int> range =
+      blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+          constraint);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_TRUE(range.Min());
   EXPECT_EQ(*range.Min(), 10);
@@ -1233,7 +1236,8 @@
   constraint = blink::LongConstraint("aConstraint");
   constraint.SetMin(0);
   constraint.SetMax(100);
-  range = NumericRangeSet<int>::FromConstraint(constraint);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_TRUE(range.Min());
   EXPECT_EQ(*range.Min(), 0);
@@ -1244,7 +1248,8 @@
   // set in both cases.
   constraint = blink::LongConstraint("aConstraint");
   constraint.SetMin(0);
-  range = NumericRangeSet<int>::FromConstraint(constraint);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_TRUE(range.Min());
   EXPECT_EQ(*range.Min(), 0);
@@ -1252,7 +1257,8 @@
 
   constraint = blink::LongConstraint("aConstraint");
   constraint.SetMax(100);
-  range = NumericRangeSet<int>::FromConstraint(constraint);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_TRUE(range.Max());
   EXPECT_EQ(*range.Max(), 100);
@@ -1260,7 +1266,8 @@
 
   // A constraint with no values specified maps to an unbounded range.
   constraint = blink::LongConstraint("aConstraint");
-  range = NumericRangeSet<int>::FromConstraint(constraint);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_FALSE(range.Min());
   EXPECT_FALSE(range.Max());
@@ -1273,8 +1280,9 @@
   // Exact value translates in a range with a single value.
   blink::LongConstraint constraint = blink::LongConstraint("aConstraint");
   constraint.SetExact(10);
-  NumericRangeSet<int> range = NumericRangeSet<int>::FromConstraint(
-      constraint, lower_bound, upper_bound);
+  blink::media_constraints::NumericRangeSet<int> range =
+      blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+          constraint, lower_bound, upper_bound);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_TRUE(range.Min());
   EXPECT_EQ(*range.Min(), 10);
@@ -1287,14 +1295,15 @@
   constraint = blink::LongConstraint("aConstraint");
   constraint.SetMin(0);
   constraint.SetMax(100);
-  range = NumericRangeSet<int>::FromConstraint(constraint, 0, 100);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint, 0, 100);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_TRUE(range.Min());
   EXPECT_EQ(*range.Min(), 0);
   EXPECT_TRUE(range.Max());
   EXPECT_EQ(*range.Max(), 100);
-  range = NumericRangeSet<int>::FromConstraint(constraint, lower_bound,
-                                               upper_bound);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint, lower_bound, upper_bound);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_FALSE(range.Min());
   EXPECT_FALSE(range.Max());
@@ -1304,16 +1313,16 @@
   // allow for it.
   constraint = blink::LongConstraint("aConstraint");
   constraint.SetMin(0);
-  range = NumericRangeSet<int>::FromConstraint(constraint, lower_bound,
-                                               upper_bound);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint, lower_bound, upper_bound);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_FALSE(range.Min());
   EXPECT_FALSE(range.Max());
 
   constraint = blink::LongConstraint("aConstraint");
   constraint.SetMax(100);
-  range = NumericRangeSet<int>::FromConstraint(constraint, lower_bound,
-                                               upper_bound);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint, lower_bound, upper_bound);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_FALSE(range.Min());
   EXPECT_FALSE(range.Max());
@@ -1321,8 +1330,8 @@
   // A constraint with no values specified maps to an unbounded range
   // independently of upper and lower bounds.
   constraint = blink::LongConstraint("aConstraint");
-  range = NumericRangeSet<int>::FromConstraint(constraint, lower_bound,
-                                               upper_bound);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint, lower_bound, upper_bound);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_FALSE(range.Min());
   EXPECT_FALSE(range.Max());
@@ -1332,22 +1341,22 @@
   constraint = blink::LongConstraint("aConstraint");
   constraint.SetMin(-5);
   constraint.SetMax(0);
-  range = NumericRangeSet<int>::FromConstraint(constraint, lower_bound,
-                                               upper_bound);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint, lower_bound, upper_bound);
   EXPECT_TRUE(range.IsEmpty());
 
   constraint = blink::LongConstraint("aConstraint");
   constraint.SetMin(105);
   constraint.SetMax(110);
-  range = NumericRangeSet<int>::FromConstraint(constraint, lower_bound,
-                                               upper_bound);
+  range = blink::media_constraints::NumericRangeSet<int>::FromConstraint(
+      constraint, lower_bound, upper_bound);
   EXPECT_TRUE(range.IsEmpty());
 }
 
 TEST_F(MediaStreamConstraintsUtilSetsTest, NumericRangeSetFromValue) {
   // Getting a range from a single value, will return a range with a single
   // value set as both max and min.
-  auto range = NumericRangeSet<int>::FromValue(0);
+  auto range = blink::media_constraints::NumericRangeSet<int>::FromValue(0);
   EXPECT_FALSE(range.IsEmpty());
   EXPECT_TRUE(range.Min());
   EXPECT_EQ(*range.Min(), 0);
@@ -1357,7 +1366,7 @@
 
 TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetString) {
   // Universal set.
-  using StringSet = DiscreteSet<std::string>;
+  using StringSet = blink::media_constraints::DiscreteSet<std::string>;
   StringSet set = StringSet::UniversalSet();
   EXPECT_TRUE(set.Contains("arbitrary"));
   EXPECT_TRUE(set.Contains("strings"));
@@ -1506,27 +1515,31 @@
 TEST_F(MediaStreamConstraintsUtilSetsTest, RescaleSetFromConstraints) {
   factory_.Reset();
   factory_.CreateWebMediaConstraints();
-  BoolSet set = RescaleSetFromConstraint(factory_.basic().resize_mode);
+  BoolSet set = blink::media_constraints::RescaleSetFromConstraint(
+      factory_.basic().resize_mode);
   EXPECT_TRUE(set.is_universal());
   EXPECT_FALSE(set.HasExplicitElements());
 
   // Invalid exact value.
   factory_.basic().resize_mode.SetExact(
       {blink::WebString::FromASCII("invalid")});
-  set = RescaleSetFromConstraint(factory_.basic().resize_mode);
+  set = blink::media_constraints::RescaleSetFromConstraint(
+      factory_.basic().resize_mode);
   EXPECT_TRUE(set.IsEmpty());
 
   // No rescaling
   factory_.basic().resize_mode.SetExact(
       blink::WebString::FromASCII(blink::WebMediaStreamTrack::kResizeModeNone));
-  set = RescaleSetFromConstraint(factory_.basic().resize_mode);
+  set = blink::media_constraints::RescaleSetFromConstraint(
+      factory_.basic().resize_mode);
   EXPECT_TRUE(set.Contains(false));
   EXPECT_FALSE(set.Contains(true));
 
   // Rescaling
   factory_.basic().resize_mode.SetExact(blink::WebString::FromASCII(
       blink::WebMediaStreamTrack::kResizeModeRescale));
-  set = RescaleSetFromConstraint(factory_.basic().resize_mode);
+  set = blink::media_constraints::RescaleSetFromConstraint(
+      factory_.basic().resize_mode);
   EXPECT_TRUE(set.Contains(true));
   EXPECT_FALSE(set.Contains(false));
 
@@ -1537,7 +1550,8 @@
       blink::WebString::FromASCII(blink::WebMediaStreamTrack::kResizeModeNone)};
   factory_.basic().resize_mode.SetExact(blink::WebVector<blink::WebString>(
       rescale_modes, base::size(rescale_modes)));
-  set = RescaleSetFromConstraint(factory_.basic().resize_mode);
+  set = blink::media_constraints::RescaleSetFromConstraint(
+      factory_.basic().resize_mode);
   EXPECT_TRUE(set.Contains(true));
   EXPECT_TRUE(set.Contains(false));
 
@@ -1545,7 +1559,8 @@
   rescale_modes[0] = "invalid";
   factory_.basic().resize_mode.SetExact(blink::WebVector<blink::WebString>(
       rescale_modes, base::size(rescale_modes)));
-  set = RescaleSetFromConstraint(factory_.basic().resize_mode);
+  set = blink::media_constraints::RescaleSetFromConstraint(
+      factory_.basic().resize_mode);
   EXPECT_FALSE(set.Contains(true));
   EXPECT_TRUE(set.Contains(false));
 }
diff --git a/content/renderer/media/stream/media_stream_constraints_util_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_unittest.cc
index a7a53cf2..d5c42b71 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_unittest.cc
+++ b/content/renderer/media/stream/media_stream_constraints_util_unittest.cc
@@ -4,11 +4,11 @@
 
 #include <string>
 
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
 #include "content/renderer/media/stream/mock_constraint_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h"
 
 namespace content {
 
@@ -20,10 +20,10 @@
     static_cast<double>(kSourceWidth) / static_cast<double>(kSourceHeight);
 constexpr double kSourceFrameRate = 100.0;
 
-VideoTrackAdapterSettings SelectTrackSettings(
+blink::VideoTrackAdapterSettings SelectTrackSettings(
     const blink::WebMediaTrackConstraintSet& basic_constraint_set,
-    const media_constraints::ResolutionSet& resolution_set,
-    const media_constraints::NumericRangeSet<double>& frame_rate_set,
+    const blink::media_constraints::ResolutionSet& resolution_set,
+    const blink::media_constraints::NumericRangeSet<double>& frame_rate_set,
     bool enable_rescale = true) {
   media::VideoCaptureFormat source_format(
       gfx::Size(kSourceWidth, kSourceHeight), kSourceFrameRate,
@@ -37,8 +37,8 @@
 
 class MediaStreamConstraintsUtilTest : public testing::Test {
  protected:
-  using DoubleRangeSet = media_constraints::NumericRangeSet<double>;
-  using ResolutionSet = media_constraints::ResolutionSet;
+  using DoubleRangeSet = blink::media_constraints::NumericRangeSet<double>;
+  using ResolutionSet = blink::media_constraints::ResolutionSet;
 };
 
 TEST_F(MediaStreamConstraintsUtilTest, BooleanConstraints) {
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_content.cc b/content/renderer/media/stream/media_stream_constraints_util_video_content.cc
index ec9979b..16cb6e4 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_video_content.cc
+++ b/content/renderer/media/stream/media_stream_constraints_util_video_content.cc
@@ -9,12 +9,12 @@
 #include <utility>
 #include <vector>
 
-#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
 #include "media/base/limits.h"
 #include "third_party/blink/public/common/mediastream/media_stream_controls.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
 namespace content {
 
@@ -35,15 +35,16 @@
 
 const double kMaxScreenCastFrameRate = 120.0;
 const double kDefaultScreenCastFrameRate =
-    MediaStreamVideoSource::kDefaultFrameRate;
+    blink::MediaStreamVideoSource::kDefaultFrameRate;
 
 namespace {
 
-using ResolutionSet = media_constraints::ResolutionSet;
+using blink::VideoCaptureSettings;
+using ResolutionSet = blink::media_constraints::ResolutionSet;
 using Point = ResolutionSet::Point;
-using StringSet = media_constraints::DiscreteSet<std::string>;
-using BoolSet = media_constraints::DiscreteSet<bool>;
-using DoubleRangeSet = media_constraints::NumericRangeSet<double>;
+using StringSet = blink::media_constraints::DiscreteSet<std::string>;
+using BoolSet = blink::media_constraints::DiscreteSet<bool>;
+using DoubleRangeSet = blink::media_constraints::NumericRangeSet<double>;
 
 constexpr double kMinScreenCastAspectRatio =
     static_cast<double>(kMinScreenCastDimension) /
@@ -70,11 +71,11 @@
             DoubleRangeSet::FromConstraint(constraint_set.frame_rate,
                                            0.0,
                                            kMaxScreenCastFrameRate)),
-        device_id_set_(media_constraints::StringSetFromConstraint(
+        device_id_set_(blink::media_constraints::StringSetFromConstraint(
             constraint_set.device_id)),
-        noise_reduction_set_(media_constraints::BoolSetFromConstraint(
+        noise_reduction_set_(blink::media_constraints::BoolSetFromConstraint(
             constraint_set.goog_noise_reduction)),
-        rescale_set_(media_constraints::RescaleSetFromConstraint(
+        rescale_set_(blink::media_constraints::RescaleSetFromConstraint(
             constraint_set.resize_mode)) {}
 
   VideoContentCaptureCandidates(VideoContentCaptureCandidates&& other) =
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_content.h b/content/renderer/media/stream/media_stream_constraints_util_video_content.h
index 9ca414f..7c8b309 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_video_content.h
+++ b/content/renderer/media/stream/media_stream_constraints_util_video_content.h
@@ -8,8 +8,8 @@
 #include <string>
 
 #include "content/common/content_export.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 
 namespace blink {
 class WebMediaConstraints;
@@ -27,7 +27,7 @@
 
 // This function performs source, source-settings and track-settings selection
 // for content video capture based on the given |constraints|.
-VideoCaptureSettings CONTENT_EXPORT
+blink::VideoCaptureSettings CONTENT_EXPORT
 SelectSettingsVideoContentCapture(const blink::WebMediaConstraints& constraints,
                                   blink::MediaStreamType stream_type,
                                   int screen_width,
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc
index 1c21c971..8184dbb 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc
+++ b/content/renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc
@@ -21,7 +21,7 @@
 const double kDefaultScreenCastAspectRatio =
     static_cast<double>(kDefaultScreenCastWidth) / kDefaultScreenCastHeight;
 
-void CheckNonResolutionDefaults(const VideoCaptureSettings& result) {
+void CheckNonResolutionDefaults(const blink::VideoCaptureSettings& result) {
   EXPECT_EQ(kDefaultScreenCastFrameRate, result.FrameRate());
   EXPECT_EQ(base::Optional<double>(), result.min_frame_rate());
   EXPECT_EQ(base::Optional<double>(), result.max_frame_rate());
@@ -30,14 +30,15 @@
   EXPECT_FALSE(result.min_frame_rate().has_value());
 }
 
-void CheckNonFrameRateDefaults(const VideoCaptureSettings& result) {
+void CheckNonFrameRateDefaults(const blink::VideoCaptureSettings& result) {
   EXPECT_EQ(kDefaultScreenCastHeight, result.Height());
   EXPECT_EQ(kDefaultScreenCastWidth, result.Width());
   EXPECT_EQ(base::Optional<bool>(), result.noise_reduction());
   EXPECT_EQ(std::string(), result.device_id());
 }
 
-void CheckTrackAdapterSettingsEqualsFormat(const VideoCaptureSettings& result) {
+void CheckTrackAdapterSettingsEqualsFormat(
+    const blink::VideoCaptureSettings& result) {
   // For content capture, resolution and frame rate should always be the same
   // for source and track.
   EXPECT_TRUE(result.track_adapter_settings().target_size().has_value());
@@ -47,7 +48,7 @@
 }
 
 void CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(
-    const VideoCaptureSettings& result) {
+    const blink::VideoCaptureSettings& result) {
   EXPECT_EQ(
       static_cast<double>(kMinScreenCastDimension) / kMaxScreenCastDimension,
       result.track_adapter_settings().min_aspect_ratio());
@@ -61,7 +62,7 @@
 
 class MediaStreamConstraintsUtilVideoContentTest : public testing::Test {
  protected:
-  VideoCaptureSettings SelectSettings(
+  blink::VideoCaptureSettings SelectSettings(
       blink::MediaStreamType stream_type =
           blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE) {
     blink::WebMediaConstraints constraints =
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
index cd5ac4e..f91d916f 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
+++ b/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
@@ -2,21 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/stream/media_stream_constraints_util_video_device.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h"
 
 #include <algorithm>
 #include <utility>
 
 #include "base/optional.h"
 #include "base/stl_util.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
 #include "content/renderer/media/stream/mock_constraint_factory.h"
 #include "media/base/limits.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
 namespace content {
 
+using blink::MediaStreamVideoSource;
+
 namespace {
 
 const char kDeviceID1[] = "fake_device_1";
@@ -32,7 +34,7 @@
 const char kGroupID5[] = "fake_group_5";
 
 void CheckTrackAdapterSettingsEqualsResolution(
-    const VideoCaptureSettings& settings) {
+    const blink::VideoCaptureSettings& settings) {
   EXPECT_FALSE(settings.track_adapter_settings().target_size());
   EXPECT_EQ(1.0 / settings.Format().frame_size.height(),
             settings.track_adapter_settings().min_aspect_ratio());
@@ -41,7 +43,7 @@
 }
 
 void CheckTrackAdapterSettingsEqualsFrameRate(
-    const VideoCaptureSettings& settings,
+    const blink::VideoCaptureSettings& settings,
     double value = 0.0) {
   if (value >= settings.FrameRate())
     value = 0.0;
@@ -49,7 +51,7 @@
 }
 
 void CheckTrackAdapterSettingsEqualsFormat(
-    const VideoCaptureSettings& settings) {
+    const blink::VideoCaptureSettings& settings) {
   CheckTrackAdapterSettingsEqualsResolution(settings);
   CheckTrackAdapterSettingsEqualsFrameRate(settings);
 }
@@ -59,8 +61,8 @@
          static_cast<double>(format.frame_size.height());
 }
 
-VideoCaptureSettings SelectSettingsVideoDeviceCapture(
-    const VideoDeviceCaptureCapabilities& capabilities,
+blink::VideoCaptureSettings SelectSettingsVideoDeviceCapture(
+    const blink::VideoDeviceCaptureCapabilities& capabilities,
     const blink::WebMediaConstraints& constraints) {
   return SelectSettingsVideoDeviceCapture(
       capabilities, constraints, MediaStreamVideoSource::kDefaultWidth,
@@ -74,7 +76,7 @@
  public:
   void SetUp() override {
     // Default device. It is default because it is the first in the enumeration.
-    VideoInputDeviceCapabilities device;
+    blink::VideoInputDeviceCapabilities device;
     device.device_id = kDeviceID1;
     device.group_id = kGroupID1;
     device.facing_mode = media::MEDIA_VIDEO_FACING_NONE;
@@ -179,17 +181,17 @@
   }
 
  protected:
-  VideoCaptureSettings SelectSettings() {
+  blink::VideoCaptureSettings SelectSettings() {
     blink::WebMediaConstraints constraints =
         constraint_factory_.CreateWebMediaConstraints();
     return SelectSettingsVideoDeviceCapture(capabilities_, constraints);
   }
 
-  VideoDeviceCaptureCapabilities capabilities_;
-  const VideoInputDeviceCapabilities* default_device_;
-  const VideoInputDeviceCapabilities* low_res_device_;
-  const VideoInputDeviceCapabilities* high_res_device_;
-  const VideoInputDeviceCapabilities* invalid_frame_rate_device_;
+  blink::VideoDeviceCaptureCapabilities capabilities_;
+  const blink::VideoInputDeviceCapabilities* default_device_;
+  const blink::VideoInputDeviceCapabilities* low_res_device_;
+  const blink::VideoInputDeviceCapabilities* high_res_device_;
+  const blink::VideoInputDeviceCapabilities* invalid_frame_rate_device_;
   // Closest formats to the default settings.
   const media::VideoCaptureFormat* default_closest_format_;
   const media::VideoCaptureFormat* low_res_closest_format_;
@@ -389,8 +391,8 @@
   // Simulate a system that does not support noise reduction.
   // Manually adding device capabilities because VideoDeviceCaptureCapabilities
   // is move only.
-  VideoDeviceCaptureCapabilities capabilities;
-  VideoInputDeviceCapabilities device;
+  blink::VideoDeviceCaptureCapabilities capabilities;
+  blink::VideoInputDeviceCapabilities device;
   device.device_id = kDeviceID1;
   device.facing_mode = media::MEDIA_VIDEO_FACING_NONE;
   device.formats = {
@@ -2513,7 +2515,7 @@
 // when there are no candidates to choose from.
 TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, NoDevicesNoConstraints) {
   constraint_factory_.Reset();
-  VideoDeviceCaptureCapabilities capabilities;
+  blink::VideoDeviceCaptureCapabilities capabilities;
   auto result = SelectSettingsVideoDeviceCapture(
       capabilities, constraint_factory_.CreateWebMediaConstraints());
   EXPECT_FALSE(result.HasValue());
@@ -2523,7 +2525,7 @@
 TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, NoDevicesWithConstraints) {
   constraint_factory_.Reset();
   constraint_factory_.basic().height.SetExact(100);
-  VideoDeviceCaptureCapabilities capabilities;
+  blink::VideoDeviceCaptureCapabilities capabilities;
   auto result = SelectSettingsVideoDeviceCapture(
       capabilities, constraint_factory_.CreateWebMediaConstraints());
   EXPECT_FALSE(result.HasValue());
diff --git a/content/renderer/media/stream/media_stream_renderer_factory_impl.cc b/content/renderer/media/stream/media_stream_renderer_factory_impl.cc
index b934384..a6f5708 100644
--- a/content/renderer/media/stream/media_stream_renderer_factory_impl.cc
+++ b/content/renderer/media/stream/media_stream_renderer_factory_impl.cc
@@ -8,7 +8,6 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "content/renderer/media/stream/media_stream_video_renderer_sink.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/track_audio_renderer.h"
 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/peer_connection_remote_audio_source.h"
@@ -17,6 +16,7 @@
 #include "content/renderer/render_thread_impl.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
 #include "third_party/blink/public/platform/web_media_stream.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
 
 namespace content {
@@ -65,7 +65,7 @@
   blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
       web_stream.VideoTracks();
   if (video_tracks.empty() ||
-      !MediaStreamVideoTrack::GetTrack(video_tracks[0])) {
+      !blink::MediaStreamVideoTrack::GetTrack(video_tracks[0])) {
     return nullptr;
   }
 
diff --git a/content/renderer/media/stream/media_stream_video_capturer_source.cc b/content/renderer/media/stream/media_stream_video_capturer_source.cc
index 50c9445a..8aebb3d 100644
--- a/content/renderer/media/stream/media_stream_video_capturer_source.cc
+++ b/content/renderer/media/stream/media_stream_video_capturer_source.cc
@@ -8,9 +8,9 @@
 
 #include "base/bind.h"
 #include "content/public/renderer/render_frame.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "media/capture/video_capturer_source.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 
 namespace content {
diff --git a/content/renderer/media/stream/media_stream_video_capturer_source.h b/content/renderer/media/stream/media_stream_video_capturer_source.h
index d0b63cb..a73d13b 100644
--- a/content/renderer/media/stream/media_stream_video_capturer_source.h
+++ b/content/renderer/media/stream/media_stream_video_capturer_source.h
@@ -12,10 +12,11 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
+#include "content/common/content_export.h"
 #include "media/capture/video_capture_types.h"
 #include "third_party/blink/public/common/media/video_capture.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
 namespace media {
 class VideoCapturerSource;
@@ -30,7 +31,7 @@
 // Render thread. Objects can be constructed either by indicating a |device| to
 // look for, or by plugging in a |source| constructed elsewhere.
 class CONTENT_EXPORT MediaStreamVideoCapturerSource
-    : public MediaStreamVideoSource {
+    : public blink::MediaStreamVideoSource {
  public:
   using DeviceCapturerFactoryCallback =
       base::RepeatingCallback<std::unique_ptr<media::VideoCapturerSource>(
@@ -58,7 +59,7 @@
                            CaptureTimeAndMetadataPlumbing);
   FRIEND_TEST_ALL_PREFIXES(MediaStreamVideoCapturerSourceTest, ChangeSource);
 
-  // MediaStreamVideoSource overrides.
+  // blink::MediaStreamVideoSource overrides.
   void RequestRefreshFrame() override;
   void OnFrameDropped(media::VideoCaptureFrameDropReason reason) override;
   void OnLog(const std::string& message) override;
diff --git a/content/renderer/media/stream/media_stream_video_capturer_source_unittest.cc b/content/renderer/media/stream/media_stream_video_capturer_source_unittest.cc
index f9922ed..7cd07b8 100644
--- a/content/renderer/media/stream/media_stream_video_capturer_source_unittest.cc
+++ b/content/renderer/media/stream/media_stream_video_capturer_source_unittest.cc
@@ -11,14 +11,14 @@
 #include "base/run_loop.h"
 #include "base/test/scoped_task_environment.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_mojo_media_stream_dispatcher_host.h"
-#include "content/renderer/media/stream/video_track_adapter.h"
 #include "content/renderer/media_stream_video_sink.h"
 #include "media/base/bind_to_current_loop.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 #include "third_party/blink/public/web/web_heap.h"
 
 using ::testing::_;
@@ -135,13 +135,13 @@
   }
 
   blink::WebMediaStreamTrack StartSource(
-      const VideoTrackAdapterSettings& adapter_settings,
+      const blink::VideoTrackAdapterSettings& adapter_settings,
       const base::Optional<bool>& noise_reduction,
       bool is_screencast,
       double min_frame_rate) {
     bool enabled = true;
     // CreateVideoTrack will trigger OnConstraintsApplied.
-    return MediaStreamVideoTrack::CreateVideoTrack(
+    return blink::MediaStreamVideoTrack::CreateVideoTrack(
         source_, adapter_settings, noise_reduction, is_screencast,
         min_frame_rate,
         base::Bind(&MediaStreamVideoCapturerSourceTest::OnConstraintsApplied,
@@ -196,8 +196,8 @@
 TEST_F(MediaStreamVideoCapturerSourceTest, StartAndStop) {
   InSequence s;
   EXPECT_CALL(mock_delegate(), MockStartCapture(_, _, _));
-  blink::WebMediaStreamTrack track =
-      StartSource(VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
+  blink::WebMediaStreamTrack track = StartSource(
+      blink::VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
             webkit_source_.GetReadyState());
@@ -233,8 +233,8 @@
                                testing::SaveArg<2>(&running_cb)));
   EXPECT_CALL(mock_delegate(), RequestRefreshFrame());
   EXPECT_CALL(mock_delegate(), MockStopCapture());
-  blink::WebMediaStreamTrack track =
-      StartSource(VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
+  blink::WebMediaStreamTrack track = StartSource(
+      blink::VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
   running_cb.Run(true);
 
   base::RunLoop run_loop;
@@ -264,8 +264,8 @@
 TEST_F(MediaStreamVideoCapturerSourceTest, Restart) {
   InSequence s;
   EXPECT_CALL(mock_delegate(), MockStartCapture(_, _, _));
-  blink::WebMediaStreamTrack track =
-      StartSource(VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
+  blink::WebMediaStreamTrack track = StartSource(
+      blink::VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
@@ -275,8 +275,9 @@
   EXPECT_CALL(mock_delegate(), MockStopCapture());
   EXPECT_TRUE(source_->IsRunning());
   source_->StopForRestart(
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::IS_STOPPED);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::IS_STOPPED);
       }));
   base::RunLoop().RunUntilIdle();
   // When the source has stopped for restart, the source is not considered
@@ -293,8 +294,9 @@
   // the same.
   EXPECT_FALSE(source_->IsRunning());
   source_->StopForRestart(
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::INVALID_STATE);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::INVALID_STATE);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(webkit_source_.GetReadyState(),
@@ -307,8 +309,9 @@
   EXPECT_FALSE(source_->IsRunning());
   source_->Restart(
       media::VideoCaptureFormat(),
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::IS_RUNNING);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::IS_RUNNING);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(webkit_source_.GetReadyState(),
@@ -321,8 +324,9 @@
   EXPECT_TRUE(source_->IsRunning());
   source_->Restart(
       media::VideoCaptureFormat(),
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::INVALID_STATE);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::INVALID_STATE);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(webkit_source_.GetReadyState(),
@@ -345,8 +349,8 @@
 TEST_F(MediaStreamVideoCapturerSourceTest, StartStopAndNotify) {
   InSequence s;
   EXPECT_CALL(mock_delegate(), MockStartCapture(_, _, _));
-  blink::WebMediaStreamTrack web_track =
-      StartSource(VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
+  blink::WebMediaStreamTrack web_track = StartSource(
+      blink::VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
             webkit_source_.GetReadyState());
@@ -376,8 +380,8 @@
 TEST_F(MediaStreamVideoCapturerSourceTest, ChangeSource) {
   InSequence s;
   EXPECT_CALL(mock_delegate(), MockStartCapture(_, _, _));
-  blink::WebMediaStreamTrack track =
-      StartSource(VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
+  blink::WebMediaStreamTrack track = StartSource(
+      blink::VideoTrackAdapterSettings(), base::nullopt, false, 0.0);
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
             webkit_source_.GetReadyState());
diff --git a/content/renderer/media/stream/media_stream_video_renderer_sink_unittest.cc b/content/renderer/media/stream/media_stream_video_renderer_sink_unittest.cc
index 8f2586a..dd552e8 100644
--- a/content/renderer/media/stream/media_stream_video_renderer_sink_unittest.cc
+++ b/content/renderer/media/stream/media_stream_video_renderer_sink_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_task_environment.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_media_stream_registry.h"
 #include "content/renderer/media/stream/mock_media_stream_video_source.h"
 #include "media/base/video_frame.h"
@@ -21,6 +20,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_heap.h"
 
 using ::testing::_;
@@ -45,7 +45,7 @@
                              blink::WebString::FromASCII("dummy_source_name"),
                              false /* remote */);
     blink_source_.SetPlatformSource(base::WrapUnique(mock_source_));
-    blink_track_ = MediaStreamVideoTrack::CreateVideoTrack(
+    blink_track_ = blink::MediaStreamVideoTrack::CreateVideoTrack(
         mock_source_,
         blink::WebPlatformMediaStreamSource::ConstraintsCallback(), true);
     mock_source_->StartMockedSource();
diff --git a/content/renderer/media/stream/media_stream_video_source_unittest.cc b/content/renderer/media/stream/media_stream_video_source_unittest.cc
index 44b7470..21baf254 100644
--- a/content/renderer/media/stream/media_stream_video_source_unittest.cc
+++ b/content/renderer/media/stream/media_stream_video_source_unittest.cc
@@ -13,15 +13,15 @@
 #include "base/test/scoped_task_environment.h"
 #include "build/build_config.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_constraint_factory.h"
 #include "content/renderer/media/stream/mock_media_stream_video_sink.h"
 #include "content/renderer/media/stream/mock_media_stream_video_source.h"
-#include "content/renderer/media/stream/video_track_adapter.h"
 #include "media/base/limits.h"
 #include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 #include "third_party/blink/public/web/web_heap.h"
 
 using ::testing::_;
@@ -74,12 +74,12 @@
   MOCK_METHOD0(MockNotification, void());
 
  protected:
-  MediaStreamVideoSource* source() { return mock_source_; }
+  blink::MediaStreamVideoSource* source() { return mock_source_; }
 
   // Create a track that's associated with |web_source_|.
   blink::WebMediaStreamTrack CreateTrack(const std::string& id) {
     bool enabled = true;
-    return MediaStreamVideoTrack::CreateVideoTrack(
+    return blink::MediaStreamVideoTrack::CreateVideoTrack(
         mock_source_,
         base::Bind(&MediaStreamVideoSourceTest::OnConstraintsApplied,
                    base::Unretained(this)),
@@ -88,12 +88,12 @@
 
   blink::WebMediaStreamTrack CreateTrack(
       const std::string& id,
-      const VideoTrackAdapterSettings& adapter_settings,
+      const blink::VideoTrackAdapterSettings& adapter_settings,
       const base::Optional<bool>& noise_reduction,
       bool is_screencast,
       double min_frame_rate) {
     bool enabled = true;
-    return MediaStreamVideoTrack::CreateVideoTrack(
+    return blink::MediaStreamVideoTrack::CreateVideoTrack(
         mock_source_, adapter_settings, noise_reduction, is_screencast,
         min_frame_rate,
         base::Bind(&MediaStreamVideoSourceTest::OnConstraintsApplied,
@@ -107,7 +107,8 @@
       double frame_rate,
       bool detect_rotation = false) {
     blink::WebMediaStreamTrack track = CreateTrack(
-        "123", VideoTrackAdapterSettings(gfx::Size(width, height), frame_rate),
+        "123",
+        blink::VideoTrackAdapterSettings(gfx::Size(width, height), frame_rate),
         base::Optional<bool>(), false, 0.0);
 
     EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
@@ -196,15 +197,16 @@
                                           int expected_height1,
                                           int expected_width2,
                                           int expected_height2) {
-    blink::WebMediaStreamTrack track1 =
-        CreateTrackAndStartSource(expected_width1, expected_height1,
-                                  MediaStreamVideoSource::kDefaultFrameRate);
+    blink::WebMediaStreamTrack track1 = CreateTrackAndStartSource(
+        expected_width1, expected_height1,
+        blink::MediaStreamVideoSource::kDefaultFrameRate);
 
-    blink::WebMediaStreamTrack track2 = CreateTrack(
-        "dummy",
-        VideoTrackAdapterSettings(gfx::Size(expected_width2, expected_height2),
-                                  MediaStreamVideoSource::kDefaultFrameRate),
-        base::Optional<bool>(), false, 0.0);
+    blink::WebMediaStreamTrack track2 =
+        CreateTrack("dummy",
+                    blink::VideoTrackAdapterSettings(
+                        gfx::Size(expected_width2, expected_height2),
+                        blink::MediaStreamVideoSource::kDefaultFrameRate),
+                    base::Optional<bool>(), false, 0.0);
 
     MockMediaStreamVideoSink sink1;
     sink1.ConnectToTrack(track1);
@@ -452,8 +454,8 @@
   EXPECT_EQ(track.Source().GetReadyState(),
             blink::WebMediaStreamSource::kReadyStateLive);
 
-  MediaStreamVideoTrack* native_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* native_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   blink::WebMediaStreamTrack::Settings settings;
   native_track->GetSettings(settings);
   EXPECT_EQ(settings.width, 640);
@@ -461,8 +463,8 @@
   EXPECT_EQ(settings.frame_rate, media::limits::kMaxFramesPerSecond - 2);
   EXPECT_EQ(settings.aspect_ratio, 640.0 / 480.0);
 
-  source()->ReconfigureTrack(
-      native_track, VideoTrackAdapterSettings(gfx::Size(630, 470), 30.0));
+  source()->ReconfigureTrack(native_track, blink::VideoTrackAdapterSettings(
+                                               gfx::Size(630, 470), 30.0));
   native_track->GetSettings(settings);
   EXPECT_EQ(settings.width, 630);
   EXPECT_EQ(settings.height, 470);
@@ -483,8 +485,8 @@
   EXPECT_EQ(track.Source().GetReadyState(),
             blink::WebMediaStreamSource::kReadyStateLive);
 
-  MediaStreamVideoTrack* native_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* native_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   blink::WebMediaStreamTrack::Settings settings;
   native_track->GetSettings(settings);
   EXPECT_EQ(settings.width, 640);
@@ -498,8 +500,8 @@
   EXPECT_EQ(track.Source().GetReadyState(),
             blink::WebMediaStreamSource::kReadyStateEnded);
 
-  source()->ReconfigureTrack(
-      native_track, VideoTrackAdapterSettings(gfx::Size(630, 470), 30.0));
+  source()->ReconfigureTrack(native_track, blink::VideoTrackAdapterSettings(
+                                               gfx::Size(630, 470), 30.0));
   blink::WebMediaStreamTrack::Settings stopped_settings;
   native_track->GetSettings(stopped_settings);
   EXPECT_EQ(stopped_settings.width, -1);
@@ -518,8 +520,9 @@
 
   // The source does not support Restart/StopForRestart.
   mock_source()->StopForRestart(
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::IS_RUNNING);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::IS_RUNNING);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -529,8 +532,9 @@
   // successful StopForRestart().
   mock_source()->Restart(
       media::VideoCaptureFormat(),
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::INVALID_STATE);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::INVALID_STATE);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -540,8 +544,9 @@
   // Verify that StopForRestart() fails with INVALID_STATE when called when the
   // source is not running.
   mock_source()->StopForRestart(
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::INVALID_STATE);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::INVALID_STATE);
       }));
 }
 
@@ -556,8 +561,9 @@
             blink::WebMediaStreamSource::kReadyStateLive);
 
   mock_source()->StopForRestart(
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::IS_STOPPED);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::IS_STOPPED);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -566,8 +572,9 @@
   // Verify that StopForRestart() fails with INVALID_STATE called after the
   // source is already stopped.
   mock_source()->StopForRestart(
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::INVALID_STATE);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::INVALID_STATE);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -575,8 +582,9 @@
 
   mock_source()->Restart(
       media::VideoCaptureFormat(),
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::IS_RUNNING);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::IS_RUNNING);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -586,8 +594,9 @@
   // started.
   mock_source()->Restart(
       media::VideoCaptureFormat(),
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::INVALID_STATE);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::INVALID_STATE);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -610,8 +619,9 @@
             blink::WebMediaStreamSource::kReadyStateLive);
 
   mock_source()->StopForRestart(
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::IS_STOPPED);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::IS_STOPPED);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -619,8 +629,9 @@
 
   mock_source()->Restart(
       media::VideoCaptureFormat(),
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::IS_STOPPED);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::IS_STOPPED);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -630,8 +641,9 @@
   // state.
   mock_source()->Restart(
       media::VideoCaptureFormat(),
-      base::BindOnce([](MediaStreamVideoSource::RestartResult result) {
-        EXPECT_EQ(result, MediaStreamVideoSource::RestartResult::IS_STOPPED);
+      base::BindOnce([](blink::MediaStreamVideoSource::RestartResult result) {
+        EXPECT_EQ(result,
+                  blink::MediaStreamVideoSource::RestartResult::IS_STOPPED);
       }));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(track.Source().GetReadyState(),
@@ -686,15 +698,15 @@
 
   // Simulate assigning |track1| to a sink, then removing it from the sink, and
   // then stopping it.
-  MediaStreamVideoTrack* track1 =
-      MediaStreamVideoTrack::GetVideoTrack(web_track1);
+  blink::MediaStreamVideoTrack* track1 =
+      blink::MediaStreamVideoTrack::GetVideoTrack(web_track1);
   mock_source()->UpdateHasConsumers(track1, true);
   mock_source()->UpdateHasConsumers(track1, false);
   track1->Stop();
 
   // Simulate assigning |track2| to a sink. The source should not be suspended.
-  MediaStreamVideoTrack* track2 =
-      MediaStreamVideoTrack::GetVideoTrack(web_track2);
+  blink::MediaStreamVideoTrack* track2 =
+      blink::MediaStreamVideoTrack::GetVideoTrack(web_track2);
   mock_source()->UpdateHasConsumers(track2, true);
   EXPECT_FALSE(mock_source()->is_suspended());
 }
@@ -705,8 +717,8 @@
   EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
   EXPECT_EQ(0, NumberOfFailedConstraintsCallbacks());
 
-  MediaStreamVideoTrack* track1 =
-      MediaStreamVideoTrack::GetVideoTrack(web_track1);
+  blink::MediaStreamVideoTrack* track1 =
+      blink::MediaStreamVideoTrack::GetVideoTrack(web_track1);
   EXPECT_CALL(*this, MockNotification());
   // This is equivalent to track.stop() in JavaScript.
   track1->StopAndNotify(base::BindOnce(
diff --git a/content/renderer/media/stream/media_stream_video_track_unittest.cc b/content/renderer/media/stream/media_stream_video_track_unittest.cc
index aa63034..425e1a8 100644
--- a/content/renderer/media/stream/media_stream_video_track_unittest.cc
+++ b/content/renderer/media/stream/media_stream_video_track_unittest.cc
@@ -14,12 +14,12 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_checker_impl.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_media_stream_video_sink.h"
 #include "content/renderer/media/stream/mock_media_stream_video_source.h"
-#include "content/renderer/media/stream/video_track_adapter.h"
 #include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 #include "third_party/blink/public/web/web_heap.h"
 
 namespace content {
@@ -63,8 +63,8 @@
       MockMediaStreamVideoSink* sink) {
     const scoped_refptr<media::VideoFrame> frame =
         media::VideoFrame::CreateColorFrame(
-            gfx::Size(MediaStreamVideoSource::kDefaultWidth,
-                      MediaStreamVideoSource::kDefaultHeight),
+            gfx::Size(blink::MediaStreamVideoSource::kDefaultWidth,
+                      blink::MediaStreamVideoSource::kDefaultHeight),
             kColorValue, kColorValue, kColorValue, base::TimeDelta());
     DeliverVideoFrameAndWaitForRenderer(frame, sink);
   }
@@ -87,9 +87,11 @@
   // Create a track that's associated with |mock_source_|.
   blink::WebMediaStreamTrack CreateTrack() {
     const bool enabled = true;
-    blink::WebMediaStreamTrack track = MediaStreamVideoTrack::CreateVideoTrack(
-        mock_source_,
-        blink::WebPlatformMediaStreamSource::ConstraintsCallback(), enabled);
+    blink::WebMediaStreamTrack track =
+        blink::MediaStreamVideoTrack::CreateVideoTrack(
+            mock_source_,
+            blink::WebPlatformMediaStreamSource::ConstraintsCallback(),
+            enabled);
     if (!source_started_) {
       mock_source_->StartMockedSource();
       source_started_ = true;
@@ -100,11 +102,13 @@
   // Create a track that's associated with |mock_source_| and has the given
   // |adapter_settings|.
   blink::WebMediaStreamTrack CreateTrackWithSettings(
-      const VideoTrackAdapterSettings& adapter_settings) {
+      const blink::VideoTrackAdapterSettings& adapter_settings) {
     const bool enabled = true;
-    blink::WebMediaStreamTrack track = MediaStreamVideoTrack::CreateVideoTrack(
-        mock_source_, adapter_settings, base::Optional<bool>(), false, 0.0,
-        blink::WebPlatformMediaStreamSource::ConstraintsCallback(), enabled);
+    blink::WebMediaStreamTrack track =
+        blink::MediaStreamVideoTrack::CreateVideoTrack(
+            mock_source_, adapter_settings, base::Optional<bool>(), false, 0.0,
+            blink::WebPlatformMediaStreamSource::ConstraintsCallback(),
+            enabled);
     if (!source_started_) {
       mock_source_->StartMockedSource();
       source_started_ = true;
@@ -155,10 +159,9 @@
 
   sink.DisconnectFromTrack();
 
-  scoped_refptr<media::VideoFrame> frame =
-      media::VideoFrame::CreateBlackFrame(
-          gfx::Size(MediaStreamVideoSource::kDefaultWidth,
-                    MediaStreamVideoSource::kDefaultHeight));
+  scoped_refptr<media::VideoFrame> frame = media::VideoFrame::CreateBlackFrame(
+      gfx::Size(blink::MediaStreamVideoSource::kDefaultWidth,
+                blink::MediaStreamVideoSource::kDefaultHeight));
   mock_source()->DeliverVideoFrame(frame);
   // Wait for the IO thread to complete delivering frames.
   base::RunLoop().RunUntilIdle();
@@ -214,8 +217,8 @@
   blink::WebMediaStreamTrack track = CreateTrack();
   sink.ConnectToTrack(track);
 
-  MediaStreamVideoTrack* video_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* video_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
 
   DeliverDefaultSizeVideoFrameAndWaitForRenderer(&sink);
   EXPECT_EQ(1, sink.number_of_frames());
@@ -263,16 +266,16 @@
   sink2.ConnectToTrack(track2);
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive, sink2.state());
 
-  MediaStreamVideoTrack* const native_track1 =
-      MediaStreamVideoTrack::GetVideoTrack(track1);
+  blink::MediaStreamVideoTrack* const native_track1 =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track1);
   native_track1->Stop();
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded, sink1.state());
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
             blink_source().GetReadyState());
   sink1.DisconnectFromTrack();
 
-  MediaStreamVideoTrack* const native_track2 =
-        MediaStreamVideoTrack::GetVideoTrack(track2);
+  blink::MediaStreamVideoTrack* const native_track2 =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track2);
   native_track2->Stop();
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded, sink2.state());
   EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded,
@@ -301,8 +304,8 @@
 TEST_F(MediaStreamVideoTrackTest, GetSettings) {
   InitializeSource();
   blink::WebMediaStreamTrack track = CreateTrack();
-  MediaStreamVideoTrack* const native_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* const native_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   blink::WebMediaStreamTrack::Settings settings;
   native_track->GetSettings(settings);
   // These values come straight from the mock video track implementation.
@@ -318,12 +321,12 @@
   const int kAdjustedWidth = 600;
   const int kAdjustedHeight = 400;
   const double kAdjustedFrameRate = 20.0;
-  VideoTrackAdapterSettings adapter_settings(
+  blink::VideoTrackAdapterSettings adapter_settings(
       gfx::Size(kAdjustedWidth, kAdjustedHeight), 0.0, 10000.0,
       kAdjustedFrameRate);
   blink::WebMediaStreamTrack track = CreateTrackWithSettings(adapter_settings);
-  MediaStreamVideoTrack* const native_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* const native_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   blink::WebMediaStreamTrack::Settings settings;
   native_track->GetSettings(settings);
   EXPECT_EQ(kAdjustedWidth, settings.width);
@@ -336,8 +339,8 @@
 TEST_F(MediaStreamVideoTrackTest, GetSettingsStopped) {
   InitializeSource();
   blink::WebMediaStreamTrack track = CreateTrack();
-  MediaStreamVideoTrack* const native_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* const native_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   native_track->Stop();
   blink::WebMediaStreamTrack::Settings settings;
   native_track->GetSettings(settings);
@@ -354,8 +357,8 @@
   MockMediaStreamVideoSink sink;
   blink::WebMediaStreamTrack track = CreateTrack();
   sink.ConnectToTrack(track);
-  MediaStreamVideoTrack* const native_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* const native_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   blink::WebMediaStreamTrack::Settings settings;
 
   const scoped_refptr<media::VideoFrame>& frame1 =
diff --git a/content/renderer/media/stream/mock_constraint_factory.cc b/content/renderer/media/stream/mock_constraint_factory.cc
index 1153e2c..98d6c5a 100644
--- a/content/renderer/media/stream/mock_constraint_factory.cc
+++ b/content/renderer/media/stream/mock_constraint_factory.cc
@@ -7,8 +7,8 @@
 #include "base/macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
 #include "content/renderer/media/stream/mock_constraint_factory.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
 
 namespace content {
 
diff --git a/content/renderer/media/stream/mock_media_stream_registry.cc b/content/renderer/media/stream/mock_media_stream_registry.cc
index d218f5d..30b1302 100644
--- a/content/renderer/media/stream/mock_media_stream_registry.cc
+++ b/content/renderer/media/stream/mock_media_stream_registry.cc
@@ -4,17 +4,17 @@
 
 #include "content/renderer/media/stream/mock_media_stream_registry.h"
 
-#include <string>
+#include <memory>
 
 #include "base/strings/utf_string_conversions.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_media_stream_video_source.h"
-#include "content/renderer/media/stream/video_track_adapter.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 
 namespace content {
 
@@ -54,7 +54,7 @@
 
 void MockMediaStreamRegistry::AddVideoTrack(
     const std::string& track_id,
-    const VideoTrackAdapterSettings& adapter_settings,
+    const blink::VideoTrackAdapterSettings& adapter_settings,
     const base::Optional<bool>& noise_reduction,
     bool is_screencast,
     double min_frame_rate) {
@@ -67,16 +67,17 @@
   blink::WebMediaStreamTrack blink_track;
   blink_track.Initialize(blink::WebString::FromUTF8(track_id), blink_source);
 
-  blink_track.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
+  blink_track.SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
       native_source, adapter_settings, noise_reduction, is_screencast,
-      min_frame_rate, MediaStreamVideoSource::ConstraintsCallback(),
+      min_frame_rate, blink::MediaStreamVideoSource::ConstraintsCallback(),
       true /* enabled */));
   test_stream_.AddTrack(blink_track);
 }
 
 void MockMediaStreamRegistry::AddVideoTrack(const std::string& track_id) {
-  AddVideoTrack(track_id, VideoTrackAdapterSettings(), base::Optional<bool>(),
-                false /* is_screncast */, 0.0 /* min_frame_rate */);
+  AddVideoTrack(track_id, blink::VideoTrackAdapterSettings(),
+                base::Optional<bool>(), false /* is_screncast */,
+                0.0 /* min_frame_rate */);
 }
 
 void MockMediaStreamRegistry::AddAudioTrack(const std::string& track_id) {
diff --git a/content/renderer/media/stream/mock_media_stream_registry.h b/content/renderer/media/stream/mock_media_stream_registry.h
index e92d59e..7b5ee2e7 100644
--- a/content/renderer/media/stream/mock_media_stream_registry.h
+++ b/content/renderer/media/stream/mock_media_stream_registry.h
@@ -10,9 +10,11 @@
 #include "base/optional.h"
 #include "third_party/blink/public/platform/web_media_stream.h"
 
-namespace content {
-
+namespace blink {
 class VideoTrackAdapterSettings;
+}
+
+namespace content {
 
 // This class encapsulates creation of a Blink MediaStream having inside the
 // necessary Blink and Chromium, track and source. The Chrome Video source is
@@ -23,7 +25,7 @@
 
   void Init();
   void AddVideoTrack(const std::string& track_id,
-                     const VideoTrackAdapterSettings& adapter_settings,
+                     const blink::VideoTrackAdapterSettings& adapter_settings,
                      const base::Optional<bool>& noise_reduction,
                      bool is_screen_cast,
                      double min_frame_rate);
diff --git a/content/renderer/media/stream/mock_media_stream_video_source.h b/content/renderer/media/stream/mock_media_stream_video_source.h
index 38f682a..47868e79 100644
--- a/content/renderer/media/stream/mock_media_stream_video_source.h
+++ b/content/renderer/media/stream/mock_media_stream_video_source.h
@@ -5,14 +5,14 @@
 #ifndef CONTENT_RENDERER_MEDIA_STREAM_MOCK_MEDIA_STREAM_VIDEO_SOURCE_H_
 #define CONTENT_RENDERER_MEDIA_STREAM_MOCK_MEDIA_STREAM_VIDEO_SOURCE_H_
 
-#include "content/renderer/media/stream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
 #include "base/macros.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace content {
 
-class MockMediaStreamVideoSource : public MediaStreamVideoSource {
+class MockMediaStreamVideoSource : public blink::MediaStreamVideoSource {
  public:
   MockMediaStreamVideoSource();
   explicit MockMediaStreamVideoSource(bool respond_to_request_refresh_frame);
@@ -43,7 +43,7 @@
   double max_requested_frame_rate() const { return max_requested_frame_rate_; }
 
   void SetMutedState(bool muted_state) override {
-    MediaStreamVideoSource::SetMutedState(muted_state);
+    blink::MediaStreamVideoSource::SetMutedState(muted_state);
     DoSetMutedState(muted_state);
   }
 
@@ -55,7 +55,7 @@
 
   bool is_suspended() { return is_suspended_; }
 
-  // Implements MediaStreamVideoSource.
+  // Implements blink::MediaStreamVideoSource.
   void RequestRefreshFrame() override;
   base::Optional<media::VideoCaptureParams> GetCurrentCaptureParams()
       const override;
@@ -65,7 +65,7 @@
   // Implements MediaStreamSource.
   void DoChangeSource(const blink::MediaStreamDevice& new_device) override;
 
-  // Implements MediaStreamVideoSource.
+  // Implements blink::MediaStreamVideoSource.
   void StartSourceImpl(
       const blink::VideoCaptureDeliverFrameCB& frame_callback) override;
   void StopSourceImpl() override;
diff --git a/content/renderer/media/stream/processed_local_audio_source.cc b/content/renderer/media/stream/processed_local_audio_source.cc
index e8f2cf1..989dc5e2 100644
--- a/content/renderer/media/stream/processed_local_audio_source.cc
+++ b/content/renderer/media/stream/processed_local_audio_source.cc
@@ -14,8 +14,6 @@
 #include "build/build_config.h"
 #include "content/public/common/content_features.h"
 #include "content/renderer/media/audio/audio_device_factory.h"
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/webrtc_audio_device_impl.h"
 #include "content/renderer/media/webrtc_logging.h"
@@ -23,11 +21,14 @@
 #include "media/base/channel_layout.h"
 #include "media/base/sample_rates.h"
 #include "media/webrtc/webrtc_switches.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 #include "third_party/webrtc/media/base/media_channel.h"
 
 namespace content {
 
-using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+using EchoCancellationType =
+    blink::AudioProcessingProperties::EchoCancellationType;
 
 namespace {
 // Used as an identifier for ProcessedLocalAudioSource::From().
@@ -42,10 +43,11 @@
 #endif
 }
 
-void LogAudioProcesingProperties(const AudioProcessingProperties& properties) {
+void LogAudioProcesingProperties(
+    const blink::AudioProcessingProperties& properties) {
   auto aec_to_string =
-      [](AudioProcessingProperties::EchoCancellationType type) {
-        using AEC = AudioProcessingProperties::EchoCancellationType;
+      [](blink::AudioProcessingProperties::EchoCancellationType type) {
+        using AEC = blink::AudioProcessingProperties::EchoCancellationType;
         switch (type) {
           case AEC::kEchoCancellationDisabled:
             return "disabled";
@@ -89,7 +91,7 @@
     int consumer_render_frame_id,
     const blink::MediaStreamDevice& device,
     bool disable_local_echo,
-    const AudioProcessingProperties& audio_processing_properties,
+    const blink::AudioProcessingProperties& audio_processing_properties,
     const ConstraintsCallback& started_callback,
     PeerConnectionDependencyFactory* factory)
     : blink::MediaStreamAudioSource(true /* is_local_source */,
diff --git a/content/renderer/media/stream/processed_local_audio_source.h b/content/renderer/media/stream/processed_local_audio_source.h
index 1297187c..6c11297 100644
--- a/content/renderer/media/stream/processed_local_audio_source.h
+++ b/content/renderer/media/stream/processed_local_audio_source.h
@@ -43,7 +43,7 @@
       int consumer_render_frame_id,
       const blink::MediaStreamDevice& device,
       bool disable_local_echo,
-      const AudioProcessingProperties& audio_processing_properties,
+      const blink::AudioProcessingProperties& audio_processing_properties,
       const ConstraintsCallback& started_callback,
       PeerConnectionDependencyFactory* factory);
 
@@ -60,7 +60,7 @@
     allow_invalid_render_frame_id_for_testing_ = allowed;
   }
 
-  const AudioProcessingProperties& audio_processing_properties() const {
+  const blink::AudioProcessingProperties& audio_processing_properties() const {
     return audio_processing_properties_;
   }
 
@@ -127,7 +127,7 @@
 
   PeerConnectionDependencyFactory* const pc_factory_;
 
-  AudioProcessingProperties audio_processing_properties_;
+  blink::AudioProcessingProperties audio_processing_properties_;
 
   // Callback that's called when the audio source has been initialized.
   ConstraintsCallback started_callback_;
diff --git a/content/renderer/media/stream/processed_local_audio_source_unittest.cc b/content/renderer/media/stream/processed_local_audio_source_unittest.cc
index db510d5..d686d29d 100644
--- a/content/renderer/media/stream/processed_local_audio_source_unittest.cc
+++ b/content/renderer/media/stream/processed_local_audio_source_unittest.cc
@@ -10,13 +10,13 @@
 #include "base/test/scoped_task_environment.h"
 #include "build/build_config.h"
 #include "content/renderer/media/audio/mock_audio_device_factory.h"
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
 #include "content/renderer/media/stream/processed_local_audio_source.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
 #include "media/base/audio_bus.h"
 #include "media/base/audio_parameters.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
@@ -97,7 +97,7 @@
   }
 
   void CreateProcessedLocalAudioSource(
-      const AudioProcessingProperties& properties) {
+      const blink::AudioProcessingProperties& properties) {
     std::unique_ptr<ProcessedLocalAudioSource> source =
         std::make_unique<ProcessedLocalAudioSource>(
             -1 /* consumer_render_frame_id is N/A for non-browser tests */,
@@ -166,7 +166,7 @@
 
   // Turn off the default constraints so the sink will get audio in chunks of
   // the native buffer size.
-  AudioProcessingProperties properties;
+  blink::AudioProcessingProperties properties;
   properties.DisableDefaultProperties();
   CreateProcessedLocalAudioSource(properties);
 
diff --git a/content/renderer/media/stream/remote_media_stream_track_adapter.cc b/content/renderer/media/stream/remote_media_stream_track_adapter.cc
index 741000d..82ca989 100644
--- a/content/renderer/media/stream/remote_media_stream_track_adapter.cc
+++ b/content/renderer/media/stream/remote_media_stream_track_adapter.cc
@@ -4,11 +4,11 @@
 
 #include "content/renderer/media/stream/remote_media_stream_track_adapter.h"
 
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
 #include "content/renderer/media/webrtc/peer_connection_remote_audio_source.h"
 #include "content/renderer/media/webrtc/track_observer.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 
 namespace content {
 
@@ -47,8 +47,9 @@
   capabilities.device_id = blink::WebString::FromUTF8(id());
   web_track()->Source().SetCapabilities(capabilities);
 
-  web_track()->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
-      video_source, MediaStreamVideoSource::ConstraintsCallback(), enabled));
+  web_track()->SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
+      video_source, blink::MediaStreamVideoSource::ConstraintsCallback(),
+      enabled));
 }
 
 RemoteAudioTrackAdapter::RemoteAudioTrackAdapter(
diff --git a/content/renderer/media/stream/user_media_client_impl.cc b/content/renderer/media/stream/user_media_client_impl.cc
index 80f4b66a..c134178b 100644
--- a/content/renderer/media/stream/user_media_client_impl.cc
+++ b/content/renderer/media/stream/user_media_client_impl.cc
@@ -15,7 +15,6 @@
 #include "base/task_runner.h"
 #include "content/renderer/media/stream/apply_constraints_processor.h"
 #include "content/renderer/media/stream/media_stream_device_observer.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/webrtc/peer_connection_tracker.h"
 #include "content/renderer/media/webrtc_logging.h"
 #include "content/renderer/render_frame_impl.h"
@@ -24,6 +23,7 @@
 #include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_document.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/public/web/web_user_gesture_indicator.h"
diff --git a/content/renderer/media/stream/user_media_client_impl_unittest.cc b/content/renderer/media/stream/user_media_client_impl_unittest.cc
index f1b803b..c9dcb37 100644
--- a/content/renderer/media/stream/user_media_client_impl_unittest.cc
+++ b/content/renderer/media/stream/user_media_client_impl_unittest.cc
@@ -16,8 +16,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_task_environment.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "content/renderer/media/stream/media_stream_constraints_util_video_content.h"
 #include "content/renderer/media/stream/media_stream_device_observer.h"
 #include "content/renderer/media/stream/mock_constraint_factory.h"
@@ -28,6 +26,7 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/mediastream/media_devices.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h"
@@ -37,6 +36,7 @@
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 #include "third_party/blink/public/web/web_heap.h"
 
 using testing::_;
@@ -44,7 +44,8 @@
 
 namespace content {
 
-using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+using EchoCancellationType =
+    blink::AudioProcessingProperties::EchoCancellationType;
 
 namespace {
 
@@ -102,7 +103,7 @@
   return factory.CreateWebMediaConstraints();
 }
 
-void CheckVideoSource(MediaStreamVideoSource* source,
+void CheckVideoSource(blink::MediaStreamVideoSource* source,
                       int expected_source_width,
                       int expected_source_height,
                       double expected_source_frame_rate) {
@@ -114,7 +115,7 @@
   EXPECT_EQ(format.frame_rate, expected_source_frame_rate);
 }
 
-void CheckVideoSourceAndTrack(MediaStreamVideoSource* source,
+void CheckVideoSourceAndTrack(blink::MediaStreamVideoSource* source,
                               int expected_source_width,
                               int expected_source_height,
                               double expected_source_frame_rate,
@@ -126,8 +127,8 @@
                    expected_source_frame_rate);
   EXPECT_EQ(web_track.Source().GetReadyState(),
             blink::WebMediaStreamSource::kReadyStateLive);
-  MediaStreamVideoTrack* track =
-      MediaStreamVideoTrack::GetVideoTrack(web_track);
+  blink::MediaStreamVideoTrack* track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(web_track);
   EXPECT_EQ(track->source(), source);
 
   blink::WebMediaStreamTrack::Settings settings;
@@ -274,14 +275,14 @@
     std::move(callback).Run(formats);
   }
 
-  void SetVideoSource(MediaStreamVideoSource* video_source) {
+  void SetVideoSource(blink::MediaStreamVideoSource* video_source) {
     video_source_ = video_source;
   }
 
  private:
   media::AudioParameters audio_parameters_ =
       media::AudioParameters::UnavailableDeviceParams();
-  MediaStreamVideoSource* video_source_ = nullptr;
+  blink::MediaStreamVideoSource* video_source_ = nullptr;
 };
 
 enum RequestState {
@@ -331,10 +332,10 @@
   }
   void ClearLastGeneratedStream() { last_generated_stream_.Reset(); }
 
-  AudioCaptureSettings AudioSettings() const {
+  blink::AudioCaptureSettings AudioSettings() const {
     return AudioCaptureSettingsForTesting();
   }
-  VideoCaptureSettings VideoSettings() const {
+  blink::VideoCaptureSettings VideoSettings() const {
     return VideoCaptureSettingsForTesting();
   }
 
@@ -342,7 +343,7 @@
   blink::WebString constraint_name() const { return constraint_name_; }
 
   // UserMediaProcessor overrides.
-  std::unique_ptr<MediaStreamVideoSource> CreateVideoSource(
+  std::unique_ptr<blink::MediaStreamVideoSource> CreateVideoSource(
       const blink::MediaStreamDevice& device,
       const blink::WebPlatformMediaStreamSource::SourceStoppedCallback&
           stop_callback) override {
@@ -884,9 +885,9 @@
       blink::WebUserMediaRequest::CreateForTesting(CreateDefaultConstraints(),
                                                    CreateDefaultConstraints());
   user_media_client_impl_->RequestUserMediaForTest(request);
-  AudioCaptureSettings audio_capture_settings =
+  blink::AudioCaptureSettings audio_capture_settings =
       user_media_processor_->AudioSettings();
-  VideoCaptureSettings video_capture_settings =
+  blink::VideoCaptureSettings video_capture_settings =
       user_media_processor_->VideoSettings();
   user_media_client_impl_->CancelUserMediaRequest(request);
 
@@ -897,7 +898,7 @@
   EXPECT_TRUE(audio_capture_settings.disable_local_echo());
   EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());
 
-  const AudioProcessingProperties& properties =
+  const blink::AudioProcessingProperties& properties =
       audio_capture_settings.audio_processing_properties();
   EXPECT_EQ(EchoCancellationType::kEchoCancellationAec3,
             properties.echo_cancellation_type);
@@ -905,8 +906,9 @@
   EXPECT_TRUE(properties.goog_auto_gain_control);
   // The default value for goog_experimental_echo_cancellation is platform
   // dependent.
-  EXPECT_EQ(AudioProcessingProperties().goog_experimental_echo_cancellation,
-            properties.goog_experimental_echo_cancellation);
+  EXPECT_EQ(
+      blink::AudioProcessingProperties().goog_experimental_echo_cancellation,
+      properties.goog_experimental_echo_cancellation);
   EXPECT_TRUE(properties.goog_typing_noise_detection);
   EXPECT_TRUE(properties.goog_noise_suppression);
   EXPECT_TRUE(properties.goog_experimental_noise_suppression);
@@ -915,23 +917,23 @@
 
   EXPECT_TRUE(video_capture_settings.HasValue());
   EXPECT_EQ(video_capture_settings.Width(),
-            MediaStreamVideoSource::kDefaultWidth);
+            blink::MediaStreamVideoSource::kDefaultWidth);
   EXPECT_EQ(video_capture_settings.Height(),
-            MediaStreamVideoSource::kDefaultHeight);
+            blink::MediaStreamVideoSource::kDefaultHeight);
   EXPECT_EQ(video_capture_settings.FrameRate(),
-            MediaStreamVideoSource::kDefaultFrameRate);
+            blink::MediaStreamVideoSource::kDefaultFrameRate);
   EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
             media::ResolutionChangePolicy::FIXED_RESOLUTION);
   EXPECT_FALSE(video_capture_settings.noise_reduction());
   EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());
 
-  const VideoTrackAdapterSettings& track_settings =
+  const blink::VideoTrackAdapterSettings& track_settings =
       video_capture_settings.track_adapter_settings();
   EXPECT_FALSE(track_settings.target_size().has_value());
   EXPECT_EQ(track_settings.min_aspect_ratio(),
-            1.0 / MediaStreamVideoSource::kDefaultHeight);
+            1.0 / blink::MediaStreamVideoSource::kDefaultHeight);
   EXPECT_EQ(track_settings.max_aspect_ratio(),
-            MediaStreamVideoSource::kDefaultWidth);
+            blink::MediaStreamVideoSource::kDefaultWidth);
   // 0.0 is the default max_frame_rate and it indicates no frame-rate adjustment
   EXPECT_EQ(track_settings.max_frame_rate(), 0.0);
 }
@@ -948,9 +950,9 @@
       blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
                                                    video_constraints);
   user_media_client_impl_->RequestUserMediaForTest(request);
-  AudioCaptureSettings audio_capture_settings =
+  blink::AudioCaptureSettings audio_capture_settings =
       user_media_processor_->AudioSettings();
-  VideoCaptureSettings video_capture_settings =
+  blink::VideoCaptureSettings video_capture_settings =
       user_media_processor_->VideoSettings();
   user_media_client_impl_->CancelUserMediaRequest(request);
 
@@ -960,7 +962,7 @@
   EXPECT_TRUE(audio_capture_settings.disable_local_echo());
   EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());
 
-  const AudioProcessingProperties& properties =
+  const blink::AudioProcessingProperties& properties =
       audio_capture_settings.audio_processing_properties();
   EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
             properties.echo_cancellation_type);
@@ -983,7 +985,7 @@
   EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());
   EXPECT_FALSE(video_capture_settings.max_frame_rate().has_value());
 
-  const VideoTrackAdapterSettings& track_settings =
+  const blink::VideoTrackAdapterSettings& track_settings =
       video_capture_settings.track_adapter_settings();
   EXPECT_EQ(track_settings.target_width(), kDefaultScreenCastWidth);
   EXPECT_EQ(track_settings.target_height(), kDefaultScreenCastHeight);
@@ -1005,9 +1007,9 @@
       blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
                                                    video_constraints);
   user_media_client_impl_->RequestUserMediaForTest(request);
-  AudioCaptureSettings audio_capture_settings =
+  blink::AudioCaptureSettings audio_capture_settings =
       user_media_processor_->AudioSettings();
-  VideoCaptureSettings video_capture_settings =
+  blink::VideoCaptureSettings video_capture_settings =
       user_media_processor_->VideoSettings();
   user_media_client_impl_->CancelUserMediaRequest(request);
   base::RunLoop().RunUntilIdle();
@@ -1018,7 +1020,7 @@
   EXPECT_FALSE(audio_capture_settings.disable_local_echo());
   EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());
 
-  const AudioProcessingProperties& properties =
+  const blink::AudioProcessingProperties& properties =
       audio_capture_settings.audio_processing_properties();
   EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
             properties.echo_cancellation_type);
@@ -1041,7 +1043,7 @@
   EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());
   EXPECT_FALSE(video_capture_settings.max_frame_rate().has_value());
 
-  const VideoTrackAdapterSettings& track_settings =
+  const blink::VideoTrackAdapterSettings& track_settings =
       video_capture_settings.track_adapter_settings();
   EXPECT_EQ(track_settings.target_width(), kDefaultScreenCastWidth);
   EXPECT_EQ(track_settings.target_height(), kDefaultScreenCastHeight);
@@ -1069,9 +1071,9 @@
       blink::WebUserMediaRequest::CreateForTesting(
           audio_constraints, blink::WebMediaConstraints());
   user_media_client_impl_->RequestUserMediaForTest(request);
-  AudioCaptureSettings audio_capture_settings =
+  blink::AudioCaptureSettings audio_capture_settings =
       user_media_processor_->AudioSettings();
-  VideoCaptureSettings video_capture_settings =
+  blink::VideoCaptureSettings video_capture_settings =
       user_media_processor_->VideoSettings();
   user_media_client_impl_->CancelUserMediaRequest(request);
 
@@ -1082,7 +1084,7 @@
   EXPECT_TRUE(audio_capture_settings.disable_local_echo());
   EXPECT_TRUE(audio_capture_settings.render_to_associated_sink());
 
-  const AudioProcessingProperties& properties =
+  const blink::AudioProcessingProperties& properties =
       audio_capture_settings.audio_processing_properties();
   EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
             properties.echo_cancellation_type);
@@ -1186,9 +1188,9 @@
 TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceSingleTrack) {
   EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
   blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
-  MediaStreamVideoTrack* track =
-      MediaStreamVideoTrack::GetVideoTrack(web_track);
-  MediaStreamVideoSource* source = track->source();
+  blink::MediaStreamVideoTrack* track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(web_track);
+  blink::MediaStreamVideoSource* source = track->source();
   CheckVideoSource(source, 0, 0, 0.0);
 
   media_devices_dispatcher_.SetVideoSource(source);
diff --git a/content/renderer/media/stream/user_media_processor.cc b/content/renderer/media/stream/user_media_processor.cc
index 0fab41fd..53ce7bc 100644
--- a/content/renderer/media/stream/user_media_processor.cc
+++ b/content/renderer/media/stream/user_media_processor.cc
@@ -22,13 +22,10 @@
 #include "content/renderer/media/stream/local_media_stream_audio_source.h"
 #include "content/renderer/media/stream/local_video_capturer_source.h"
 #include "content/renderer/media/stream/media_stream_audio_processor.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "content/renderer/media/stream/media_stream_constraints_util_audio.h"
 #include "content/renderer/media/stream/media_stream_constraints_util_video_content.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_video_device.h"
 #include "content/renderer/media/stream/media_stream_device_observer.h"
 #include "content/renderer/media/stream/media_stream_video_capturer_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/processed_local_audio_source.h"
 #include "content/renderer/media/stream/user_media_client_impl.h"
 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
@@ -47,6 +44,9 @@
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "ui/gfx/geometry/size.h"
 #include "url/origin.h"
 
@@ -59,7 +59,8 @@
 using blink::StreamControls;
 using blink::TrackControls;
 using blink::WebMediaStreamSource;
-using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+using EchoCancellationType =
+    blink::AudioProcessingProperties::EchoCancellationType;
 
 namespace {
 
@@ -159,7 +160,7 @@
   // If the source is a processed source, get the properties from it.
   if (ProcessedLocalAudioSource* processed_source =
           ProcessedLocalAudioSource::From(source_impl)) {
-    AudioProcessingProperties properties =
+    blink::AudioProcessingProperties properties =
         processed_source->audio_processing_properties();
     WebMediaStreamSource::EchoCancellationMode echo_cancellation_mode;
 
@@ -195,10 +196,10 @@
   }
 }
 
-std::vector<VideoInputDeviceCapabilities> ToVideoInputDeviceCapabilities(
+std::vector<blink::VideoInputDeviceCapabilities> ToVideoInputDeviceCapabilities(
     const std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr>&
         input_capabilities) {
-  std::vector<VideoInputDeviceCapabilities> capabilities;
+  std::vector<blink::VideoInputDeviceCapabilities> capabilities;
   for (const auto& capability : input_capabilities) {
     capabilities.emplace_back(capability->device_id, capability->group_id,
                               capability->formats, capability->facing_mode);
@@ -253,16 +254,16 @@
   State state() const { return state_; }
   void set_state(State state) { state_ = state; }
 
-  const AudioCaptureSettings& audio_capture_settings() const {
+  const blink::AudioCaptureSettings& audio_capture_settings() const {
     return audio_capture_settings_;
   }
-  void SetAudioCaptureSettings(const AudioCaptureSettings& settings,
+  void SetAudioCaptureSettings(const blink::AudioCaptureSettings& settings,
                                bool is_content_capture) {
     DCHECK(settings.HasValue());
     is_audio_content_capture_ = is_content_capture;
     audio_capture_settings_ = settings;
   }
-  const VideoCaptureSettings& video_capture_settings() const {
+  const blink::VideoCaptureSettings& video_capture_settings() const {
     return video_capture_settings_;
   }
   bool is_video_content_capture() const {
@@ -271,7 +272,7 @@
   bool is_video_device_capture() const {
     return video_capture_settings_.HasValue() && !is_video_content_capture_;
   }
-  void SetVideoCaptureSettings(const VideoCaptureSettings& settings,
+  void SetVideoCaptureSettings(const blink::VideoCaptureSettings& settings,
                                bool is_content_capture) {
     DCHECK(settings.HasValue());
     is_video_content_capture_ = is_content_capture;
@@ -330,9 +331,9 @@
 
   std::unique_ptr<UserMediaRequest> request_;
   State state_ = State::NOT_SENT_FOR_GENERATION;
-  AudioCaptureSettings audio_capture_settings_;
+  blink::AudioCaptureSettings audio_capture_settings_;
   bool is_audio_content_capture_ = false;
-  VideoCaptureSettings video_capture_settings_;
+  blink::VideoCaptureSettings video_capture_settings_;
   bool is_video_content_capture_ = false;
   blink::WebMediaStream web_stream_;
   StreamControls stream_controls_;
@@ -386,12 +387,12 @@
   DCHECK(source.GetType() == blink::WebMediaStreamSource::kTypeVideo);
   DCHECK(web_request().Video());
   DCHECK(video_capture_settings_.HasValue());
-  MediaStreamVideoSource* native_source =
-      MediaStreamVideoSource::GetVideoSource(source);
+  blink::MediaStreamVideoSource* native_source =
+      blink::MediaStreamVideoSource::GetVideoSource(source);
   DCHECK(native_source);
   sources_.push_back(source);
   sources_waiting_for_callback_.push_back(native_source);
-  return MediaStreamVideoTrack::CreateVideoTrack(
+  return blink::MediaStreamVideoTrack::CreateVideoTrack(
       native_source, video_capture_settings_.track_adapter_settings(),
       video_capture_settings_.noise_reduction(), is_video_content_capture_,
       video_capture_settings_.min_frame_rate(),
@@ -638,17 +639,17 @@
   DCHECK(IsDeviceMediaType(
       current_request_info_->stream_controls()->video.stream_type));
 
-  VideoDeviceCaptureCapabilities capabilities;
+  blink::VideoDeviceCaptureCapabilities capabilities;
   capabilities.device_capabilities =
       ToVideoInputDeviceCapabilities(video_input_capabilities);
   capabilities.noise_reduction_capabilities = {base::Optional<bool>(),
                                                base::Optional<bool>(true),
                                                base::Optional<bool>(false)};
-  VideoCaptureSettings settings = SelectSettingsVideoDeviceCapture(
+  blink::VideoCaptureSettings settings = SelectSettingsVideoDeviceCapture(
       std::move(capabilities), web_request.VideoConstraints(),
-      MediaStreamVideoSource::kDefaultWidth,
-      MediaStreamVideoSource::kDefaultHeight,
-      MediaStreamVideoSource::kDefaultFrameRate);
+      blink::MediaStreamVideoSource::kDefaultWidth,
+      blink::MediaStreamVideoSource::kDefaultHeight,
+      blink::MediaStreamVideoSource::kDefaultFrameRate);
   if (!settings.HasValue()) {
     blink::WebString failed_constraint_name =
         blink::WebString::FromASCII(settings.failed_constraint_name());
@@ -670,7 +671,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(current_request_info_);
   gfx::Size screen_size = GetScreenSize();
-  VideoCaptureSettings settings = SelectSettingsVideoContentCapture(
+  blink::VideoCaptureSettings settings = SelectSettingsVideoContentCapture(
       current_request_info_->web_request().VideoConstraints(),
       current_request_info_->stream_controls()->video.stream_type,
       screen_size.width(), screen_size.height());
@@ -1024,7 +1025,7 @@
   // If the audio device is a loopback device (for screen capture), or if the
   // constraints/effects parameters indicate no audio processing is needed,
   // create an efficient, direct-path MediaStreamAudioSource instance.
-  AudioProcessingProperties audio_processing_properties =
+  blink::AudioProcessingProperties audio_processing_properties =
       current_request_info_->audio_capture_settings()
           .audio_processing_properties();
   if (IsScreenCaptureMediaType(device.type) ||
@@ -1043,7 +1044,8 @@
       source_ready, dependency_factory_);
 }
 
-std::unique_ptr<MediaStreamVideoSource> UserMediaProcessor::CreateVideoSource(
+std::unique_ptr<blink::MediaStreamVideoSource>
+UserMediaProcessor::CreateVideoSource(
     const MediaStreamDevice& device,
     const blink::WebPlatformMediaStreamSource::SourceStoppedCallback&
         stop_callback) {
@@ -1471,14 +1473,14 @@
   return media_devices_dispatcher_cb_.Run();
 }
 
-const AudioCaptureSettings& UserMediaProcessor::AudioCaptureSettingsForTesting()
-    const {
+const blink::AudioCaptureSettings&
+UserMediaProcessor::AudioCaptureSettingsForTesting() const {
   DCHECK(current_request_info_);
   return current_request_info_->audio_capture_settings();
 }
 
-const VideoCaptureSettings& UserMediaProcessor::VideoCaptureSettingsForTesting()
-    const {
+const blink::VideoCaptureSettings&
+UserMediaProcessor::VideoCaptureSettingsForTesting() const {
   DCHECK(current_request_info_);
   return current_request_info_->video_capture_settings();
 }
diff --git a/content/renderer/media/stream/user_media_processor.h b/content/renderer/media/stream/user_media_processor.h
index 8a7c93a2..ef3aa51 100644
--- a/content/renderer/media/stream/user_media_processor.h
+++ b/content/renderer/media/stream/user_media_processor.h
@@ -28,7 +28,10 @@
 }
 
 namespace blink {
+class AudioCaptureSettings;
 class MediaStreamAudioSource;
+class MediaStreamVideoSource;
+class VideoCaptureSettings;
 class WebMediaStream;
 class WebMediaStreamSource;
 class WebString;
@@ -36,12 +39,9 @@
 
 namespace content {
 
-class AudioCaptureSettings;
 class AudioDeviceCaptureCapability;
 class MediaStreamDeviceObserver;
-class MediaStreamVideoSource;
 class PeerConnectionDependencyFactory;
-class VideoCaptureSettings;
 class RenderFrameImpl;
 
 // TODO(guidou): Add |request_id| and |is_processing_user_gesture| to
@@ -135,14 +135,14 @@
       const blink::MediaStreamDevice& device,
       const blink::WebPlatformMediaStreamSource::ConstraintsCallback&
           source_ready);
-  virtual std::unique_ptr<MediaStreamVideoSource> CreateVideoSource(
+  virtual std::unique_ptr<blink::MediaStreamVideoSource> CreateVideoSource(
       const blink::MediaStreamDevice& device,
       const blink::WebPlatformMediaStreamSource::SourceStoppedCallback&
           stop_callback);
 
   // Intended to be used only for testing.
-  const AudioCaptureSettings& AudioCaptureSettingsForTesting() const;
-  const VideoCaptureSettings& VideoCaptureSettingsForTesting() const;
+  const blink::AudioCaptureSettings& AudioCaptureSettingsForTesting() const;
+  const blink::VideoCaptureSettings& VideoCaptureSettingsForTesting() const;
 
  private:
   class RequestInfo;
@@ -274,7 +274,7 @@
           video_input_capabilities);
   void FinalizeSelectVideoDeviceSettings(
       const blink::WebUserMediaRequest& web_request,
-      const VideoCaptureSettings& settings);
+      const blink::VideoCaptureSettings& settings);
   void SelectVideoContentSettings();
 
   void GenerateStreamForCurrentRequestInfo();
diff --git a/content/renderer/media/stream/video_track_adapter_unittest.cc b/content/renderer/media/stream/video_track_adapter_unittest.cc
index 10f919a..a65018d9 100644
--- a/content/renderer/media/stream/video_track_adapter_unittest.cc
+++ b/content/renderer/media/stream/video_track_adapter_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/stream/video_track_adapter.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 
 #include <limits>
 
@@ -11,6 +11,9 @@
 
 namespace content {
 
+using blink::VideoTrackAdapter;
+using blink::VideoTrackAdapterSettings;
+
 // Most VideoTrackAdapter functionality is tested in MediaStreamVideoSourceTest.
 // These tests focus on the computation of cropped frame sizes in edge cases
 // that cannot be easily reproduced by a mocked video source, such as tests
diff --git a/content/renderer/media/stream/webmediaplayer_ms.cc b/content/renderer/media/stream/webmediaplayer_ms.cc
index 4cd7b75..f4176200 100644
--- a/content/renderer/media/stream/webmediaplayer_ms.cc
+++ b/content/renderer/media/stream/webmediaplayer_ms.cc
@@ -15,7 +15,6 @@
 #include "cc/layers/video_frame_provider_client_impl.h"
 #include "cc/layers/video_layer.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/webmediaplayer_ms_compositor.h"
 #include "content/renderer/media/web_media_element_source_utils.h"
 #include "content/renderer/media/webrtc_logging.h"
@@ -39,6 +38,7 @@
 #include "third_party/blink/public/platform/web_rect.h"
 #include "third_party/blink/public/platform/web_size.h"
 #include "third_party/blink/public/platform/web_surface_layer_bridge.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 
 namespace {
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
index 1d57d6ea..d670b00a 100644
--- a/content/renderer/media/webrtc/media_stream_remote_video_source.cc
+++ b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
@@ -244,7 +244,7 @@
   // longer receives the video track.
   if (!observer_)
     return;
-  DCHECK(state() != MediaStreamVideoSource::ENDED);
+  DCHECK(state() != blink::MediaStreamVideoSource::ENDED);
   scoped_refptr<webrtc::VideoTrackInterface> video_track(
       static_cast<webrtc::VideoTrackInterface*>(observer_->track().get()));
   video_track->RemoveSink(delegate_.get());
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.h b/content/renderer/media/webrtc/media_stream_remote_video_source.h
index 04401c8..dd3c84ce9 100644
--- a/content/renderer/media/webrtc/media_stream_remote_video_source.h
+++ b/content/renderer/media/webrtc/media_stream_remote_video_source.h
@@ -11,20 +11,21 @@
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "content/common/content_export.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
 
 namespace content {
 
 class TrackObserver;
 
-// MediaStreamRemoteVideoSource implements the MediaStreamVideoSource interface
-// for video tracks received on a PeerConnection. The purpose of the class is
-// to make sure there is no difference between a video track where the source is
-// a local source and a video track where the source is a remote video track.
+// MediaStreamRemoteVideoSource implements the blink::MediaStreamVideoSource
+// interface for video tracks received on a PeerConnection. The purpose of the
+// class is to make sure there is no difference between a video track where the
+// source is a local source and a video track where the source is a remote video
+// track.
 class CONTENT_EXPORT MediaStreamRemoteVideoSource
-    : public MediaStreamVideoSource {
+    : public blink::MediaStreamVideoSource {
  public:
   explicit MediaStreamRemoteVideoSource(
       std::unique_ptr<TrackObserver> observer);
@@ -36,7 +37,7 @@
   void OnSourceTerminated();
 
  protected:
-  // Implements MediaStreamVideoSource.
+  // Implements blink::MediaStreamVideoSource.
   void StartSourceImpl(
       const blink::VideoCaptureDeliverFrameCB& frame_callback) override;
 
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc b/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
index 2261a12..0386ff0 100644
--- a/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
+++ b/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
@@ -15,13 +15,13 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_media_stream_video_sink.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/track_observer.h"
 #include "media/base/video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_heap.h"
 #include "third_party/webrtc/api/video/color_space.h"
 #include "third_party/webrtc/api/video/i420_buffer.h"
@@ -100,9 +100,9 @@
     return remote_source_;
   }
 
-  MediaStreamVideoTrack* CreateTrack() {
+  blink::MediaStreamVideoTrack* CreateTrack() {
     bool enabled = true;
-    return new MediaStreamVideoTrack(
+    return new blink::MediaStreamVideoTrack(
         source(),
         base::Bind(&MediaStreamRemoteVideoSourceTest::OnTrackStarted,
                    base::Unretained(this)),
@@ -161,7 +161,7 @@
 };
 
 TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
-  std::unique_ptr<MediaStreamVideoTrack> track(CreateTrack());
+  std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
   EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
 
   MockMediaStreamVideoSink sink;
@@ -184,7 +184,7 @@
 }
 
 TEST_F(MediaStreamRemoteVideoSourceTest, RemoteTrackStop) {
-  std::unique_ptr<MediaStreamVideoTrack> track(CreateTrack());
+  std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
 
   MockMediaStreamVideoSink sink;
   track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
@@ -201,7 +201,7 @@
 }
 
 TEST_F(MediaStreamRemoteVideoSourceTest, PreservesColorSpace) {
-  std::unique_ptr<MediaStreamVideoTrack> track(CreateTrack());
+  std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
   MockMediaStreamVideoSink sink;
   track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
 
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
index 628aa84a..d115ab6 100644
--- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
+++ b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
@@ -18,11 +18,11 @@
 #include "base/timer/timer.h"
 #include "content/public/common/content_features.h"
 #include "content/public/renderer/media_stream_utils.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/webrtc_video_track_source.h"
 #include "media/base/limits.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/webrtc/api/video_track_source_proxy.h"
 
 namespace content {
@@ -214,8 +214,8 @@
     PeerConnectionDependencyFactory* factory,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
     : weak_factory_(this) {
-  MediaStreamVideoTrack* video_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* video_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   DCHECK(video_track);
 
   absl::optional<bool> needs_denoising =
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
index e2f703f..970b7ef 100644
--- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
+++ b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
@@ -16,14 +16,17 @@
 class SingleThreadTaskRunner;
 }
 
+namespace blink {
+class MediaStreamVideoTrack;
+}
+
 namespace content {
 
-class MediaStreamVideoTrack;
 class PeerConnectionDependencyFactory;
 class WebRtcVideoTrackSource;
 
 // MediaStreamVideoWebRtcSink is an adapter between a
-// content::MediaStreamVideoTrack object and a webrtc VideoTrack that is
+// blink::MediaStreamVideoTrack object and a webrtc VideoTrack that is
 // currently sent on a PeerConnection.
 // The responsibility of the class is to create and own a representation of a
 // webrtc VideoTrack that can be added and removed from a RTCPeerConnection. An
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc b/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
index 762e1479..3b32fea 100644
--- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
+++ b/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
@@ -8,10 +8,10 @@
 #include "content/child/child_process.h"
 #include "content/renderer/media/stream/mock_constraint_factory.h"
 #include "content/renderer/media/stream/mock_media_stream_registry.h"
-#include "content/renderer/media/stream/video_track_adapter.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 
 namespace content {
 namespace {
@@ -34,8 +34,9 @@
 
   void SetVideoTrack(const base::Optional<bool>& noise_reduction) {
     registry_.Init();
-    registry_.AddVideoTrack("test video track", VideoTrackAdapterSettings(),
-                            noise_reduction, false, 0.0);
+    registry_.AddVideoTrack("test video track",
+                            blink::VideoTrackAdapterSettings(), noise_reduction,
+                            false, 0.0);
     blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
         registry_.test_stream().VideoTracks();
     track_ = video_tracks[0];
diff --git a/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc b/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
index a1ec79ef..880ab858 100644
--- a/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
+++ b/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
@@ -13,9 +13,7 @@
 
 namespace content {
 
-MockWebRTCPeerConnectionHandlerClient::
-MockWebRTCPeerConnectionHandlerClient()
-    : candidate_mline_index_(-1) {
+MockWebRTCPeerConnectionHandlerClient::MockWebRTCPeerConnectionHandlerClient() {
   ON_CALL(*this, DidGenerateICECandidate(_))
       .WillByDefault(
           testing::Invoke(this, &MockWebRTCPeerConnectionHandlerClient::
diff --git a/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h b/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
index c9788a8..1736aa4 100644
--- a/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
+++ b/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
@@ -73,7 +73,7 @@
       std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers);
 
   const std::string& candidate_sdp() const { return candidate_sdp_; }
-  int candidate_mlineindex() const {
+  const base::Optional<uint16_t>& candidate_mlineindex() const {
     return candidate_mline_index_;
   }
   const std::string& candidate_mid() const { return candidate_mid_ ; }
@@ -82,7 +82,7 @@
  private:
   blink::WebString remote_stream_id_;
   std::string candidate_sdp_;
-  int candidate_mline_index_;
+  base::Optional<uint16_t> candidate_mline_index_;
   std::string candidate_mid_;
 
   DISALLOW_COPY_AND_ASSIGN(MockWebRTCPeerConnectionHandlerClient);
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
index a17b9ad..454098b 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -30,8 +30,6 @@
 #include "content/public/common/feature_h264_with_openh264_ffmpeg.h"
 #include "content/public/common/webrtc_ip_handling_policy.h"
 #include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/webrtc/audio_codec_factory.h"
 #include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
 #include "content/renderer/media/webrtc/stun_field_trial.h"
@@ -59,6 +57,8 @@
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_url.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_document.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/webrtc/api/create_peerconnection_factory.h"
diff --git a/content/renderer/media/webrtc/peer_connection_tracker.cc b/content/renderer/media/webrtc/peer_connection_tracker.cc
index 09dd4d8..f2f2b0b1 100644
--- a/content/renderer/media/webrtc/peer_connection_tracker.cc
+++ b/content/renderer/media/webrtc/peer_connection_tracker.cc
@@ -681,10 +681,12 @@
   int id = GetLocalIDForHandler(pc_handler);
   if (id == -1)
     return;
-  std::string value =
-      "sdpMid: " + candidate->SdpMid().Utf8() + ", " +
-      "sdpMLineIndex: " + base::NumberToString(candidate->SdpMLineIndex()) +
-      ", " + "candidate: " + candidate->Candidate().Utf8();
+  std::string value = "sdpMid: " + candidate->SdpMid().Utf8() + ", " +
+                      "sdpMLineIndex: " +
+                      (candidate->SdpMLineIndex()
+                           ? base::NumberToString(*candidate->SdpMLineIndex())
+                           : "null") +
+                      ", " + "candidate: " + candidate->Candidate().Utf8();
 
   // OnIceCandidate always succeeds as it's a callback from the browser.
   DCHECK(source != SOURCE_LOCAL || succeeded);
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler.cc b/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
index ff4f8f65..a2e2306 100644
--- a/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
@@ -29,7 +29,6 @@
 #include "base/unguessable_token.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/peer_connection_tracker.h"
 #include "content/renderer/media/webrtc/rtc_dtmf_sender_handler.h"
@@ -55,6 +54,7 @@
 #include "third_party/blink/public/platform/web_rtc_stats.h"
 #include "third_party/blink/public/platform/web_rtc_void_request.h"
 #include "third_party/blink/public/platform/web_url.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 #include "third_party/webrtc/api/rtc_event_log_output.h"
 #include "third_party/webrtc/pc/media_session.h"
 #include "third_party/webrtc/pc/session_description.h"
@@ -1464,9 +1464,12 @@
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
   std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
-      dependency_factory_->CreateIceCandidate(candidate->SdpMid().Utf8(),
-                                              candidate->SdpMLineIndex(),
-                                              candidate->Candidate().Utf8()));
+      dependency_factory_->CreateIceCandidate(
+          candidate->SdpMid().Utf8(),
+          candidate->SdpMLineIndex()
+              ? static_cast<int>(*candidate->SdpMLineIndex())
+              : -1,
+          candidate->Candidate().Utf8()));
   bool return_value = false;
 
   if (native_candidate) {
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
index 07d65e5..f498a91 100644
--- a/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
+++ b/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
@@ -25,7 +25,6 @@
 #include "base/values.h"
 #include "content/child/child_process.h"
 #include "content/renderer/media/audio/mock_audio_device_factory.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_constraint_factory.h"
 #include "content/renderer/media/stream/mock_media_stream_video_source.h"
 #include "content/renderer/media/stream/processed_local_audio_source.h"
@@ -56,6 +55,7 @@
 #include "third_party/blink/public/platform/web_rtc_stats_request.h"
 #include "third_party/blink/public/platform/web_rtc_void_request.h"
 #include "third_party/blink/public/platform/web_url.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_heap.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/api/rtp_receiver_interface.h"
@@ -324,7 +324,7 @@
                 "Mock device", media::AudioParameters::kAudioCDSampleRate,
                 media::CHANNEL_LAYOUT_STEREO,
                 media::AudioParameters::kAudioCDSampleRate / 100),
-            false /* disable_local_echo */, AudioProcessingProperties(),
+            false /* disable_local_echo */, blink::AudioProcessingProperties(),
             base::Bind(&RTCPeerConnectionHandlerTest::OnAudioSourceStarted),
             mock_dependency_factory_.get());
     audio_source->SetAllowInvalidRenderFrameIdForTesting(true);
@@ -352,9 +352,9 @@
     CHECK(audio_source->ConnectToTrack(audio_tracks[0]));
     blink::WebVector<blink::WebMediaStreamTrack> video_tracks(
         static_cast<size_t>(1));
-    video_tracks[0] = MediaStreamVideoTrack::CreateVideoTrack(
-        native_video_source, MediaStreamVideoSource::ConstraintsCallback(),
-        true);
+    video_tracks[0] = blink::MediaStreamVideoTrack::CreateVideoTrack(
+        native_video_source,
+        blink::MediaStreamVideoSource::ConstraintsCallback(), true);
 
     blink::WebMediaStream local_stream;
     local_stream.Initialize(blink::WebString::FromUTF8(stream_label),
@@ -386,7 +386,7 @@
     for (const auto& track : stream.AudioTracks())
       blink::MediaStreamAudioTrack::From(track)->Stop();
     for (const auto& track : stream.VideoTracks())
-      MediaStreamVideoTrack::GetVideoTrack(track)->Stop();
+      blink::MediaStreamVideoTrack::GetVideoTrack(track)->Stop();
   }
 
   static void OnAudioSourceStarted(blink::WebPlatformMediaStreamSource* source,
@@ -842,8 +842,8 @@
 
   blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
       local_stream.VideoTracks();
-  MediaStreamVideoSource* native_video_source =
-      static_cast<MediaStreamVideoSource*>(
+  blink::MediaStreamVideoSource* native_video_source =
+      static_cast<blink::MediaStreamVideoSource*>(
           video_tracks[0].Source().GetPlatformSource());
   native_video_source->StopSource();
 
@@ -1145,7 +1145,7 @@
 
   // Check NULL candidate after ice gathering is completed.
   EXPECT_EQ("", mock_client_->candidate_mid());
-  EXPECT_EQ(-1, mock_client_->candidate_mlineindex());
+  EXPECT_FALSE(mock_client_->candidate_mlineindex().has_value());
   EXPECT_EQ("", mock_client_->candidate_sdp());
 }
 
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
index e0b3e89..09a000b 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
+++ b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/test/scoped_task_environment.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_media_stream_video_sink.h"
 #include "content/renderer/media/stream/mock_media_stream_video_source.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
@@ -23,6 +22,7 @@
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_heap.h"
 
 namespace content {
@@ -71,8 +71,9 @@
     // Takes ownership of |video_source|.
     web_source.SetPlatformSource(base::WrapUnique(video_source));
 
-    return MediaStreamVideoTrack::CreateVideoTrack(
-        video_source, MediaStreamVideoSource::ConstraintsCallback(), true);
+    return blink::MediaStreamVideoTrack::CreateVideoTrack(
+        video_source, blink::MediaStreamVideoSource::ConstraintsCallback(),
+        true);
   }
 
   void CreateRemoteTrackAdapter(
diff --git a/content/renderer/media_capture_from_element/canvas_capture_handler.cc b/content/renderer/media_capture_from_element/canvas_capture_handler.cc
index 8a3f06e7..f19a522f 100644
--- a/content/renderer/media_capture_from_element/canvas_capture_handler.cc
+++ b/content/renderer/media_capture_from_element/canvas_capture_handler.cc
@@ -14,16 +14,16 @@
 #include "base/strings/utf_string_conversions.h"
 #include "components/viz/common/gl_helper.h"
 #include "content/public/renderer/render_thread.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "content/renderer/media/stream/media_stream_video_capturer_source.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/render_thread_impl.h"
 #include "media/base/limits.h"
 #include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/libyuv/include/libyuv.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/gpu/GrBackendSurface.h"
@@ -477,7 +477,7 @@
   base::Base64Encode(base::RandBytesAsString(64), &str_track_id);
   const blink::WebString track_id = blink::WebString::FromASCII(str_track_id);
   media::VideoCaptureFormats preferred_formats = source->GetPreferredFormats();
-  MediaStreamVideoSource* media_stream_source =
+  blink::MediaStreamVideoSource* media_stream_source =
       new MediaStreamVideoCapturerSource(
           blink::WebPlatformMediaStreamSource::SourceStoppedCallback(),
           std::move(source));
@@ -491,8 +491,8 @@
       false /* is_device_capture */));
 
   web_track->Initialize(webkit_source);
-  web_track->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
-      media_stream_source, MediaStreamVideoSource::ConstraintsCallback(),
+  web_track->SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>(
+      media_stream_source, blink::MediaStreamVideoSource::ConstraintsCallback(),
       true));
 }
 
diff --git a/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc b/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc
index c27acee1e..2694000 100644
--- a/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc
+++ b/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc
@@ -12,7 +12,6 @@
 #include "base/trace_event/trace_event.h"
 #include "cc/paint/skia_paint_canvas.h"
 #include "content/public/renderer/render_thread.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
 #include "media/base/limits.h"
 #include "media/blink/webmediaplayer_impl.h"
 #include "skia/ext/platform_canvas.h"
@@ -20,6 +19,7 @@
 #include "third_party/blink/public/platform/web_media_player.h"
 #include "third_party/blink/public/platform/web_rect.h"
 #include "third_party/blink/public/platform/web_size.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 #include "third_party/libyuv/include/libyuv.h"
 
 namespace {
@@ -69,7 +69,8 @@
   // to specify it.
   const media::VideoCaptureFormat format(
       web_media_player_->NaturalSize(),
-      MediaStreamVideoSource::kDefaultFrameRate, media::PIXEL_FORMAT_I420);
+      blink::MediaStreamVideoSource::kDefaultFrameRate,
+      media::PIXEL_FORMAT_I420);
   media::VideoCaptureFormats formats;
   formats.push_back(format);
   return formats;
diff --git a/content/renderer/media_recorder/video_track_recorder_unittest.cc b/content/renderer/media_recorder/video_track_recorder_unittest.cc
index d879a9a3..6194edb 100644
--- a/content/renderer/media_recorder/video_track_recorder_unittest.cc
+++ b/content/renderer/media_recorder/video_track_recorder_unittest.cc
@@ -19,7 +19,6 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "content/child/child_process.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "content/renderer/media/stream/mock_media_stream_video_source.h"
 #include "media/base/video_codecs.h"
 #include "media/base/video_frame.h"
@@ -27,6 +26,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/web_heap.h"
 
 using media::VideoFrame;
@@ -77,7 +77,7 @@
     blink_source_.SetPlatformSource(base::WrapUnique(mock_source_));
     blink_track_.Initialize(blink_source_);
 
-    track_ = new MediaStreamVideoTrack(
+    track_ = new blink::MediaStreamVideoTrack(
         mock_source_,
         blink::WebPlatformMediaStreamSource::ConstraintsCallback(),
         true /* enabled */);
@@ -156,7 +156,7 @@
   // |mock_source_| is owned by |blink_source_|, |track_| by |blink_track_|.
   MockMediaStreamVideoSource* mock_source_;
   blink::WebMediaStreamSource blink_source_;
-  MediaStreamVideoTrack* track_;
+  blink::MediaStreamVideoTrack* track_;
   blink::WebMediaStreamTrack blink_track_;
 
   std::unique_ptr<VideoTrackRecorder> video_track_recorder_;
diff --git a/content/renderer/media_stream_utils.cc b/content/renderer/media_stream_utils.cc
index 4913d8d4..f0f8af8 100644
--- a/content/renderer/media_stream_utils.cc
+++ b/content/renderer/media_stream_utils.cc
@@ -12,15 +12,15 @@
 #include "base/rand_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/renderer/media/stream/external_media_stream_audio_source.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "content/renderer/media/stream/media_stream_video_capturer_source.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "media/base/audio_capturer_source.h"
 #include "media/capture/video_capturer_source.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h"
 #include "third_party/blink/public/platform/web_media_stream.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 
 namespace content {
 
@@ -36,7 +36,7 @@
 
   media::VideoCaptureFormats preferred_formats =
       video_source->GetPreferredFormats();
-  MediaStreamVideoSource* const media_stream_source =
+  blink::MediaStreamVideoSource* const media_stream_source =
       new MediaStreamVideoCapturerSource(
           blink::WebPlatformMediaStreamSource::SourceStoppedCallback(),
           std::move(video_source));
@@ -52,8 +52,8 @@
       track_id, preferred_formats,
       media::VideoFacingMode::MEDIA_VIDEO_FACING_NONE,
       false /* is_device_capture */));
-  web_media_stream->AddTrack(MediaStreamVideoTrack::CreateVideoTrack(
-      media_stream_source, MediaStreamVideoSource::ConstraintsCallback(),
+  web_media_stream->AddTrack(blink::MediaStreamVideoTrack::CreateVideoTrack(
+      media_stream_source, blink::MediaStreamVideoSource::ConstraintsCallback(),
       true));
   return true;
 }
@@ -62,8 +62,8 @@
     const blink::WebMediaStreamTrack& video_track) {
   if (video_track.IsNull())
     return;
-  MediaStreamVideoSource* const source =
-      MediaStreamVideoSource::GetVideoSource(video_track.Source());
+  blink::MediaStreamVideoSource* const source =
+      blink::MediaStreamVideoSource::GetVideoSource(video_track.Source());
   if (source)
     source->RequestRefreshFrame();
 }
@@ -73,16 +73,16 @@
     blink::WebMediaStreamSink* sink,
     const blink::VideoCaptureDeliverFrameCB& callback,
     bool is_sink_secure) {
-  MediaStreamVideoTrack* const video_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* const video_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   DCHECK(video_track);
   video_track->AddSink(sink, callback, is_sink_secure);
 }
 
 void RemoveSinkFromMediaStreamTrack(const blink::WebMediaStreamTrack& track,
                                     blink::WebMediaStreamSink* sink) {
-  MediaStreamVideoTrack* const video_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* const video_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   if (video_track)
     video_track->RemoveSink(sink);
 }
@@ -90,8 +90,8 @@
 void OnFrameDroppedAtMediaStreamSink(
     const blink::WebMediaStreamTrack& track,
     media::VideoCaptureFrameDropReason reason) {
-  MediaStreamVideoTrack* const video_track =
-      MediaStreamVideoTrack::GetVideoTrack(track);
+  blink::MediaStreamVideoTrack* const video_track =
+      blink::MediaStreamVideoTrack::GetVideoTrack(track);
   if (video_track)
     video_track->OnFrameDropped(reason);
 }
diff --git a/content/renderer/media_stream_video_sink.cc b/content/renderer/media_stream_video_sink.cc
index 82d3fcef..a984471 100644
--- a/content/renderer/media_stream_video_sink.cc
+++ b/content/renderer/media_stream_video_sink.cc
@@ -5,7 +5,7 @@
 #include "content/renderer/media_stream_video_sink.h"
 
 #include "content/public/renderer/media_stream_utils.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 
 namespace content {
 
diff --git a/content/renderer/pepper/pepper_media_stream_video_track_host.cc b/content/renderer/pepper/pepper_media_stream_video_track_host.cc
index 30390fd..666b7e7 100644
--- a/content/renderer/pepper/pepper_media_stream_video_track_host.cc
+++ b/content/renderer/pepper/pepper_media_stream_video_track_host.cc
@@ -13,8 +13,6 @@
 #include "base/rand_util.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/utf_string_conversions.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/base/video_util.h"
 #include "ppapi/c/pp_errors.h"
@@ -24,6 +22,8 @@
 #include "ppapi/host/host_message_context.h"
 #include "ppapi/proxy/ppapi_messages.h"
 #include "ppapi/shared_impl/media_stream_buffer.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/libyuv/include/libyuv.h"
 
 using media::VideoFrame;
@@ -177,7 +177,7 @@
 namespace content {
 
 // Internal class used for delivering video frames on the IO-thread to
-// the MediaStreamVideoSource implementation.
+// the blink::MediaStreamVideoSource implementation.
 class PepperMediaStreamVideoTrackHost::FrameDeliverer
     : public base::RefCountedThreadSafe<FrameDeliverer> {
  public:
@@ -409,7 +409,7 @@
 }
 
 class PepperMediaStreamVideoTrackHost::VideoSource final
-    : public MediaStreamVideoSource {
+    : public blink::MediaStreamVideoSource {
  public:
   explicit VideoSource(base::WeakPtr<PepperMediaStreamVideoTrackHost> host)
       : host_(std::move(host)) {}
@@ -514,13 +514,13 @@
                            blink::WebMediaStreamSource::kTypeVideo,
                            blink::WebString::FromASCII(kPepperVideoSourceName),
                            false /* remote */);
-  MediaStreamVideoSource* const source =
+  blink::MediaStreamVideoSource* const source =
       new VideoSource(weak_factory_.GetWeakPtr());
   webkit_source.SetPlatformSource(
       base::WrapUnique(source));  // Takes ownership of |source|.
 
   const bool enabled = true;
-  track_ = MediaStreamVideoTrack::CreateVideoTrack(
+  track_ = blink::MediaStreamVideoTrack::CreateVideoTrack(
       source,
       base::Bind(&PepperMediaStreamVideoTrackHost::OnTrackStarted,
                  base::Unretained(this)),
diff --git a/content/renderer/pepper/pepper_video_capture_host.cc b/content/renderer/pepper/pepper_video_capture_host.cc
index 2d671fb..248f8a2a 100644
--- a/content/renderer/pepper/pepper_video_capture_host.cc
+++ b/content/renderer/pepper/pepper_video_capture_host.cc
@@ -4,7 +4,6 @@
 
 #include "content/renderer/pepper/pepper_video_capture_host.h"
 
-#include "content/renderer/media/stream/media_stream_video_source.h"
 #include "content/renderer/pepper/host_globals.h"
 #include "content/renderer/pepper/pepper_media_device_manager.h"
 #include "content/renderer/pepper/pepper_platform_video_capture.h"
@@ -20,6 +19,7 @@
 #include "ppapi/shared_impl/host_resource.h"
 #include "ppapi/thunk/enter.h"
 #include "ppapi/thunk/ppb_buffer_api.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
 using ppapi::HostResource;
 using ppapi::TrackedCallback;
@@ -132,7 +132,7 @@
                                      &frame_rate))
       rounded_frame_rate = static_cast<int>(frame_rate + 0.5 /* round */);
     else
-      rounded_frame_rate = MediaStreamVideoSource::kUnknownFrameRate;
+      rounded_frame_rate = blink::MediaStreamVideoSource::kUnknownFrameRate;
     AllocBuffers(alloc_size_, rounded_frame_rate);
   }
 
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 1277a3b..b837bc63 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -851,6 +851,19 @@
   UpdateWebRTCMethodCount(api_name);
 }
 
+base::Optional<double>
+RendererBlinkPlatformImpl::GetWebRtcMaxCaptureFrameRate() {
+  const std::string max_fps_str =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          switches::kWebRtcMaxCaptureFramerate);
+  if (!max_fps_str.empty()) {
+    double value;
+    if (base::StringToDouble(max_fps_str, &value) && value >= 0.0)
+      return value;
+  }
+  return base::nullopt;
+}
+
 //------------------------------------------------------------------------------
 
 std::unique_ptr<blink::WebSpeechSynthesizer>
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 38ff3be..b5eca2c 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -182,6 +182,8 @@
   std::unique_ptr<webrtc::RtpCapabilities> GetRtpReceiverCapabilities(
       const blink::WebString& kind) override;
   void UpdateWebRTCAPICount(blink::WebRTCAPIName api_name) override;
+  base::Optional<double> GetWebRtcMaxCaptureFrameRate() override;
+
   std::unique_ptr<blink::WebGraphicsContext3DProvider>
   CreateOffscreenGraphicsContext3DProvider(
       const blink::Platform::ContextAttributes& attributes,
diff --git a/content/test/data/gpu/pixel_video_test.js b/content/test/data/gpu/pixel_video_test.js
index 18adb1f..1ffc1e90 100644
--- a/content/test/data/gpu/pixel_video_test.js
+++ b/content/test/data/gpu/pixel_video_test.js
@@ -5,8 +5,8 @@
 var video;
 
 // Some videos are less than 60 fps, so actual video frame presentations
-// could be much less than 60.
-var g_swaps_before_success = 60
+// could be much less than 30.
+var g_swaps_before_success = 30
 
 function main() {
   video = document.getElementById("video");
diff --git a/content/test/data/lite_js_test.mojom b/content/test/data/lite_js_test.mojom
index 58b0d61..9bf8d77 100644
--- a/content/test/data/lite_js_test.mojom
+++ b/content/test/data/lite_js_test.mojom
@@ -6,6 +6,7 @@
 
 struct TestStruct {
   int32 x;
+  const bool isValid = false;
 };
 
 union TestUnion {
diff --git a/extensions/browser/api/device_permissions_manager.cc b/extensions/browser/api/device_permissions_manager.cc
index 3d030c3..f31310d 100644
--- a/extensions/browser/api/device_permissions_manager.cc
+++ b/extensions/browser/api/device_permissions_manager.cc
@@ -16,11 +16,11 @@
 #include "base/values.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_thread.h"
-#include "device/base/device_client.h"
 #include "device/usb/mojo/type_converters.h"
 #include "device/usb/usb_device.h"
 #include "device/usb/usb_ids.h"
 #include "extensions/browser/api/hid/hid_device_manager.h"
+#include "extensions/browser/api/usb/usb_device_manager.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extensions_browser_client.h"
@@ -32,8 +32,6 @@
 
 using content::BrowserContext;
 using content::BrowserThread;
-using device::UsbDevice;
-using device::UsbService;
 using extensions::APIPermission;
 using extensions::Extension;
 using extensions::ExtensionHost;
@@ -559,13 +557,13 @@
     device_permissions->entries_.insert(device_entry);
     device_permissions->ephemeral_usb_devices_[device_info.guid] = device_entry;
 
-    // Only start observing when an ephemeral device has been added so that
-    // UsbService is not automatically initialized on profile creation (which it
-    // would be if this call were in the constructor).
-    UsbService* usb_service = device::DeviceClient::Get()->GetUsbService();
-    if (!usb_service_observer_.IsObserving(usb_service)) {
-      usb_service_observer_.Add(usb_service);
-    }
+    // Make sure the UsbDeviceManager has been connected to the DeviceService.
+    // UsbDeviceManager is responsible for removing the permission entry for
+    // an ephemeral USB device. Only do this when an ephemeral device has been
+    // added.
+    UsbDeviceManager* device_manager = UsbDeviceManager::Get(context_);
+    DCHECK(device_manager);
+    device_manager->EnsureConnectionWithDeviceManager();
   }
 }
 
@@ -648,7 +646,7 @@
 
 DevicePermissionsManager::DevicePermissionsManager(
     content::BrowserContext* context)
-    : context_(context), usb_service_observer_(this) {}
+    : context_(context) {}
 
 DevicePermissionsManager::~DevicePermissionsManager() {
   for (const auto& map_entry : extension_id_to_device_permissions_) {
@@ -667,22 +665,6 @@
   return NULL;
 }
 
-void DevicePermissionsManager::OnDeviceRemovedCleanup(
-    scoped_refptr<UsbDevice> device) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  for (const auto& map_entry : extension_id_to_device_permissions_) {
-    // An ephemeral device cannot be identified if it is reconnected and so
-    // permission to access it is cleared on disconnect.
-    DevicePermissions* device_permissions = map_entry.second;
-    const auto& device_entry =
-        device_permissions->ephemeral_usb_devices_.find(device->guid());
-    if (device_entry != device_permissions->ephemeral_usb_devices_.end()) {
-      device_permissions->entries_.erase(device_entry->second);
-      device_permissions->ephemeral_usb_devices_.erase(device_entry);
-    }
-  }
-}
-
 void DevicePermissionsManager::RemoveEntryByDeviceGUID(
     DevicePermissionEntry::Type type,
     const std::string& guid) {
diff --git a/extensions/browser/api/device_permissions_manager.h b/extensions/browser/api/device_permissions_manager.h
index faa8710a..4282acba 100644
--- a/extensions/browser/api/device_permissions_manager.h
+++ b/extensions/browser/api/device_permissions_manager.h
@@ -22,7 +22,6 @@
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "device/usb/public/mojom/device.mojom.h"
-#include "device/usb/usb_service.h"
 #include "services/device/public/mojom/hid.mojom.h"
 
 namespace base {
@@ -35,6 +34,10 @@
 class BrowserContext;
 }
 
+namespace device {
+class UsbDevice;
+}
+
 namespace extensions {
 
 // Stores information about a device saved with access granted.
@@ -136,8 +139,7 @@
 };
 
 // Manages saved device permissions for all extensions.
-class DevicePermissionsManager : public KeyedService,
-                                 public device::UsbService::Observer {
+class DevicePermissionsManager : public KeyedService {
  public:
   static DevicePermissionsManager* Get(content::BrowserContext* context);
 
@@ -187,14 +189,9 @@
 
   DevicePermissions* GetInternal(const std::string& extension_id) const;
 
-  // UsbService::Observer implementation
-  void OnDeviceRemovedCleanup(scoped_refptr<device::UsbDevice> device) override;
-
   base::ThreadChecker thread_checker_;
   content::BrowserContext* context_;
   std::map<std::string, DevicePermissions*> extension_id_to_device_permissions_;
-  ScopedObserver<device::UsbService, device::UsbService::Observer>
-      usb_service_observer_;
 
   DISALLOW_COPY_AND_ASSIGN(DevicePermissionsManager);
 };
diff --git a/extensions/browser/api/usb/usb_device_manager.cc b/extensions/browser/api/usb/usb_device_manager.cc
index 4f670f1..1cf32d9a 100644
--- a/extensions/browser/api/usb/usb_device_manager.cc
+++ b/extensions/browser/api/usb/usb_device_manager.cc
@@ -78,9 +78,6 @@
 void UsbDeviceManager::Observer::OnDeviceRemoved(
     const device::mojom::UsbDeviceInfo& device_info) {}
 
-void UsbDeviceManager::Observer::OnDeviceRemovedCleanup(
-    const device::mojom::UsbDeviceInfo& device_info) {}
-
 void UsbDeviceManager::Observer::OnDeviceManagerConnectionError() {}
 
 UsbDeviceManager::UsbDeviceManager(content::BrowserContext* browser_context)
@@ -143,8 +140,17 @@
 
 void UsbDeviceManager::GetDevices(
     device::mojom::UsbDeviceManager::GetDevicesCallback callback) {
-  EnsureConnectionWithDeviceManager();
-  device_manager_->GetDevices(/*options=*/nullptr, std::move(callback));
+  if (!is_initialized_) {
+    pending_get_devices_requests_.push(std::move(callback));
+    EnsureConnectionWithDeviceManager();
+    return;
+  }
+
+  std::vector<device::mojom::UsbDeviceInfoPtr> device_list;
+  for (const auto& pair : devices_)
+    device_list.push_back(pair.second->Clone());
+  base::SequencedTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(std::move(callback), std::move(device_list)));
 }
 
 void UsbDeviceManager::GetDevice(
@@ -156,6 +162,13 @@
                              std::move(device_client));
 }
 
+const device::mojom::UsbDeviceInfo* UsbDeviceManager::GetDeviceInfo(
+    const std::string& guid) {
+  DCHECK(is_initialized_);
+  auto it = devices_.find(guid);
+  return it == devices_.end() ? nullptr : it->second.get();
+}
+
 #if defined(OS_CHROMEOS)
 void UsbDeviceManager::CheckAccess(
     const std::string& guid,
@@ -165,50 +178,6 @@
 }
 #endif  // defined(OS_CHROMEOS)
 
-void UsbDeviceManager::Shutdown() {
-  EventRouter* event_router = EventRouter::Get(browser_context_);
-  if (event_router) {
-    event_router->UnregisterObserver(this);
-  }
-}
-
-void UsbDeviceManager::OnListenerAdded(const EventListenerInfo& details) {
-  EnsureConnectionWithDeviceManager();
-}
-
-void UsbDeviceManager::OnDeviceAdded(
-    device::mojom::UsbDeviceInfoPtr device_info) {
-  DCHECK(device_info);
-
-  DispatchEvent(usb::OnDeviceAdded::kEventName, *device_info);
-
-  // Notify all observers.
-  for (auto& observer : observer_list_)
-    observer.OnDeviceAdded(*device_info);
-}
-
-void UsbDeviceManager::OnDeviceRemoved(
-    device::mojom::UsbDeviceInfoPtr device_info) {
-  DCHECK(device_info);
-
-  DispatchEvent(usb::OnDeviceRemoved::kEventName, *device_info);
-
-  // Notify all observers for OnDeviceRemoved event.
-  for (auto& observer : observer_list_)
-    observer.OnDeviceRemoved(*device_info);
-
-  auto iter = guid_to_id_map_.find(device_info->guid);
-  if (iter != guid_to_id_map_.end()) {
-    int id = iter->second;
-    guid_to_id_map_.erase(iter);
-    id_to_guid_map_.erase(id);
-  }
-
-  // Notify all observers for OnDeviceRemovedCleanup event.
-  for (auto& observer : observer_list_)
-    observer.OnDeviceRemovedCleanup(*device_info);
-}
-
 void UsbDeviceManager::EnsureConnectionWithDeviceManager() {
   if (device_manager_)
     return;
@@ -223,6 +192,70 @@
   SetUpDeviceManagerConnection();
 }
 
+void UsbDeviceManager::SetDeviceManagerForTesting(
+    device::mojom::UsbDeviceManagerPtr fake_device_manager) {
+  DCHECK(!device_manager_);
+  DCHECK(fake_device_manager);
+  device_manager_ = std::move(fake_device_manager);
+  SetUpDeviceManagerConnection();
+}
+
+void UsbDeviceManager::Shutdown() {
+  EventRouter* event_router = EventRouter::Get(browser_context_);
+  if (event_router) {
+    event_router->UnregisterObserver(this);
+  }
+}
+
+void UsbDeviceManager::OnListenerAdded(const EventListenerInfo& details) {
+  EnsureConnectionWithDeviceManager();
+}
+
+void UsbDeviceManager::OnDeviceAdded(
+    device::mojom::UsbDeviceInfoPtr device_info) {
+  DCHECK(device_info);
+  // Update the device list.
+  DCHECK(!base::ContainsKey(devices_, device_info->guid));
+  std::string guid = device_info->guid;
+  auto result =
+      devices_.insert(std::make_pair(std::move(guid), std::move(device_info)));
+  const device::mojom::UsbDeviceInfo& stored_info = *result.first->second;
+
+  DispatchEvent(usb::OnDeviceAdded::kEventName, stored_info);
+
+  // Notify all observers.
+  for (auto& observer : observer_list_)
+    observer.OnDeviceAdded(stored_info);
+}
+
+void UsbDeviceManager::OnDeviceRemoved(
+    device::mojom::UsbDeviceInfoPtr device_info) {
+  DCHECK(device_info);
+  // Update the device list.
+  DCHECK(base::ContainsKey(devices_, device_info->guid));
+  devices_.erase(device_info->guid);
+
+  DispatchEvent(usb::OnDeviceRemoved::kEventName, *device_info);
+
+  // Notify all observers for OnDeviceRemoved event.
+  for (auto& observer : observer_list_)
+    observer.OnDeviceRemoved(*device_info);
+
+  auto iter = guid_to_id_map_.find(device_info->guid);
+  if (iter != guid_to_id_map_.end()) {
+    int id = iter->second;
+    guid_to_id_map_.erase(iter);
+    id_to_guid_map_.erase(id);
+  }
+
+  // Remove permission entry for ephemeral USB device.
+  DevicePermissionsManager* permissions_manager =
+      DevicePermissionsManager::Get(browser_context_);
+  DCHECK(permissions_manager);
+  permissions_manager->RemoveEntryByDeviceGUID(DevicePermissionEntry::Type::USB,
+                                               device_info->guid);
+}
+
 void UsbDeviceManager::SetUpDeviceManagerConnection() {
   DCHECK(device_manager_);
   device_manager_.set_connection_error_handler(
@@ -233,12 +266,36 @@
   DCHECK(!client_binding_);
   device::mojom::UsbDeviceManagerClientAssociatedPtrInfo client;
   client_binding_.Bind(mojo::MakeRequest(&client));
-  device_manager_->SetClient(std::move(client));
+  device_manager_->EnumerateDevicesAndSetClient(
+      std::move(client), base::BindOnce(&UsbDeviceManager::InitDeviceList,
+                                        weak_factory_.GetWeakPtr()));
+}
+
+void UsbDeviceManager::InitDeviceList(
+    std::vector<device::mojom::UsbDeviceInfoPtr> devices) {
+  for (auto& device_info : devices) {
+    DCHECK(device_info);
+    std::string guid = device_info->guid;
+    devices_.insert(std::make_pair(guid, std::move(device_info)));
+  }
+  is_initialized_ = true;
+
+  while (!pending_get_devices_requests_.empty()) {
+    std::vector<device::mojom::UsbDeviceInfoPtr> device_list;
+    for (const auto& entry : devices_) {
+      device_list.push_back(entry.second->Clone());
+    }
+    std::move(pending_get_devices_requests_.front())
+        .Run(std::move(device_list));
+    pending_get_devices_requests_.pop();
+  }
 }
 
 void UsbDeviceManager::OnDeviceManagerConnectionError() {
   device_manager_.reset();
   client_binding_.Close();
+  devices_.clear();
+  is_initialized_ = false;
 
   guid_to_id_map_.clear();
   id_to_guid_map_.clear();
diff --git a/extensions/browser/api/usb/usb_device_manager.h b/extensions/browser/api/usb/usb_device_manager.h
index 809297b2..1e95668e 100644
--- a/extensions/browser/api/usb/usb_device_manager.h
+++ b/extensions/browser/api/usb/usb_device_manager.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <string>
+#include <vector>
 
 #include "base/macros.h"
 #include "content/public/browser/browser_thread.h"
@@ -35,7 +36,6 @@
    public:
     virtual void OnDeviceAdded(const device::mojom::UsbDeviceInfo&);
     virtual void OnDeviceRemoved(const device::mojom::UsbDeviceInfo&);
-    virtual void OnDeviceRemovedCleanup(const device::mojom::UsbDeviceInfo&);
     virtual void OnDeviceManagerConnectionError();
   };
 
@@ -62,12 +62,19 @@
                  device::mojom::UsbDeviceRequest device_request,
                  device::mojom::UsbDeviceClientPtr device_client);
 
+  const device::mojom::UsbDeviceInfo* GetDeviceInfo(const std::string& guid);
+
 #if defined(OS_CHROMEOS)
   void CheckAccess(
       const std::string& guid,
       device::mojom::UsbDeviceManager::CheckAccessCallback callback);
 #endif  // defined(OS_CHROMEOS)
 
+  void EnsureConnectionWithDeviceManager();
+
+  void SetDeviceManagerForTesting(
+      device::mojom::UsbDeviceManagerPtr fake_device_manager);
+
  private:
   friend class BrowserContextKeyedAPIFactory<UsbDeviceManager>;
 
@@ -76,7 +83,6 @@
 
   // BrowserContextKeyedAPI implementation.
   static const char* service_name() { return "UsbDeviceManager"; }
-  static const bool kServiceIsNULLWhileTesting = true;
 
   // KeyedService implementation.
   void Shutdown() override;
@@ -88,8 +94,8 @@
   void OnDeviceAdded(device::mojom::UsbDeviceInfoPtr device_info) override;
   void OnDeviceRemoved(device::mojom::UsbDeviceInfoPtr device_info) override;
 
-  void EnsureConnectionWithDeviceManager();
   void SetUpDeviceManagerConnection();
+  void InitDeviceList(std::vector<device::mojom::UsbDeviceInfoPtr> devices);
   void OnDeviceManagerConnectionError();
 
   // Broadcasts a device add or remove event for the given device.
@@ -104,6 +110,11 @@
   std::map<std::string, int> guid_to_id_map_;
   std::map<int, std::string> id_to_guid_map_;
 
+  bool is_initialized_ = false;
+  base::queue<device::mojom::UsbDeviceManager::GetDevicesCallback>
+      pending_get_devices_requests_;
+  std::map<std::string, device::mojom::UsbDeviceInfoPtr> devices_;
+
   // Connection to |device_manager_instance_|.
   device::mojom::UsbDeviceManagerPtr device_manager_;
   mojo::AssociatedBinding<device::mojom::UsbDeviceManagerClient>
diff --git a/extensions/common/api/printer_provider/usb_printer_manifest_data.cc b/extensions/common/api/printer_provider/usb_printer_manifest_data.cc
index d25a7110..d14187b 100644
--- a/extensions/common/api/printer_provider/usb_printer_manifest_data.cc
+++ b/extensions/common/api/printer_provider/usb_printer_manifest_data.cc
@@ -4,14 +4,11 @@
 
 #include "extensions/common/api/printer_provider/usb_printer_manifest_data.h"
 
-#include <memory>
 #include <utility>
 
 #include "base/strings/utf_string_conversions.h"
 #include "device/usb/public/cpp/usb_utils.h"
 #include "device/usb/public/mojom/device_enumeration_options.mojom.h"
-#include "device/usb/public/mojom/device_manager.mojom.h"
-#include "device/usb/usb_device.h"
 #include "extensions/common/api/extensions_manifest_types.h"
 #include "extensions/common/manifest_constants.h"
 
@@ -76,9 +73,9 @@
 }
 
 bool UsbPrinterManifestData::SupportsDevice(
-    const device::UsbDevice& device) const {
+    const device::mojom::UsbDeviceInfo& device) const {
   for (const auto& filter : filters_) {
-    if (UsbDeviceFilterMatches(*filter, device))
+    if (device::UsbDeviceFilterMatches(*filter, device))
       return true;
   }
 
diff --git a/extensions/common/api/printer_provider/usb_printer_manifest_data.h b/extensions/common/api/printer_provider/usb_printer_manifest_data.h
index 2dfecc7..2fab639 100644
--- a/extensions/common/api/printer_provider/usb_printer_manifest_data.h
+++ b/extensions/common/api/printer_provider/usb_printer_manifest_data.h
@@ -5,15 +5,13 @@
 #ifndef EXTENSIONS_COMMON_API_PRINTER_PROVIDER_USB_PRINTER_MANIFEST_DATA_H_
 #define EXTENSIONS_COMMON_API_PRINTER_PROVIDER_USB_PRINTER_MANIFEST_DATA_H_
 
+#include <memory>
 #include <vector>
 
-#include "device/usb/public/mojom/device_manager.mojom.h"
+#include "device/usb/public/mojom/device.mojom.h"
+#include "device/usb/public/mojom/device_enumeration_options.mojom.h"
 #include "extensions/common/extension.h"
 
-namespace device {
-class UsbDevice;
-}
-
 namespace extensions {
 
 // The parsed form of the "usb_printers" manifest entry.
@@ -32,7 +30,7 @@
       const base::Value& value,
       base::string16* error);
 
-  bool SupportsDevice(const device::UsbDevice& device) const;
+  bool SupportsDevice(const device::mojom::UsbDeviceInfo& device) const;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(UsbPrinterManifestTest, Filters);
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc
index e5929d97..45cf0ea 100644
--- a/extensions/shell/browser/shell_content_browser_client.cc
+++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -318,7 +318,9 @@
     ui::PageTransition page_transition,
     bool has_user_gesture,
     const std::string& method,
-    const net::HttpRequestHeaders& headers) {
+    const net::HttpRequestHeaders& headers,
+    network::mojom::URLLoaderFactoryRequest* factory_request,
+    network::mojom::URLLoaderFactory*& out_factory) {
   return false;
 }
 
diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h
index f669db6..29f0830 100644
--- a/extensions/shell/browser/shell_content_browser_client.h
+++ b/extensions/shell/browser/shell_content_browser_client.h
@@ -92,7 +92,9 @@
       ui::PageTransition page_transition,
       bool has_user_gesture,
       const std::string& method,
-      const net::HttpRequestHeaders& headers) override;
+      const net::HttpRequestHeaders& headers,
+      network::mojom::URLLoaderFactoryRequest* factory_request,
+      network::mojom::URLLoaderFactory*& out_factory) override;
   network::mojom::URLLoaderFactoryPtrInfo
   CreateURLLoaderFactoryForNetworkRequests(
       content::RenderProcessHost* process,
diff --git a/fuchsia/BUILD.gn b/fuchsia/BUILD.gn
index d171f0c..8096362 100644
--- a/fuchsia/BUILD.gn
+++ b/fuchsia/BUILD.gn
@@ -10,9 +10,6 @@
 # Location where Fuchsia release archives and supporting files are placed.
 _release_artifact_root = "$root_out_dir/fuchsia_artifacts"
 
-# Location where debug symbol tarballs are placed.
-_symbol_artifact_root = "$root_out_dir/symbol_artifacts"
-
 fidl_library("web_fidl") {
   library_name = "web"
   namespace = "chromium"
@@ -108,38 +105,43 @@
   ]
 }
 
-copy("symbol_tarballs") {
-  sources = [
-    "$_release_artifact_root/build_id.txt",
-    "$root_gen_dir/fuchsia/engine/chromium/chromium.symbols.tar.bz2",
-    "$root_gen_dir/fuchsia/http/http/http.symbols.tar.bz2",
-    "$root_gen_dir/fuchsia/runners/cast_runner/cast_runner.symbols.tar.bz2",
-    "$root_gen_dir/fuchsia/runners/web_runner/web_runner.symbols.tar.bz2",
-    _license_path,
-  ]
-  outputs = [
-    "$_symbol_artifact_root/{{source_file_part}}",
-  ]
-  deps = [
-    ":build_id",
-    ":license",
-    "//fuchsia/engine:symbol_archive",
-    "//fuchsia/http:symbol_archive",
-    "//fuchsia/runners:cast_runner_symbol_archive",
-    "//fuchsia/runners:web_runner_symbol_archive",
-  ]
-}
+if (is_official_build) {
+  # Location where debug symbol tarballs are placed.
+  _symbol_artifact_root = "$root_out_dir/symbol_artifacts"
 
-# Specifies the build steps that must be performed before the creation of
-# a CIPD archive.
-group("archive_sources") {
-  deps = [
-    ":build_id",
-    ":license",
-    ":release_archives",
-    ":symbol_tarballs",
-  ]
-}
+  copy("symbol_tarballs") {
+    sources = [
+      "$_release_artifact_root/build_id.txt",
+      "$root_gen_dir/fuchsia/engine/chromium/chromium.symbols.tar.bz2",
+      "$root_gen_dir/fuchsia/http/http/http.symbols.tar.bz2",
+      "$root_gen_dir/fuchsia/runners/cast_runner/cast_runner.symbols.tar.bz2",
+      "$root_gen_dir/fuchsia/runners/web_runner/web_runner.symbols.tar.bz2",
+      _license_path,
+    ]
+    outputs = [
+      "$_symbol_artifact_root/{{source_file_part}}",
+    ]
+    deps = [
+      ":build_id",
+      ":license",
+      "//fuchsia/engine:symbol_archive",
+      "//fuchsia/http:symbol_archive",
+      "//fuchsia/runners:cast_runner_symbol_archive",
+      "//fuchsia/runners:web_runner_symbol_archive",
+    ]
+  }
+
+  # Specifies the build steps that must be performed before the creation of
+  # a CIPD archive.
+  group("archive_sources") {
+    deps = [
+      ":build_id",
+      ":license",
+      ":release_archives",
+      ":symbol_tarballs",
+    ]
+  }
+}  # is_official_build
 
 # Used by the top-level "gn_all" target to discover Fuchsia build targets.
 group("gn_all") {
diff --git a/fuchsia/base/BUILD.gn b/fuchsia/base/BUILD.gn
index 88becec5..ca183d7 100644
--- a/fuchsia/base/BUILD.gn
+++ b/fuchsia/base/BUILD.gn
@@ -27,6 +27,8 @@
   sources = [
     "agent_impl.cc",
     "agent_impl.h",
+    "lifecycle_impl.cc",
+    "lifecycle_impl.h",
   ]
   deps = [
     "//base",
diff --git a/fuchsia/base/lifecycle_impl.cc b/fuchsia/base/lifecycle_impl.cc
new file mode 100644
index 0000000..2193ab0f3
--- /dev/null
+++ b/fuchsia/base/lifecycle_impl.cc
@@ -0,0 +1,23 @@
+// 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 "fuchsia/base/lifecycle_impl.h"
+
+#include "base/fuchsia/service_directory.h"
+
+namespace cr_fuchsia {
+
+LifecycleImpl::LifecycleImpl(base::fuchsia::ServiceDirectory* service_directory,
+                             base::OnceClosure on_terminate)
+    : binding_(service_directory, this),
+      on_terminate_(std::move(on_terminate)) {}
+
+LifecycleImpl::~LifecycleImpl() = default;
+
+void LifecycleImpl::Terminate() {
+  if (on_terminate_)
+    std::move(on_terminate_).Run();
+}
+
+}  // namespace cr_fuchsia
diff --git a/fuchsia/base/lifecycle_impl.h b/fuchsia/base/lifecycle_impl.h
new file mode 100644
index 0000000..ecc7bde7
--- /dev/null
+++ b/fuchsia/base/lifecycle_impl.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FUCHSIA_BASE_LIFECYCLE_IMPL_H_
+#define FUCHSIA_BASE_LIFECYCLE_IMPL_H_
+
+#include <fuchsia/modular/cpp/fidl.h>
+
+#include "base/fuchsia/scoped_service_binding.h"
+#include "base/macros.h"
+
+namespace base {
+namespace fuchsia {
+class ServiceDirectory;
+}  // namespace fuchsia
+}  // namespace base
+
+namespace cr_fuchsia {
+
+// Implements the fuchsia.modular.Lifecycle protocol, by invoking the supplied
+// graceful teardown Callback when Terminate() is called, or when the Lifecycle
+// client drops the channel.
+class LifecycleImpl : public ::fuchsia::modular::Lifecycle {
+ public:
+  LifecycleImpl(base::fuchsia::ServiceDirectory* service_directory,
+                base::OnceClosure on_terminate);
+  ~LifecycleImpl() override;
+
+  // fuchsia::modular::Lifecycle implementation.
+  void Terminate() override;
+
+ private:
+  const base::fuchsia::ScopedServiceBinding<::fuchsia::modular::Lifecycle>
+      binding_;
+
+  base::OnceClosure on_terminate_;
+
+  DISALLOW_COPY_AND_ASSIGN(LifecycleImpl);
+};
+
+}  // namespace cr_fuchsia
+
+#endif  // FUCHSIA_BASE_LIFECYCLE_IMPL_H_
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn
index dcb2539a..ae74510 100644
--- a/fuchsia/engine/BUILD.gn
+++ b/fuchsia/engine/BUILD.gn
@@ -92,6 +92,7 @@
     "//content/public/common",
     "//content/public/renderer",
     "//fuchsia/base",
+    "//fuchsia/base:modular",
     "//mojo/public/cpp/bindings",
     "//services/network/public/cpp",
     "//services/service_manager/sandbox",
@@ -244,11 +245,13 @@
   ]
 }
 
-symbol_archive("symbol_archive") {
-  deps = [
-    ":web_engine",
-  ]
-  ids_txt = "$root_gen_dir/fuchsia/engine/chromium/ids.txt"
-  archive_name =
-      "$root_gen_dir/fuchsia/engine/chromium/chromium.symbols.tar.bz2"
-}
+if (is_official_build) {
+  symbol_archive("symbol_archive") {
+    deps = [
+      ":web_engine",
+    ]
+    ids_txt = "$root_gen_dir/fuchsia/engine/chromium/ids.txt"
+    archive_name =
+        "$root_gen_dir/fuchsia/engine/chromium/chromium.symbols.tar.bz2"
+  }
+}  # is_official_build
diff --git a/fuchsia/engine/context_provider_main.cc b/fuchsia/engine/context_provider_main.cc
index fa417b6..cdf9683 100644
--- a/fuchsia/engine/context_provider_main.cc
+++ b/fuchsia/engine/context_provider_main.cc
@@ -9,18 +9,22 @@
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "fuchsia/base/lifecycle_impl.h"
 #include "fuchsia/engine/context_provider_impl.h"
 
 int ContextProviderMain() {
   base::MessageLoopForUI message_loop;
-  base::fuchsia::ServiceDirectory* directory =
+  base::fuchsia::ServiceDirectory* const directory =
       base::fuchsia::ServiceDirectory::GetDefault();
+
   ContextProviderImpl context_provider;
   base::fuchsia::ScopedServiceBinding<chromium::web::ContextProvider> binding(
       directory, &context_provider);
 
-  // TODO(crbug.com/852145): Currently the process will run until it's killed.
-  base::RunLoop().Run();
+  base::RunLoop run_loop;
+  cr_fuchsia::LifecycleImpl lifecycle(directory, run_loop.QuitClosure());
+
+  run_loop.Run();
 
   return 0;
 }
diff --git a/fuchsia/http/BUILD.gn b/fuchsia/http/BUILD.gn
index 439f2af..67b7a87 100644
--- a/fuchsia/http/BUILD.gn
+++ b/fuchsia/http/BUILD.gn
@@ -63,10 +63,12 @@
   ]
 }
 
-symbol_archive("symbol_archive") {
-  deps = [
-    ":http_pkg",
-  ]
-  ids_txt = "$root_gen_dir/fuchsia/http/http/ids.txt"
-  archive_name = "$root_gen_dir/fuchsia/http/http/http.symbols.tar.bz2"
-}
+if (is_official_build) {
+  symbol_archive("symbol_archive") {
+    deps = [
+      ":http_pkg",
+    ]
+    ids_txt = "$root_gen_dir/fuchsia/http/http/ids.txt"
+    archive_name = "$root_gen_dir/fuchsia/http/http/http.symbols.tar.bz2"
+  }
+}  # is_official_build
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia/runners/BUILD.gn
index 146af2b4..00ce41e 100644
--- a/fuchsia/runners/BUILD.gn
+++ b/fuchsia/runners/BUILD.gn
@@ -212,20 +212,22 @@
   ]
 }
 
-symbol_archive("cast_runner_symbol_archive") {
-  deps = [
-    ":cast_runner_pkg",
-  ]
-  ids_txt = "$root_gen_dir/fuchsia/runners/cast_runner/ids.txt"
-  archive_name =
-      "$root_gen_dir/fuchsia/runners/cast_runner/cast_runner.symbols.tar.bz2"
-}
+if (is_official_build) {
+  symbol_archive("cast_runner_symbol_archive") {
+    deps = [
+      ":cast_runner_pkg",
+    ]
+    ids_txt = "$root_gen_dir/fuchsia/runners/cast_runner/ids.txt"
+    archive_name =
+        "$root_gen_dir/fuchsia/runners/cast_runner/cast_runner.symbols.tar.bz2"
+  }
 
-symbol_archive("web_runner_symbol_archive") {
-  deps = [
-    ":web_runner_pkg",
-  ]
-  ids_txt = "$root_gen_dir/fuchsia/runners/web_runner/ids.txt"
-  archive_name =
-      "$root_gen_dir/fuchsia/runners/web_runner/web_runner.symbols.tar.bz2"
-}
+  symbol_archive("web_runner_symbol_archive") {
+    deps = [
+      ":web_runner_pkg",
+    ]
+    ids_txt = "$root_gen_dir/fuchsia/runners/web_runner/ids.txt"
+    archive_name =
+        "$root_gen_dir/fuchsia/runners/web_runner/web_runner.symbols.tar.bz2"
+  }
+}  # is_official_build
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc
index 8154366..9a5ad2bef 100644
--- a/gpu/ipc/service/direct_composition_surface_win.cc
+++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -1657,7 +1657,6 @@
     if (!video_swap_chain->PresentToSwapChain(*pending_overlays_[i],
                                               &video_needs_commit)) {
       DLOG(ERROR) << "PresentToSwapChain failed";
-      DCHECK(false);
       return false;
     }
     needs_commit = needs_commit || video_needs_commit;
@@ -1693,7 +1692,6 @@
     HRESULT hr = dcomp_device_->Commit();
     if (FAILED(hr)) {
       DLOG(ERROR) << "Commit failed with error 0x" << std::hex << hr;
-      DCHECK(false);
       return false;
     }
   }
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 9c9e6dd..bcc113b 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -748,6 +748,9 @@
       <message name="IDS_IOS_GOOGLE_SERVICES_SETTINGS_TITLE" desc="Title for the view in the Settings for enabling/disabling Sync and all the Google services. [Length: 26em] [iOS only]">
         Sync and Google Services
       </message>
+      <message name="IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_DISABLBED_BY_ADMINISTRATOR_STATUS" desc="Error displayed when the sync is disabled by the enterprise policy. The user doesn't have a regular gmail account.">
+        Sync is disabled by your administrator
+      </message>
       <message name="IDS_IOS_HISTORY_OTHER_FORMS_OF_HISTORY" desc="The notification at the top of the history page indicating that deleting Chrome browsing history will not delete other forms of history stored at Google My Activity.">
         Your Google Account may have other forms of browsing history at <ph name="BEGIN_LINK">BEGIN_LINK</ph>history.google.com<ph name="END_LINK">END_LINK</ph>.
       </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_DISABLBED_BY_ADMINISTRATOR_STATUS.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_DISABLBED_BY_ADMINISTRATOR_STATUS.png.sha1
new file mode 100644
index 0000000..0096c41
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_DISABLBED_BY_ADMINISTRATOR_STATUS.png.sha1
@@ -0,0 +1 @@
+9f4e421b076cff2dc87a837457f0deb787b9e9a8
\ No newline at end of file
diff --git a/ios/chrome/browser/net/ios_chrome_http_user_agent_settings.h b/ios/chrome/browser/net/ios_chrome_http_user_agent_settings.h
index 707ea00..1a26c38 100644
--- a/ios/chrome/browser/net/ios_chrome_http_user_agent_settings.h
+++ b/ios/chrome/browser/net/ios_chrome_http_user_agent_settings.h
@@ -10,7 +10,7 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "components/prefs/pref_member.h"
-#include "net/url_request/http_user_agent_settings.h"
+#include "net/base/http_user_agent_settings.h"
 
 class PrefService;
 
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
index ae316005..9150d9627 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -249,10 +249,14 @@
 
   if (AuthenticationServiceFactory::GetForBrowserState(browserState)
           ->IsAuthenticatedIdentityManaged()) {
-    NSString* hostedDomain = base::SysUTF8ToNSString(
-        IdentityManagerFactory::GetForBrowserState(browserState)
-            ->GetPrimaryAccountInfo()
-            .hosted_domain);
+    identity::IdentityManager* identity_manager =
+        IdentityManagerFactory::GetForBrowserState(browserState);
+    base::Optional<AccountInfo> primary_account_info =
+        identity_manager->FindExtendedAccountInfoForAccount(
+            identity_manager->GetPrimaryAccountInfo());
+    DCHECK(primary_account_info);
+    NSString* hostedDomain =
+        base::SysUTF8ToNSString(primary_account_info->hosted_domain);
     [self promptSwitchFromManagedEmail:lastSignedInEmail
                       withHostedDomain:hostedDomain
                                toEmail:[identity userEmail]
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index ee1083b..ddac71d 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -3081,37 +3081,34 @@
 
 - (web::WebState*)webState:(web::WebState*)webState
          openURLWithParams:(const web::WebState::OpenURLParams&)params {
+  web::NavigationManager::WebLoadParams loadParams(params.url);
+  loadParams.referrer = params.referrer;
+  loadParams.transition_type = params.transition;
+  loadParams.is_renderer_initiated = params.is_renderer_initiated;
+  loadParams.virtual_url = params.virtual_url;
   switch (params.disposition) {
     case WindowOpenDisposition::NEW_FOREGROUND_TAB:
     case WindowOpenDisposition::NEW_BACKGROUND_TAB: {
       Tab* tab = [[self tabModel]
-          insertTabWithURL:params.url
-                  referrer:params.referrer
-                transition:params.transition
-                    opener:LegacyTabHelper::GetTabForWebState(webState)
-               openedByDOM:NO
-                   atIndex:TabModelConstants::kTabPositionAutomatically
-              inBackground:(params.disposition ==
-                            WindowOpenDisposition::NEW_BACKGROUND_TAB)];
+          insertTabWithLoadParams:loadParams
+                           opener:LegacyTabHelper::GetTabForWebState(webState)
+                      openedByDOM:NO
+                          atIndex:TabModelConstants::kTabPositionAutomatically
+                     inBackground:(params.disposition ==
+                                   WindowOpenDisposition::NEW_BACKGROUND_TAB)];
       return tab.webState;
     }
     case WindowOpenDisposition::CURRENT_TAB: {
-      web::NavigationManager::WebLoadParams loadParams(params.url);
-      loadParams.referrer = params.referrer;
-      loadParams.transition_type = params.transition;
-      loadParams.is_renderer_initiated = params.is_renderer_initiated;
       webState->GetNavigationManager()->LoadURLWithParams(loadParams);
       return webState;
     }
     case WindowOpenDisposition::NEW_POPUP: {
       Tab* tab = [[self tabModel]
-          insertTabWithURL:params.url
-                  referrer:params.referrer
-                transition:params.transition
-                    opener:LegacyTabHelper::GetTabForWebState(webState)
-               openedByDOM:YES
-                   atIndex:TabModelConstants::kTabPositionAutomatically
-              inBackground:NO];
+          insertTabWithLoadParams:loadParams
+                           opener:LegacyTabHelper::GetTabForWebState(webState)
+                      openedByDOM:YES
+                          atIndex:TabModelConstants::kTabPositionAutomatically
+                     inBackground:NO];
       return tab.webState;
     }
     default:
diff --git a/ios/chrome/browser/ui/infobars/BUILD.gn b/ios/chrome/browser/ui/infobars/BUILD.gn
index 4bf6415..5c4fd73 100644
--- a/ios/chrome/browser/ui/infobars/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/BUILD.gn
@@ -23,7 +23,6 @@
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
     "//ios/chrome/browser/ui/fullscreen",
     "//ios/chrome/browser/ui/infobars/coordinators",
-    "//ios/chrome/browser/ui/infobars/presentation",
     "//ios/chrome/browser/ui/settings/sync/utils",
     "//ios/chrome/browser/ui/signin_interaction/public",
     "//ios/chrome/browser/ui/translate",
diff --git a/ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h b/ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h
index 78603eb8..907ffb2 100644
--- a/ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h
+++ b/ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h
@@ -16,8 +16,8 @@
 // Asks the delegate to dismiss the InfobarBanner.
 - (void)dismissInfobarBanner:(UIViewController*)sender;
 
-// Asks the delegate to to present the InfobarModal for this InfobarBanner.
-- (void)presentInfobarModal;
+// Asks the delegate to present the InfobarModal for this InfobarBanner.
+- (void)presentInfobarModalFromBanner;
 
 @end
 
diff --git a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
index 19a3a47..3a8ae83 100644
--- a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
+++ b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
@@ -200,7 +200,7 @@
       gesture.state == UIGestureRecognizerStateCancelled) {
     if (self.view.center.y > self.originalCenter.y) {
       self.view.center = self.originalCenter;
-      [self.delegate presentInfobarModal];
+      [self.delegate presentInfobarModalFromBanner];
     } else {
       [self.delegate dismissInfobarBanner:self];
     }
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_confirm_coordinator.mm b/ios/chrome/browser/ui/infobars/coordinators/infobar_confirm_coordinator.mm
index e2203ce..e6f97cab 100644
--- a/ios/chrome/browser/ui/infobars/coordinators/infobar_confirm_coordinator.mm
+++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_confirm_coordinator.mm
@@ -11,29 +11,34 @@
 #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.h"
 #import "ios/chrome/browser/ui/infobars/modals/infobar_modal_delegate.h"
 #import "ios/chrome/browser/ui/infobars/modals/infobar_modal_view_controller.h"
-#import "ios/chrome/browser/ui/infobars/presentation/infobar_expand_banner_animator.h"
-#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.h"
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h"
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
 @interface InfobarConfirmCoordinator () <InfobarBannerDelegate,
-                                         InfobarModalDelegate,
-                                         UIViewControllerTransitioningDelegate>
+                                         InfobarModalDelegate>
 
 // Delegate that holds the Infobar information and actions.
 @property(nonatomic, readonly) ConfirmInfoBarDelegate* confirmInfobarDelegate;
 // InfobarBannerViewController owned by this Coordinator.
 @property(nonatomic, strong) InfobarBannerViewController* bannerViewController;
+// InfobarModalViewController owned by this Coordinator.
+@property(nonatomic, strong) InfobarModalViewController* modalViewController;
 
 @end
 
 @implementation InfobarConfirmCoordinator
 // Property defined in InfobarCoordinating.
 @synthesize bannerViewController = _bannerViewController;
+// Property defined in InfobarCoordinating.
+@synthesize bannerTransitionDriver = _bannerTransitionDriver;
 // Property defined in InfobarUIDelegate.
 @synthesize delegate = _delegate;
+// Property defined in InfobarCoordinating.
+@synthesize modalTransitionDriver = _modalTransitionDriver;
 // Property defined in InfobarUIDelegate.
 @synthesize presented = _presented;
 // Property defined in InfobarCoordinating.
@@ -63,23 +68,40 @@
 - (void)stop {
   if (self.started) {
     self.started = NO;
-    [self.bannerViewController.presentingViewController
-        dismissViewControllerAnimated:YES
-                           completion:nil];
+    // RemoveInfoBar() will delete the InfobarIOS that owns this Coordinator
+    // from memory.
+    self.delegate->RemoveInfoBar();
   }
 }
 
 #pragma mark - InfobarUIDelegate
 
 - (void)removeView {
-  [self stop];
+  [self dismissInfobarBanner:self.bannerViewController];
 }
 
 - (void)detachView {
+  [self dismissInfobarBanner:self.bannerViewController];
   [self stop];
-  // RemoveInfoBar() will delete the InfobarIOS that owns this Coordinator
-  // from memory.
-  self.delegate->RemoveInfoBar();
+}
+
+#pragma mark - InfobarCoordinating
+
+- (void)presentInfobarModalFrom:(UIViewController*)baseViewController {
+  self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
+      initWithTransitionMode:InfobarModalTransitionBase];
+  [self presentInfobarModalFrom:baseViewController
+                         driver:self.modalTransitionDriver];
+}
+
+- (void)presentInfobarBannerFrom:(UIViewController*)baseViewController {
+  [self.bannerViewController
+      setModalPresentationStyle:UIModalPresentationCustom];
+  self.bannerTransitionDriver = [[InfobarBannerTransitionDriver alloc] init];
+  self.bannerViewController.transitioningDelegate = self.bannerTransitionDriver;
+  [baseViewController presentViewController:self.bannerViewController
+                                   animated:YES
+                                 completion:nil];
 }
 
 #pragma mark - InfobarBannerDelegate
@@ -90,61 +112,49 @@
 }
 
 - (void)dismissInfobarBanner:(id)sender {
-  [self stop];
+  [self.bannerViewController.presentingViewController
+      dismissViewControllerAnimated:YES
+                         completion:^{
+                           self.bannerTransitionDriver = nil;
+                         }];
 }
 
-- (void)presentInfobarModal {
-  InfobarModalViewController* expandedViewController =
-      [[InfobarModalViewController alloc] initWithModalDelegate:self];
-  expandedViewController.transitioningDelegate = self;
-  [expandedViewController setModalPresentationStyle:UIModalPresentationCustom];
-  [self.bannerViewController presentViewController:expandedViewController
-                                          animated:YES
-                                        completion:nil];
+- (void)presentInfobarModalFromBanner {
+  self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
+      initWithTransitionMode:InfobarModalTransitionBanner];
+  [self presentInfobarModalFrom:self.bannerViewController
+                         driver:self.modalTransitionDriver];
 }
 
 #pragma mark - InfobarModalDelegate
 
 - (void)dismissInfobarModal:(UIViewController*)sender {
-  [self.bannerViewController dismissViewControllerAnimated:YES
-                                                completion:^{
-                                                  [self stop];
-                                                }];
+  [self.modalViewController.presentingViewController
+      dismissViewControllerAnimated:YES
+                         completion:^{
+                           // If the Modal was presented by the
+                           // BannerViewController, dismiss it too.
+                           if (self.modalTransitionDriver.transitionMode ==
+                               InfobarModalTransitionBanner) {
+                             [self dismissInfobarBanner:
+                                       self.bannerViewController];
+                           }
+                           self.modalTransitionDriver = nil;
+                         }];
 }
 
-// TODO(crbug.com/1372916): Create a Transitioning objects that can be shared
-// with all Infobar Coordinators.
-#pragma mark - UIViewControllerTransitioningDelegate
+#pragma mark - Private
 
-- (UIPresentationController*)
-    presentationControllerForPresentedViewController:
-        (UIViewController*)presented
-                            presentingViewController:
-                                (UIViewController*)presenting
-                                sourceViewController:(UIViewController*)source {
-  InfobarModalPresentationController* presentationController =
-      [[InfobarModalPresentationController alloc]
-          initWithPresentedViewController:presented
-                 presentingViewController:presenting];
-  return presentationController;
-}
-
-- (id<UIViewControllerAnimatedTransitioning>)
-    animationControllerForPresentedController:(UIViewController*)presented
-                         presentingController:(UIViewController*)presenting
-                             sourceController:(UIViewController*)source {
-  InfobarExpandBannerAnimator* animator =
-      [[InfobarExpandBannerAnimator alloc] init];
-  animator.presenting = YES;
-  return animator;
-}
-
-- (id<UIViewControllerAnimatedTransitioning>)
-    animationControllerForDismissedController:(UIViewController*)dismissed {
-  InfobarExpandBannerAnimator* animator =
-      [[InfobarExpandBannerAnimator alloc] init];
-  animator.presenting = NO;
-  return animator;
+- (void)presentInfobarModalFrom:(UIViewController*)presentingViewController
+                         driver:(InfobarModalTransitionDriver*)driver {
+  self.modalViewController =
+      [[InfobarModalViewController alloc] initWithModalDelegate:self];
+  self.modalViewController.transitioningDelegate = driver;
+  [self.modalViewController
+      setModalPresentationStyle:UIModalPresentationCustom];
+  [presentingViewController presentViewController:self.modalViewController
+                                         animated:YES
+                                       completion:nil];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinating.h b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinating.h
index a4758f7d..0348b31 100644
--- a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinating.h
+++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinating.h
@@ -5,15 +5,38 @@
 #ifndef IOS_CHROME_BROWSER_UI_INFOBARS_COORDINATORS_INFOBAR_COORDINATING_H_
 #define IOS_CHROME_BROWSER_UI_INFOBARS_COORDINATORS_INFOBAR_COORDINATING_H_
 
+@class InfobarBannerTransitionDriver;
+@class InfobarModalTransitionDriver;
+
 // InfobarCoordinating defines common methods for all Infobar Coordinators.
 @protocol InfobarCoordinating
 
 // YES if the Coordinator has been started.
 @property(nonatomic, assign) BOOL started;
 
-// The Coordinator BannerViewController.
+// The transition delegate used by the Coordinator to present the InfobarBanner.
+// nil if no Banner is being presented.
+@property(nonatomic, strong)
+    InfobarBannerTransitionDriver* bannerTransitionDriver;
+
+// The transition delegate used by the Coordinator to present the InfobarModal.
+// nil if no Modal is being presented.
+@property(nonatomic, strong)
+    InfobarModalTransitionDriver* modalTransitionDriver;
+
+// The Coordinator's BannerViewController, can be nil.
 - (UIViewController*)bannerViewController;
 
+// Present the InfobarBanner for this Infobar using |baseViewController|.
+// TODO(crbug.com/927064): Once we create the coordinators in the UI Hierarchy
+// baseViewController will be set on init.
+- (void)presentInfobarBannerFrom:(UIViewController*)baseViewController;
+
+// Present the InfobarModal for this Infobar using |baseViewController|.
+// TODO(crbug.com/927064): Once we create the coordinators in the UI Hierarchy
+// baseViewController will be set on init.
+- (void)presentInfobarModalFrom:(UIViewController*)baseViewController;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_INFOBARS_COORDINATORS_INFOBAR_COORDINATING_H_
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.mm b/ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.mm
index 92f15f0..11fda74 100644
--- a/ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.mm
+++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.mm
@@ -11,30 +11,35 @@
 #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.h"
 #import "ios/chrome/browser/ui/infobars/modals/infobar_modal_delegate.h"
 #import "ios/chrome/browser/ui/infobars/modals/infobar_modal_view_controller.h"
-#import "ios/chrome/browser/ui/infobars/presentation/infobar_expand_banner_animator.h"
-#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.h"
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h"
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
 @interface InfobarPasswordCoordinator () <InfobarBannerDelegate,
-                                          InfobarModalDelegate,
-                                          UIViewControllerTransitioningDelegate>
+                                          InfobarModalDelegate>
 
 // Delegate that holds the Infobar information and actions.
 @property(nonatomic, readonly)
     IOSChromePasswordManagerInfoBarDelegate* passwordInfoBarDelegate;
 // InfobarBannerViewController owned by this Coordinator.
 @property(nonatomic, strong) InfobarBannerViewController* bannerViewController;
+// InfobarModalViewController owned by this Coordinator.
+@property(nonatomic, strong) InfobarModalViewController* modalViewController;
 
 @end
 
 @implementation InfobarPasswordCoordinator
 // Property defined in InfobarCoordinating.
 @synthesize bannerViewController = _bannerViewController;
+// Property defined in InfobarCoordinating.
+@synthesize bannerTransitionDriver = _bannerTransitionDriver;
 // Property defined in InfobarUIDelegate.
 @synthesize delegate = _delegate;
+// Property defined in InfobarCoordinating.
+@synthesize modalTransitionDriver = _modalTransitionDriver;
 // Property defined in InfobarUIDelegate.
 @synthesize presented = _presented;
 // Property defined in InfobarCoordinating.
@@ -66,23 +71,40 @@
 - (void)stop {
   if (self.started) {
     self.started = NO;
-    [self.bannerViewController.presentingViewController
-        dismissViewControllerAnimated:YES
-                           completion:nil];
+    // RemoveInfoBar() will delete the InfobarIOS that owns this Coordinator
+    // from memory.
+    self.delegate->RemoveInfoBar();
   }
 }
 
 #pragma mark - InfobarUIDelegate
 
 - (void)removeView {
-  [self stop];
+  [self dismissInfobarBanner:self.bannerViewController];
 }
 
 - (void)detachView {
+  [self dismissInfobarBanner:self.bannerViewController];
   [self stop];
-  // RemoveInfoBar() will delete the InfobarIOS that owns this Coordinator
-  // from memory.
-  self.delegate->RemoveInfoBar();
+}
+
+#pragma mark - InfobarCoordinating
+
+- (void)presentInfobarModalFrom:(UIViewController*)baseViewController {
+  self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
+      initWithTransitionMode:InfobarModalTransitionBase];
+  [self presentInfobarModalFrom:baseViewController
+                         driver:self.modalTransitionDriver];
+}
+
+- (void)presentInfobarBannerFrom:(UIViewController*)baseViewController {
+  [self.bannerViewController
+      setModalPresentationStyle:UIModalPresentationCustom];
+  self.bannerTransitionDriver = [[InfobarBannerTransitionDriver alloc] init];
+  self.bannerViewController.transitioningDelegate = self.bannerTransitionDriver;
+  [baseViewController presentViewController:self.bannerViewController
+                                   animated:YES
+                                 completion:nil];
 }
 
 #pragma mark - InfobarBannerDelegate
@@ -93,61 +115,49 @@
 }
 
 - (void)dismissInfobarBanner:(id)sender {
-  [self stop];
+  [self.bannerViewController.presentingViewController
+      dismissViewControllerAnimated:YES
+                         completion:^{
+                           self.bannerTransitionDriver = nil;
+                         }];
 }
 
-- (void)presentInfobarModal {
-  InfobarModalViewController* expandedViewController =
-      [[InfobarModalViewController alloc] initWithModalDelegate:self];
-  expandedViewController.transitioningDelegate = self;
-  [expandedViewController setModalPresentationStyle:UIModalPresentationCustom];
-  [self.bannerViewController presentViewController:expandedViewController
-                                          animated:YES
-                                        completion:nil];
+- (void)presentInfobarModalFromBanner {
+  self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
+      initWithTransitionMode:InfobarModalTransitionBanner];
+  [self presentInfobarModalFrom:self.bannerViewController
+                         driver:self.modalTransitionDriver];
 }
 
 #pragma mark - InfobarModalDelegate
 
 - (void)dismissInfobarModal:(UIViewController*)sender {
-  [self.bannerViewController dismissViewControllerAnimated:YES
-                                                completion:^{
-                                                  [self stop];
-                                                }];
+  [self.modalViewController.presentingViewController
+      dismissViewControllerAnimated:YES
+                         completion:^{
+                           // If the Modal was presented by the
+                           // BannerViewController, dismiss it too.
+                           if (self.modalTransitionDriver.transitionMode ==
+                               InfobarModalTransitionBanner) {
+                             [self dismissInfobarBanner:
+                                       self.bannerViewController];
+                           }
+                           self.modalTransitionDriver = nil;
+                         }];
 }
 
-// TODO(crbug.com/911864): Create a Transitioning object that can be shared
-// with all Infobar Coordinators.
-#pragma mark - UIViewControllerTransitioningDelegate
+#pragma mark - Private
 
-- (UIPresentationController*)
-    presentationControllerForPresentedViewController:
-        (UIViewController*)presented
-                            presentingViewController:
-                                (UIViewController*)presenting
-                                sourceViewController:(UIViewController*)source {
-  InfobarModalPresentationController* presentationController =
-      [[InfobarModalPresentationController alloc]
-          initWithPresentedViewController:presented
-                 presentingViewController:presenting];
-  return presentationController;
-}
-
-- (id<UIViewControllerAnimatedTransitioning>)
-    animationControllerForPresentedController:(UIViewController*)presented
-                         presentingController:(UIViewController*)presenting
-                             sourceController:(UIViewController*)source {
-  InfobarExpandBannerAnimator* animator =
-      [[InfobarExpandBannerAnimator alloc] init];
-  animator.presenting = YES;
-  return animator;
-}
-
-- (id<UIViewControllerAnimatedTransitioning>)
-    animationControllerForDismissedController:(UIViewController*)dismissed {
-  InfobarExpandBannerAnimator* animator =
-      [[InfobarExpandBannerAnimator alloc] init];
-  animator.presenting = NO;
-  return animator;
+- (void)presentInfobarModalFrom:(UIViewController*)presentingViewController
+                         driver:(InfobarModalTransitionDriver*)driver {
+  self.modalViewController =
+      [[InfobarModalViewController alloc] initWithModalDelegate:self];
+  self.modalViewController.transitioningDelegate = driver;
+  [self.modalViewController
+      setModalPresentationStyle:UIModalPresentationCustom];
+  [presentingViewController presentViewController:self.modalViewController
+                                         animated:YES
+                                       completion:nil];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm
index 61bae63..9c72f16 100644
--- a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm
+++ b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm
@@ -17,8 +17,6 @@
 #import "ios/chrome/browser/ui/infobars/infobar_feature.h"
 #import "ios/chrome/browser/ui/infobars/infobar_positioner.h"
 #include "ios/chrome/browser/ui/infobars/legacy_infobar_container_view_controller.h"
-#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_animator.h"
-#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_presentation_controller.h"
 #import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h"
 #include "ios/chrome/browser/upgrade/upgrade_center.h"
 
@@ -28,7 +26,6 @@
 
 @interface InfobarContainerCoordinator () <
     InfobarContainerConsumer,
-    UIViewControllerTransitioningDelegate,
     SigninPresenter>
 
 @property(nonatomic, assign) TabModel* tabModel;
@@ -148,16 +145,11 @@
   ChromeCoordinator<InfobarCoordinating>* infobarCoordinator =
       static_cast<ChromeCoordinator<InfobarCoordinating>*>(infoBarDelegate);
 
-  // Present the InfobarCoordinator BannerViewController.
+  // Present the InfobarBanner, and set the Coordinator and View hierarchies.
   [infobarCoordinator start];
+  [infobarCoordinator presentInfobarBannerFrom:self.baseViewController];
   self.infobarViewController = [infobarCoordinator bannerViewController];
-  [infobarCoordinator bannerViewController].transitioningDelegate = self;
-  [[infobarCoordinator bannerViewController]
-      setModalPresentationStyle:UIModalPresentationCustom];
-  [self.baseViewController
-      presentViewController:[infobarCoordinator bannerViewController]
-                   animated:YES
-                 completion:nil];
+  [self.childCoordinators addObject:infobarCoordinator];
 }
 
 - (void)setUserInteractionEnabled:(BOOL)enabled {
@@ -173,38 +165,15 @@
 #pragma mark - InfobarCommands
 
 - (void)displayModalInfobar {
-  // TODO(crbug.com/911864): To be implemented.
-}
+  // Dismiss the InfobarBanner if being presented.
+  if (self.baseViewController.presentedViewController) {
+    [self.baseViewController dismissViewControllerAnimated:NO completion:nil];
+  }
 
-#pragma mark - UIViewControllerTransitioningDelegate
-
-- (UIPresentationController*)
-    presentationControllerForPresentedViewController:
-        (UIViewController*)presented
-                            presentingViewController:
-                                (UIViewController*)presenting
-                                sourceViewController:(UIViewController*)source {
-  InfobarBannerPresentationController* presentationController =
-      [[InfobarBannerPresentationController alloc]
-          initWithPresentedViewController:presented
-                 presentingViewController:presenting];
-  return presentationController;
-}
-
-- (id<UIViewControllerAnimatedTransitioning>)
-    animationControllerForPresentedController:(UIViewController*)presented
-                         presentingController:(UIViewController*)presenting
-                             sourceController:(UIViewController*)source {
-  InfobarBannerAnimator* animator = [[InfobarBannerAnimator alloc] init];
-  animator.presenting = YES;
-  return animator;
-}
-
-- (id<UIViewControllerAnimatedTransitioning>)
-    animationControllerForDismissedController:(UIViewController*)dismissed {
-  InfobarBannerAnimator* animator = [[InfobarBannerAnimator alloc] init];
-  animator.presenting = NO;
-  return animator;
+  ChromeCoordinator<InfobarCoordinating>* infobarCoordinator =
+      static_cast<ChromeCoordinator<InfobarCoordinating>*>(
+          self.activeChildCoordinator);
+  [infobarCoordinator presentInfobarModalFrom:self.baseViewController];
 }
 
 #pragma mark - SigninPresenter
diff --git a/ios/chrome/browser/ui/infobars/presentation/BUILD.gn b/ios/chrome/browser/ui/infobars/presentation/BUILD.gn
index 4a712d6..3dd5f58 100644
--- a/ios/chrome/browser/ui/infobars/presentation/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/presentation/BUILD.gn
@@ -9,10 +9,14 @@
     "infobar_banner_animator.mm",
     "infobar_banner_presentation_controller.h",
     "infobar_banner_presentation_controller.mm",
+    "infobar_banner_transition_driver.h",
+    "infobar_banner_transition_driver.mm",
     "infobar_expand_banner_animator.h",
     "infobar_expand_banner_animator.mm",
     "infobar_modal_presentation_controller.h",
     "infobar_modal_presentation_controller.mm",
+    "infobar_modal_transition_driver.h",
+    "infobar_modal_transition_driver.mm",
   ]
   deps = [
     "//base",
diff --git a/ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h b/ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h
new file mode 100644
index 0000000..b9891a2
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_BANNER_TRANSITION_DRIVER_H_
+#define IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_BANNER_TRANSITION_DRIVER_H_
+
+#import <UIKit/UIKit.h>
+
+// The transition delegate used to present an InfobarBanner.
+@interface InfobarBannerTransitionDriver
+    : NSObject <UIViewControllerTransitioningDelegate>
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_BANNER_TRANSITION_DRIVER_H_
diff --git a/ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.mm b/ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.mm
new file mode 100644
index 0000000..c8abb5a
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.mm
@@ -0,0 +1,47 @@
+// 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.
+
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h"
+
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_animator.h"
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_presentation_controller.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation InfobarBannerTransitionDriver
+
+#pragma mark - UIViewControllerTransitioningDelegate
+
+- (UIPresentationController*)
+    presentationControllerForPresentedViewController:
+        (UIViewController*)presented
+                            presentingViewController:
+                                (UIViewController*)presenting
+                                sourceViewController:(UIViewController*)source {
+  InfobarBannerPresentationController* presentationController =
+      [[InfobarBannerPresentationController alloc]
+          initWithPresentedViewController:presented
+                 presentingViewController:presenting];
+  return presentationController;
+}
+
+- (id<UIViewControllerAnimatedTransitioning>)
+    animationControllerForPresentedController:(UIViewController*)presented
+                         presentingController:(UIViewController*)presenting
+                             sourceController:(UIViewController*)source {
+  InfobarBannerAnimator* animator = [[InfobarBannerAnimator alloc] init];
+  animator.presenting = YES;
+  return animator;
+}
+
+- (id<UIViewControllerAnimatedTransitioning>)
+    animationControllerForDismissedController:(UIViewController*)dismissed {
+  InfobarBannerAnimator* animator = [[InfobarBannerAnimator alloc] init];
+  animator.presenting = NO;
+  return animator;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h b/ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h
new file mode 100644
index 0000000..c41e067
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h
@@ -0,0 +1,30 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_MODAL_TRANSITION_DRIVER_H_
+#define IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_MODAL_TRANSITION_DRIVER_H_
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, InfobarModalTransition) {
+  // InfobarModal will be presented from a base ViewController.
+  InfobarModalTransitionBase,
+  // InfobarModal will be presented by an InfobarBanner ViewController.
+  InfobarModalTransitionBanner,
+};
+
+// The transition delegate used to present an InfobarModal.
+@interface InfobarModalTransitionDriver
+    : NSObject <UIViewControllerTransitioningDelegate>
+
+- (instancetype)initWithTransitionMode:(InfobarModalTransition)transitionMode
+    NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+
+// The InfobarModalTransition mode being used for this Transition driver.
+@property(nonatomic, assign, readonly) InfobarModalTransition transitionMode;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_MODAL_TRANSITION_DRIVER_H_
diff --git a/ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.mm b/ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.mm
new file mode 100644
index 0000000..7c84acf
--- /dev/null
+++ b/ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.mm
@@ -0,0 +1,69 @@
+// 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.
+
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h"
+
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_expand_banner_animator.h"
+#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation InfobarModalTransitionDriver
+
+- (instancetype)initWithTransitionMode:(InfobarModalTransition)transitionMode {
+  self = [super init];
+  if (self) {
+    _transitionMode = transitionMode;
+  }
+  return self;
+}
+
+#pragma mark - UIViewControllerTransitioningDelegate
+
+- (UIPresentationController*)
+    presentationControllerForPresentedViewController:
+        (UIViewController*)presented
+                            presentingViewController:
+                                (UIViewController*)presenting
+                                sourceViewController:(UIViewController*)source {
+  InfobarModalPresentationController* presentationController =
+      [[InfobarModalPresentationController alloc]
+          initWithPresentedViewController:presented
+                 presentingViewController:presenting];
+  return presentationController;
+}
+
+- (id<UIViewControllerAnimatedTransitioning>)
+    animationControllerForPresentedController:(UIViewController*)presented
+                         presentingController:(UIViewController*)presenting
+                             sourceController:(UIViewController*)source {
+  switch (self.transitionMode) {
+    case InfobarModalTransitionBase:
+      return nil;
+
+    case InfobarModalTransitionBanner:
+      InfobarExpandBannerAnimator* animator =
+          [[InfobarExpandBannerAnimator alloc] init];
+      animator.presenting = YES;
+      return animator;
+  }
+}
+
+- (id<UIViewControllerAnimatedTransitioning>)
+    animationControllerForDismissedController:(UIViewController*)dismissed {
+  switch (self.transitionMode) {
+    case InfobarModalTransitionBase:
+      return nil;
+
+    case InfobarModalTransitionBanner:
+      InfobarExpandBannerAnimator* animator =
+          [[InfobarExpandBannerAnimator alloc] init];
+      animator.presenting = NO;
+      return animator;
+  }
+}
+
+@end
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
index 8e451bc8..7ad31af4 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
@@ -117,14 +117,14 @@
     self.popupViewController.shortcutsEnabled = YES;
   }
 
-  [self.mediator.presenter updateHeightAndAnimateAppearanceIfNecessary];
+  [self.mediator.presenter updateHeight];
   self.mediator.open = YES;
 }
 
 - (void)closePopup {
   self.mediator.open = NO;
   self.popupViewController.shortcutsEnabled = NO;
-  [self.mediator.presenter animateCollapse];
+  [self.mediator.presenter collapse];
 }
 
 #pragma mark - Property accessor
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm
index 9a013a5..bc2df1a 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_mediator.mm
@@ -64,7 +64,7 @@
   BOOL isNTP = IsVisibleURLNewTabPage(self.webStateList->GetActiveWebState());
 
   if (!self.hasResults && (!shortcutsEnabled || isNTP)) {
-    [self.presenter animateCollapse];
+    [self.presenter collapse];
   }
 }
 
@@ -99,7 +99,7 @@
   self.open = !result.empty();
 
   if (self.open) {
-    [self.presenter updateHeightAndAnimateAppearanceIfNecessary];
+    [self.presenter updateHeight];
   }
 }
 
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h
index bb89493..c6e80701 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h
@@ -31,11 +31,10 @@
 @interface OmniboxPopupPresenter : NSObject
 
 // Updates appearance depending on the content size of the presented view
-// controller by changing the visible height of the popup. When the popup was
-// not previously shown, it will appear with "expansion" animation.
-- (void)updateHeightAndAnimateAppearanceIfNecessary;
-// Call this to hide the popup with animation.
-- (void)animateCollapse;
+// controller by changing the visible height of the popup.
+- (void)updateHeight;
+// Hides the popup.
+- (void)collapse;
 
 - (instancetype)initWithPopupPresenterDelegate:
                     (id<OmniboxPopupPresenterDelegate>)presenterDelegate
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
index 9da5fa7..f5152b3 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
@@ -17,8 +17,6 @@
 #endif
 
 namespace {
-const CGFloat kExpandAnimationDuration = 0.1;
-const CGFloat kCollapseAnimationDuration = 0.05;
 const CGFloat kVerticalOffset = 6;
 }  // namespace
 
@@ -29,7 +27,6 @@
 @property(nonatomic, weak) id<OmniboxPopupPresenterDelegate> delegate;
 @property(nonatomic, weak) UIViewController* viewController;
 @property(nonatomic, strong) UIView* popupContainerView;
-@property(nonatomic) UIViewPropertyAnimator* animator;
 @end
 
 @implementation OmniboxPopupPresenter
@@ -69,7 +66,7 @@
   return self;
 }
 
-- (void)updateHeightAndAnimateAppearanceIfNecessary {
+- (void)updateHeight {
   UIView* popup = self.popupContainerView;
   if (!popup.superview) {
     UIViewController* parentVC =
@@ -86,43 +83,18 @@
   }
 
   [self.delegate popupDidOpenForPresenter:self];
-
-  [self.animator stopAnimation:YES];
-
-  if (popup.bounds.size.height == 0) {
-    // Animate if it expanding.
-    self.animator = [[UIViewPropertyAnimator alloc]
-        initWithDuration:kExpandAnimationDuration
-                   curve:UIViewAnimationCurveEaseInOut
-              animations:^{
-                [[popup superview] layoutIfNeeded];
-              }];
-    [self.animator startAnimation];
-  }
 }
 
-- (void)animateCollapse {
-  [self.delegate popupDidCloseForPresenter:self];
-  UIView* retainedPopupView = self.popupContainerView;
-  UIViewController* retainedViewController = self.viewController;
+- (void)collapse {
   if (!IsIPadIdiom()) {
     self.bottomConstraint.active = NO;
   }
 
-  [self.animator stopAnimation:YES];
+  [self.viewController willMoveToParentViewController:nil];
+  [self.popupContainerView removeFromSuperview];
+  [self.viewController removeFromParentViewController];
 
-  self.animator = [[UIViewPropertyAnimator alloc]
-      initWithDuration:kCollapseAnimationDuration
-                 curve:UIViewAnimationCurveEaseInOut
-            animations:^{
-              [[self.popupContainerView superview] layoutIfNeeded];
-            }];
-  [self.animator addCompletion:^(UIViewAnimatingPosition) {
-    [retainedViewController willMoveToParentViewController:nil];
-    [retainedPopupView removeFromSuperview];
-    [retainedViewController removeFromParentViewController];
-  }];
-  [self.animator startAnimation];
+  [self.delegate popupDidCloseForPresenter:self];
 }
 
 #pragma mark - Private
diff --git a/ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.mm b/ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.mm
index 92721cb5..c249ff8 100644
--- a/ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.mm
+++ b/ios/chrome/browser/ui/page_info/page_info_legacy_coordinator.mm
@@ -95,13 +95,6 @@
   if (!navItem)
     return;
 
-  // Don't show if the page is native except for offline pages (to show the
-  // offline page info).
-  if (web::GetWebClient()->IsAppSpecificURL(navItem->GetURL()) &&
-      !reading_list::IsOfflineURL(navItem->GetURL())) {
-    return;
-  }
-
   // Don't show the bubble twice (this can happen when tapping very quickly in
   // accessibility mode).
   if (self.pageInfoViewController)
diff --git a/ios/chrome/browser/ui/page_info/page_info_model.cc b/ios/chrome/browser/ui/page_info/page_info_model.cc
index f1c79e17..5cbe6d1 100644
--- a/ios/chrome/browser/ui/page_info/page_info_model.cc
+++ b/ios/chrome/browser/ui/page_info/page_info_model.cc
@@ -52,8 +52,10 @@
   }
 
   if (url.SchemeIs(kChromeUIScheme)) {
+    base::string16 spec(base::UTF8ToUTF16(url.spec()));
+
     sections_.push_back(
-        SectionInfo(ICON_STATE_INTERNAL_PAGE, base::string16(),
+        SectionInfo(ICON_STATE_INTERNAL_PAGE, spec,
                     l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE),
                     SECTION_INFO_INTERNAL_PAGE, BUTTON_NONE));
     return;
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
index 3fd9d0d7..669762cc 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -516,8 +516,7 @@
   if (URL.SchemeIs(kChromeUIScheme) && URL.host() == kChromeUIOfflineHost) {
     return YES;
   }
-  return navItem->GetVirtualURL().is_valid() &&
-         !web::GetWebClient()->IsAppSpecificURL(navItem->GetVirtualURL());
+  return navItem->GetVirtualURL().is_valid();
 }
 
 // Whether the current page is a web page.
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
index f6a10ec..b363eaa 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
@@ -272,5 +272,5 @@
   web_state_->OnNavigationFinished(&context);
 
   EXPECT_TRUE(HasItem(consumer, kToolsMenuNewTabId, /*enabled=*/YES));
-  EXPECT_TRUE(HasItem(consumer, kToolsMenuSiteInformation, /*enabled=*/NO));
+  EXPECT_TRUE(HasItem(consumer, kToolsMenuSiteInformation, /*enabled=*/YES));
 }
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index 7d1e862..6ffee46 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -1037,6 +1037,8 @@
 // in the detail text of the cell.
 - (void)updateGoogleServicesItem:(TableViewImageItem*)googleServicesItem {
   googleServicesItem.detailTextColor = nil;
+  syncer::SyncService* syncService =
+      ProfileSyncServiceFactory::GetForBrowserState(_browserState);
   SyncSetupService* syncSetupService =
       SyncSetupServiceFactory::GetForBrowserState(_browserState);
   AuthenticationService* authService =
@@ -1046,6 +1048,12 @@
     googleServicesItem.detailText = nil;
     googleServicesItem.image =
         [UIImage imageNamed:kSyncAndGoogleServicesImageName];
+  } else if (syncService->GetDisableReasons() ==
+             syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY) {
+    googleServicesItem.detailText = l10n_util::GetNSString(
+        IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_DISABLBED_BY_ADMINISTRATOR_STATUS);
+    googleServicesItem.image =
+        [UIImage imageNamed:kSyncAndGoogleServicesSyncOffImageName];
   } else if (!syncSetupService->HasFinishedInitialSetup()) {
     googleServicesItem.detailText =
         l10n_util::GetNSString(IDS_IOS_SYNC_SETUP_IN_PROGRESS);
diff --git a/ios/showcase/BUILD.gn b/ios/showcase/BUILD.gn
index 88fa4d6..9306500 100644
--- a/ios/showcase/BUILD.gn
+++ b/ios/showcase/BUILD.gn
@@ -24,6 +24,7 @@
   deps = [
     "//ios/showcase/bubble",
     "//ios/showcase/content_suggestions",
+    "//ios/showcase/omnibox_popup",
     "//ios/showcase/payments",
     "//ios/showcase/recent_tabs",
     "//ios/showcase/settings",
diff --git a/ios/showcase/core/showcase_model.mm b/ios/showcase/core/showcase_model.mm
index ae27274..fab16d0 100644
--- a/ios/showcase/core/showcase_model.mm
+++ b/ios/showcase/core/showcase_model.mm
@@ -4,8 +4,6 @@
 
 #import "ios/showcase/core/showcase_model.h"
 
-#include "ios/chrome/browser/ui/util/ui_util.h"
-
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
@@ -104,6 +102,11 @@
       showcase::kClassForInstantiationKey : @"SCDarkThemeRecentTabsCoordinator",
       showcase::kUseCaseKey : @"Dark theme recent tabs",
     },
+    @{
+      showcase::kClassForDisplayKey : @"OmniboxPopupViewController",
+      showcase::kClassForInstantiationKey : @"SCOmniboxPopupCoordinator",
+      showcase::kUseCaseKey : @"Omnibox popup table view",
+    },
   ];
 }
 
diff --git a/ios/showcase/omnibox_popup/BUILD.gn b/ios/showcase/omnibox_popup/BUILD.gn
new file mode 100644
index 0000000..cfaf6be
--- /dev/null
+++ b/ios/showcase/omnibox_popup/BUILD.gn
@@ -0,0 +1,23 @@
+# 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.
+
+source_set("omnibox_popup") {
+  sources = [
+    "fake_autocomplete_suggestion.h",
+    "fake_autocomplete_suggestion.mm",
+    "sc_omnibox_popup_container_view_controller.h",
+    "sc_omnibox_popup_container_view_controller.mm",
+    "sc_omnibox_popup_coordinator.h",
+    "sc_omnibox_popup_coordinator.mm",
+  ]
+  deps = [
+    "//ios/chrome/browser/ui/omnibox:omnibox_internal",
+    "//ios/chrome/browser/ui/omnibox/popup",
+    "//ios/chrome/browser/ui/toolbar/buttons",
+    "//ios/chrome/common/ui_util",
+    "//ios/showcase/common",
+  ]
+  libs = [ "UIKit.framework" ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
diff --git a/ios/showcase/omnibox_popup/fake_autocomplete_suggestion.h b/ios/showcase/omnibox_popup/fake_autocomplete_suggestion.h
new file mode 100644
index 0000000..b1a18e2
--- /dev/null
+++ b/ios/showcase/omnibox_popup/fake_autocomplete_suggestion.h
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_SHOWCASE_OMNIBOX_POPUP_FAKE_AUTOCOMPLETE_SUGGESTION_H_
+#define IOS_SHOWCASE_OMNIBOX_POPUP_FAKE_AUTOCOMPLETE_SUGGESTION_H_
+
+#import <UIKit/UIKit.h>
+
+#import "ios/chrome/browser/ui/omnibox/autocomplete_suggestion.h"
+
+@interface FakeAutocompleteSuggestion : NSObject <AutocompleteSuggestion>
+@end
+
+#endif  // IOS_SHOWCASE_OMNIBOX_POPUP_FAKE_AUTOCOMPLETE_SUGGESTION_H_
diff --git a/ios/showcase/omnibox_popup/fake_autocomplete_suggestion.mm b/ios/showcase/omnibox_popup/fake_autocomplete_suggestion.mm
new file mode 100644
index 0000000..4efb80429
--- /dev/null
+++ b/ios/showcase/omnibox_popup/fake_autocomplete_suggestion.mm
@@ -0,0 +1,63 @@
+// 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.
+
+#import "ios/showcase/omnibox_popup/fake_autocomplete_suggestion.h"
+
+#import "url/gurl.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation FakeAutocompleteSuggestion
+
+- (BOOL)supportsDeletion {
+  return NO;
+}
+
+- (BOOL)hasAnswer {
+  return NO;
+}
+
+- (BOOL)isURL {
+  return YES;
+}
+
+- (BOOL)isAppendable {
+  return YES;
+}
+
+- (int)imageID {
+  return 0;
+}
+
+- (UIImage*)suggestionTypeIcon {
+  return nil;
+}
+
+- (BOOL)isTabMatch {
+  return NO;
+}
+
+- (NSAttributedString*)text {
+  return [[NSAttributedString alloc] initWithString:@"Test"];
+}
+
+- (NSAttributedString*)detailText {
+  return [[NSAttributedString alloc] initWithString:@"Test 2"];
+}
+
+- (NSInteger)numberOfLines {
+  return 1;
+}
+
+- (BOOL)hasImage {
+  return NO;
+}
+
+- (GURL)imageURL {
+  return GURL();
+}
+
+@end
diff --git a/ios/showcase/omnibox_popup/sc_omnibox_popup_container_view_controller.h b/ios/showcase/omnibox_popup/sc_omnibox_popup_container_view_controller.h
new file mode 100644
index 0000000..0fd0961
--- /dev/null
+++ b/ios/showcase/omnibox_popup/sc_omnibox_popup_container_view_controller.h
@@ -0,0 +1,21 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_SHOWCASE_OMNIBOX_POPUP_SC_OMNIBOX_POPUP_CONTAINER_VIEW_CONTROLLER_H_
+#define IOS_SHOWCASE_OMNIBOX_POPUP_SC_OMNIBOX_POPUP_CONTAINER_VIEW_CONTROLLER_H_
+
+#include <UIKit/UIKit.h>
+
+@class OmniboxPopupViewController;
+
+@interface SCOmniboxPopupContainerViewController : UIViewController
+
+@property(nonatomic, strong) OmniboxPopupViewController* popupViewController;
+
+- (instancetype)initWithPopupViewController:
+    (OmniboxPopupViewController*)popupViewController;
+
+@end
+
+#endif  // IOS_SHOWCASE_OMNIBOX_POPUP_SC_OMNIBOX_POPUP_CONTAINER_VIEW_CONTROLLER_H_
diff --git a/ios/showcase/omnibox_popup/sc_omnibox_popup_container_view_controller.mm b/ios/showcase/omnibox_popup/sc_omnibox_popup_container_view_controller.mm
new file mode 100644
index 0000000..63c599d
--- /dev/null
+++ b/ios/showcase/omnibox_popup/sc_omnibox_popup_container_view_controller.mm
@@ -0,0 +1,59 @@
+// 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.
+
+#import "ios/showcase/omnibox_popup/sc_omnibox_popup_container_view_controller.h"
+
+#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.h"
+#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h"
+#import "ios/chrome/common/ui_util/constraints_ui_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation SCOmniboxPopupContainerViewController
+
+- (instancetype)initWithPopupViewController:
+    (OmniboxPopupViewController*)popupViewController {
+  self = [super init];
+  if (self) {
+    _popupViewController = popupViewController;
+  }
+  return self;
+}
+
+- (void)viewDidLoad {
+  [super viewDidLoad];
+
+  // Popup uses same colors as the toolbar, so the ToolbarConfiguration is
+  // used to get the style.
+  ToolbarConfiguration* configuration =
+      [[ToolbarConfiguration alloc] initWithStyle:NORMAL];
+
+  UIBlurEffect* effect = [configuration blurEffect];
+  UIView* containerView;
+  if (effect) {
+    UIVisualEffectView* effectView =
+        [[UIVisualEffectView alloc] initWithEffect:effect];
+    [effectView.contentView addSubview:self.popupViewController.view];
+    containerView = effectView;
+  } else {
+    containerView = [[UIView alloc] init];
+    [containerView addSubview:self.popupViewController.view];
+  }
+  containerView.backgroundColor = [configuration blurBackgroundColor];
+  containerView.translatesAutoresizingMaskIntoConstraints = NO;
+  self.popupViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
+  AddSameConstraints(self.popupViewController.view, containerView);
+
+  self.view.backgroundColor = UIColor.whiteColor;
+
+  [self addChildViewController:self.popupViewController];
+  [self.view addSubview:containerView];
+  [self.popupViewController didMoveToParentViewController:self];
+
+  AddSameConstraints(self.view, containerView);
+}
+
+@end
diff --git a/ios/showcase/omnibox_popup/sc_omnibox_popup_coordinator.h b/ios/showcase/omnibox_popup/sc_omnibox_popup_coordinator.h
new file mode 100644
index 0000000..c087c7e
--- /dev/null
+++ b/ios/showcase/omnibox_popup/sc_omnibox_popup_coordinator.h
@@ -0,0 +1,15 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_SHOWCASE_OMNIBOX_POPUP_SC_OMNIBOX_POPUP_COORDINATOR_H_
+#define IOS_SHOWCASE_OMNIBOX_POPUP_SC_OMNIBOX_POPUP_COORDINATOR_H_
+
+#include <UIKit/UIKit.h>
+
+#import "ios/showcase/common/navigation_coordinator.h"
+
+@interface SCOmniboxPopupCoordinator : NSObject <NavigationCoordinator>
+@end
+
+#endif  // IOS_SHOWCASE_OMNIBOX_POPUP_SC_OMNIBOX_POPUP_COORDINATOR_H_
diff --git a/ios/showcase/omnibox_popup/sc_omnibox_popup_coordinator.mm b/ios/showcase/omnibox_popup/sc_omnibox_popup_coordinator.mm
new file mode 100644
index 0000000..0634713
--- /dev/null
+++ b/ios/showcase/omnibox_popup/sc_omnibox_popup_coordinator.mm
@@ -0,0 +1,61 @@
+// 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.
+
+#import "ios/showcase/omnibox_popup/sc_omnibox_popup_coordinator.h"
+
+#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.h"
+#import "ios/showcase/common/coordinator.h"
+#import "ios/showcase/common/protocol_alerter.h"
+#import "ios/showcase/omnibox_popup/fake_autocomplete_suggestion.h"
+#import "ios/showcase/omnibox_popup/sc_omnibox_popup_container_view_controller.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface SCOmniboxPopupCoordinator () <Coordinator>
+
+@property(nonatomic, strong) OmniboxPopupViewController* popupViewController;
+@property(nonatomic, strong)
+    SCOmniboxPopupContainerViewController* containerViewController;
+
+@property(nonatomic, strong) ProtocolAlerter* alerter;
+
+@end
+
+@implementation SCOmniboxPopupCoordinator
+@synthesize baseViewController = _baseViewController;
+
+- (void)start {
+  self.alerter = [[ProtocolAlerter alloc]
+      initWithProtocols:@[ @protocol(AutocompleteResultConsumerDelegate) ]];
+
+  // Ignore didScroll because it's fired all the time.
+  [self.alerter ignoreSelector:@selector(autocompleteResultConsumerDidScroll:)];
+
+  self.popupViewController = [[OmniboxPopupViewController alloc] init];
+  self.popupViewController.delegate =
+      static_cast<id<AutocompleteResultConsumerDelegate>>(self.alerter);
+  [self.popupViewController updateMatches:[self autocompleteSuggestions]
+                            withAnimation:YES];
+
+  self.containerViewController = [[SCOmniboxPopupContainerViewController alloc]
+      initWithPopupViewController:self.popupViewController];
+
+  self.alerter.baseViewController = self.containerViewController;
+
+  [self.baseViewController pushViewController:self.containerViewController
+                                     animated:YES];
+}
+
+#pragma mark - Private
+
+- (NSArray<id<AutocompleteSuggestion>>*)autocompleteSuggestions {
+  return @[
+    [[FakeAutocompleteSuggestion alloc] init],
+    [[FakeAutocompleteSuggestion alloc] init]
+  ];
+}
+
+@end
diff --git a/ios/web/public/web_state/web_state.h b/ios/web/public/web_state/web_state.h
index 5630a64a..665d5a0 100644
--- a/ios/web/public/web_state/web_state.h
+++ b/ios/web/public/web_state/web_state.h
@@ -75,14 +75,22 @@
   // Parameters for the OpenURL() method.
   struct OpenURLParams {
     OpenURLParams(const GURL& url,
+                  const GURL& virtual_url,
                   const Referrer& referrer,
                   WindowOpenDisposition disposition,
                   ui::PageTransition transition,
                   bool is_renderer_initiated);
+    OpenURLParams(const GURL& url,
+                  const Referrer& referrer,
+                  WindowOpenDisposition disposition,
+                  ui::PageTransition transition,
+                  bool is_renderer_initiated);
+    OpenURLParams(const OpenURLParams& params);
     ~OpenURLParams();
 
-    // The URL/referrer to be opened.
+    // The URL/virtualURL/referrer to be opened.
     GURL url;
+    GURL virtual_url;
     Referrer referrer;
 
     // The disposition requested by the navigation source.
diff --git a/ios/web/web_state/web_state.mm b/ios/web/web_state/web_state.mm
index 55ece67..201e489c 100644
--- a/ios/web/web_state/web_state.mm
+++ b/ios/web/web_state/web_state.mm
@@ -16,16 +16,38 @@
 WebState::CreateParams::~CreateParams() {}
 
 WebState::OpenURLParams::OpenURLParams(const GURL& url,
+                                       const GURL& virtual_url,
                                        const Referrer& referrer,
                                        WindowOpenDisposition disposition,
                                        ui::PageTransition transition,
                                        bool is_renderer_initiated)
     : url(url),
+      virtual_url(virtual_url),
       referrer(referrer),
       disposition(disposition),
       transition(transition),
       is_renderer_initiated(is_renderer_initiated) {}
 
+WebState::OpenURLParams::OpenURLParams(const GURL& url,
+                                       const Referrer& referrer,
+                                       WindowOpenDisposition disposition,
+                                       ui::PageTransition transition,
+                                       bool is_renderer_initiated)
+    : OpenURLParams(url,
+                    GURL::EmptyGURL(),
+                    referrer,
+                    disposition,
+                    transition,
+                    is_renderer_initiated) {}
+
+WebState::OpenURLParams::OpenURLParams(const OpenURLParams& params)
+    : url(params.url),
+      virtual_url(params.virtual_url),
+      referrer(params.referrer),
+      disposition(params.disposition),
+      transition(params.transition),
+      is_renderer_initiated(params.is_renderer_initiated) {}
+
 WebState::OpenURLParams::~OpenURLParams() {}
 
 }  // namespace web
diff --git a/ios/web/web_state/web_state_delegate_bridge_unittest.mm b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
index bae5bad1..89ca7246 100644
--- a/ios/web/web_state/web_state_delegate_bridge_unittest.mm
+++ b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
@@ -88,7 +88,7 @@
   ASSERT_FALSE([delegate_ openURLParams]);
 
   web::WebState::OpenURLParams params(
-      GURL("https://chromium.test/"),
+      GURL("https://chromium.test/"), GURL("https://virtual.chromium.test/"),
       web::Referrer(GURL("https://chromium2.test/"), ReferrerPolicyNever),
       WindowOpenDisposition::NEW_WINDOW, ui::PAGE_TRANSITION_FORM_SUBMIT, true);
   EXPECT_EQ(&test_web_state_,
@@ -98,6 +98,7 @@
   const web::WebState::OpenURLParams* result_params = [delegate_ openURLParams];
   ASSERT_TRUE(result_params);
   EXPECT_EQ(params.url, result_params->url);
+  EXPECT_EQ(params.virtual_url, result_params->virtual_url);
   EXPECT_EQ(params.referrer.url, result_params->referrer.url);
   EXPECT_EQ(params.referrer.policy, result_params->referrer.policy);
   EXPECT_EQ(params.disposition, result_params->disposition);
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm
index d84b1f69..983ba18 100644
--- a/ios/web/web_state/web_state_impl_unittest.mm
+++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -495,7 +495,7 @@
   EXPECT_EQ(web_state_.get(),
             delegate.last_close_web_state_request()->web_state);
 
-  // Test that OpenURLFromWebState() is called.
+  // Test that OpenURLFromWebState() is called without a virtual URL.
   WebState::OpenURLParams params(GURL("https://chromium.test/"), Referrer(),
                                  WindowOpenDisposition::CURRENT_TAB,
                                  ui::PAGE_TRANSITION_LINK, true);
@@ -506,6 +506,27 @@
   EXPECT_EQ(web_state_.get(), open_url_request->web_state);
   WebState::OpenURLParams actual_params = open_url_request->params;
   EXPECT_EQ(params.url, actual_params.url);
+  EXPECT_EQ(GURL::EmptyGURL(), params.virtual_url);
+  EXPECT_EQ(GURL::EmptyGURL(), actual_params.virtual_url);
+  EXPECT_EQ(params.referrer.url, actual_params.referrer.url);
+  EXPECT_EQ(params.referrer.policy, actual_params.referrer.policy);
+  EXPECT_EQ(params.disposition, actual_params.disposition);
+  EXPECT_TRUE(
+      PageTransitionCoreTypeIs(params.transition, actual_params.transition));
+  EXPECT_EQ(params.is_renderer_initiated, actual_params.is_renderer_initiated);
+
+  // Test that OpenURLFromWebState() is called with a virtual URL.
+  params = WebState::OpenURLParams(
+      GURL("https://chromium.test/"), GURL("https://virtual.chromium.test/"),
+      Referrer(), WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_LINK,
+      true);
+  web_state_->OpenURL(params);
+  open_url_request = delegate.last_open_url_request();
+  ASSERT_TRUE(open_url_request);
+  EXPECT_EQ(web_state_.get(), open_url_request->web_state);
+  actual_params = open_url_request->params;
+  EXPECT_EQ(params.url, actual_params.url);
+  EXPECT_EQ(params.virtual_url, actual_params.virtual_url);
   EXPECT_EQ(params.referrer.url, actual_params.referrer.url);
   EXPECT_EQ(params.referrer.policy, actual_params.referrer.policy);
   EXPECT_EQ(params.disposition, actual_params.disposition);
diff --git a/media/capture/video/chromeos/camera_device_delegate.cc b/media/capture/video/chromeos/camera_device_delegate.cc
index d0c61e8..80188481 100644
--- a/media/capture/video/chromeos/camera_device_delegate.cc
+++ b/media/capture/video/chromeos/camera_device_delegate.cc
@@ -90,12 +90,22 @@
 
 }  // namespace
 
+bool IsInputStream(StreamType stream_type) {
+  // Currently there is only one input stream. Modify this method if there is
+  // any other input streams.
+  return stream_type == StreamType::kYUVInput;
+}
+
 StreamType StreamIdToStreamType(uint64_t stream_id) {
   switch (stream_id) {
     case 0:
-      return StreamType::kPreview;
+      return StreamType::kPreviewOutput;
     case 1:
-      return StreamType::kStillCapture;
+      return StreamType::kJpegOutput;
+    case 2:
+      return StreamType::kYUVInput;
+    case 3:
+      return StreamType::kYUVOutput;
     default:
       return StreamType::kUnknown;
   }
@@ -103,10 +113,14 @@
 
 std::string StreamTypeToString(StreamType stream_type) {
   switch (stream_type) {
-    case StreamType::kPreview:
-      return std::string("StreamType::kPreview");
-    case StreamType::kStillCapture:
-      return std::string("StreamType::kStillCapture");
+    case StreamType::kPreviewOutput:
+      return std::string("StreamType::kPreviewOutput");
+    case StreamType::kJpegOutput:
+      return std::string("StreamType::kJpegOutput");
+    case StreamType::kYUVInput:
+      return std::string("StreamType::kYUVInput");
+    case StreamType::kYUVOutput:
+      return std::string("StreamType::kYUVOutput");
     default:
       return std::string("Unknown StreamType value: ") +
              std::to_string(static_cast<int32_t>(stream_type));
@@ -179,6 +193,8 @@
     base::OnceClosure device_close_callback) {
   DCHECK(ipc_task_runner_->BelongsToCurrentThread());
 
+  reprocess_manager_->FlushReprocessOptions();
+
   if (!device_context_ ||
       device_context_->GetState() == CameraDeviceContext::State::kStopped ||
       (device_context_->GetState() == CameraDeviceContext::State::kError &&
@@ -268,7 +284,7 @@
     return;
   }
 
-  if (request_manager_->GetNumberOfStreams() < kMaxConfiguredStreams) {
+  if (!request_manager_->HasStreamsConfiguredForTakePhoto()) {
     request_manager_->StopPreview(
         base::BindOnce(&CameraDeviceDelegate::OnFlushed, GetWeakPtr()));
     set_photo_option_callback_ = std::move(callback);
@@ -293,9 +309,9 @@
 
   auto construct_request_cb =
       base::BindOnce(&CameraDeviceDelegate::ConstructDefaultRequestSettings,
-                     GetWeakPtr(), StreamType::kStillCapture);
+                     GetWeakPtr(), StreamType::kJpegOutput);
 
-  if (request_manager_->GetNumberOfStreams() >= kMaxConfiguredStreams) {
+  if (request_manager_->HasStreamsConfiguredForTakePhoto()) {
     camera_3a_controller_->Stabilize3AForStillCapture(
         std::move(construct_request_cb));
     return;
@@ -392,6 +408,8 @@
   SortCameraMetadata(&camera_info->static_camera_characteristics);
   static_metadata_ = std::move(camera_info->static_camera_characteristics);
 
+  reprocess_manager_->UpdateSupportedEffects(static_metadata_);
+
   const cros::mojom::CameraMetadataEntryPtr* sensor_orientation =
       GetMetadataEntry(
           static_metadata_,
@@ -491,7 +509,7 @@
   // Set up context for preview stream.
   cros::mojom::Camera3StreamPtr preview_stream =
       cros::mojom::Camera3Stream::New();
-  preview_stream->id = static_cast<uint64_t>(StreamType::kPreview);
+  preview_stream->id = static_cast<uint64_t>(StreamType::kPreviewOutput);
   preview_stream->stream_type =
       cros::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT;
   preview_stream->width =
@@ -521,7 +539,7 @@
 
     cros::mojom::Camera3StreamPtr still_capture_stream =
         cros::mojom::Camera3Stream::New();
-    still_capture_stream->id = static_cast<uint64_t>(StreamType::kStillCapture);
+    still_capture_stream->id = static_cast<uint64_t>(StreamType::kJpegOutput);
     still_capture_stream->stream_type =
         cros::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT;
     still_capture_stream->width = max_blob_width;
@@ -532,6 +550,38 @@
     still_capture_stream->rotation =
         cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
     stream_config->streams.push_back(std::move(still_capture_stream));
+
+    int32_t max_yuv_width = 0, max_yuv_height = 0;
+    if (IsYUVReprocessingSupported(&max_yuv_width, &max_yuv_height)) {
+      auto reprocessing_stream_input = cros::mojom::Camera3Stream::New();
+      reprocessing_stream_input->id =
+          static_cast<uint64_t>(StreamType::kYUVInput);
+      reprocessing_stream_input->stream_type =
+          cros::mojom::Camera3StreamType::CAMERA3_STREAM_INPUT;
+      reprocessing_stream_input->width = max_yuv_width;
+      reprocessing_stream_input->height = max_yuv_height;
+      reprocessing_stream_input->format =
+          cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888;
+      reprocessing_stream_input->data_space = 0;
+      reprocessing_stream_input->rotation =
+          cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
+
+      auto reprocessing_stream_output = cros::mojom::Camera3Stream::New();
+      reprocessing_stream_output->id =
+          static_cast<uint64_t>(StreamType::kYUVOutput);
+      reprocessing_stream_output->stream_type =
+          cros::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT;
+      reprocessing_stream_output->width = max_yuv_width;
+      reprocessing_stream_output->height = max_yuv_height;
+      reprocessing_stream_output->format =
+          cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888;
+      reprocessing_stream_output->data_space = 0;
+      reprocessing_stream_output->rotation =
+          cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
+
+      stream_config->streams.push_back(std::move(reprocessing_stream_input));
+      stream_config->streams.push_back(std::move(reprocessing_stream_output));
+    }
   }
 
   stream_config->operation_mode = cros::mojom::Camera3StreamConfigurationMode::
@@ -562,7 +612,7 @@
   }
   if (!updated_config ||
       updated_config->streams.size() > kMaxConfiguredStreams ||
-      updated_config->streams.size() < 1) {
+      updated_config->streams.size() < kMinConfiguredStreams) {
     device_context_->SetErrorState(
         media::VideoCaptureError::
             kCrosHalV3DeviceDelegateWrongNumberOfStreamsConfigured,
@@ -578,7 +628,76 @@
 
   device_context_->SetState(CameraDeviceContext::State::kStreamConfigured);
   // Kick off the preview stream.
-  ConstructDefaultRequestSettings(StreamType::kPreview);
+  ConstructDefaultRequestSettings(StreamType::kPreviewOutput);
+}
+
+bool CameraDeviceDelegate::IsYUVReprocessingSupported(int* max_width,
+                                                      int* max_height) {
+  bool has_yuv_reprocessing_capability = [&] {
+    auto capabilities = GetMetadataEntryAsSpan<uint8_t>(
+        static_metadata_,
+        cros::mojom::CameraMetadataTag::ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    auto capability_yuv_reprocessing = static_cast<uint8_t>(
+        cros::mojom::AndroidRequestAvailableCapabilities::
+            ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);
+    for (auto capability : capabilities) {
+      if (capability == capability_yuv_reprocessing) {
+        return true;
+      }
+    }
+    return false;
+  }();
+
+  if (!has_yuv_reprocessing_capability) {
+    return false;
+  }
+
+  bool has_yuv_input_blob_output = [&] {
+    auto formats_map = GetMetadataEntryAsSpan<int32_t>(
+        static_metadata_,
+        cros::mojom::CameraMetadataTag::
+            ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP);
+    // The formats map looks like: [
+    //   {INPUT_FORMAT, NUM_OF_OUTPUTS, OUTPUT_FORMAT_1, OUTPUT_FORMAT_2, ...},
+    //   {...},
+    //   ...
+    // ]
+    auto format_yuv = static_cast<int32_t>(
+        cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888);
+    auto format_blob = static_cast<int32_t>(
+        cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_BLOB);
+
+    size_t idx = 0;
+    while (idx < formats_map.size() && !has_yuv_input_blob_output) {
+      auto in_format = formats_map[idx++];
+      auto out_amount = formats_map[idx++];
+      if (in_format != format_yuv) {
+        idx += out_amount;
+        continue;
+      }
+      for (size_t idx_end = idx + out_amount; idx < idx_end; idx++) {
+        auto out_format = formats_map[idx];
+        if (out_format == format_blob) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }();
+
+  if (!has_yuv_input_blob_output) {
+    return false;
+  }
+
+  GetMaxStreamResolution(
+      static_metadata_, cros::mojom::Camera3StreamType::CAMERA3_STREAM_INPUT,
+      cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888, max_width,
+      max_height);
+  if (max_width == 0 || max_height == 0) {
+    return false;
+  }
+
+  return true;
 }
 
 void CameraDeviceDelegate::ConstructDefaultRequestSettings(
@@ -588,18 +707,20 @@
              CameraDeviceContext::State::kStreamConfigured ||
          device_context_->GetState() == CameraDeviceContext::State::kCapturing);
 
-  if (stream_type == StreamType::kPreview) {
+  if (stream_type == StreamType::kPreviewOutput) {
     device_ops_->ConstructDefaultRequestSettings(
         cros::mojom::Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW,
         base::BindOnce(
             &CameraDeviceDelegate::OnConstructedDefaultPreviewRequestSettings,
             GetWeakPtr()));
-  } else {  // stream_type == StreamType::kStillCapture
+  } else if (stream_type == StreamType::kJpegOutput) {
     device_ops_->ConstructDefaultRequestSettings(
         cros::mojom::Camera3RequestTemplate::CAMERA3_TEMPLATE_STILL_CAPTURE,
         base::BindOnce(&CameraDeviceDelegate::
                            OnConstructedDefaultStillCaptureRequestSettings,
                        GetWeakPtr()));
+  } else {
+    NOTREACHED() << "No default request settings for stream: " << stream_type;
   }
 }
 
@@ -638,12 +759,13 @@
   DCHECK(ipc_task_runner_->BelongsToCurrentThread());
 
   while (!take_photo_callbacks_.empty()) {
-    request_manager_->TakePhoto(
-        settings.Clone(),
+    reprocess_manager_->ConsumeReprocessOptions(
         base::BindOnce(
             &TakePhotoCallbackBundle, std::move(take_photo_callbacks_.front()),
             base::BindOnce(&Camera3AController::SetAutoFocusModeForStillCapture,
-                           camera_3a_controller_->GetWeakPtr())));
+                           camera_3a_controller_->GetWeakPtr())),
+        base::BindOnce(&RequestManager::TakePhoto,
+                       request_manager_->GetWeakPtr(), settings.Clone()));
     take_photo_callbacks_.pop();
   }
 }
diff --git a/media/capture/video/chromeos/camera_device_delegate.h b/media/capture/video/chromeos/camera_device_delegate.h
index 05fe7f59..fb3a2ae4 100644
--- a/media/capture/video/chromeos/camera_device_delegate.h
+++ b/media/capture/video/chromeos/camera_device_delegate.h
@@ -24,11 +24,16 @@
 class RequestManager;
 
 enum class StreamType : uint64_t {
-  kPreview = 0,
-  kStillCapture = 1,
+  kPreviewOutput = 0,
+  kJpegOutput = 1,
+  kYUVInput = 2,
+  kYUVOutput = 3,
   kUnknown,
 };
 
+// Returns true if the given stream type is an input stream.
+bool IsInputStream(StreamType stream_type);
+
 StreamType StreamIdToStreamType(uint64_t stream_id);
 
 std::string StreamTypeToString(StreamType stream_type);
@@ -131,6 +136,14 @@
       int32_t result,
       cros::mojom::Camera3StreamConfigurationPtr updated_config);
 
+  // Checks metadata in |static_metadata_| to ensure field
+  // request.availableCapabilities contains YUV reprocessing and field
+  // scaler.availableInputOutputFormatsMap contains YUV => BLOB mapping.
+  // If above checks both pass, fill the max yuv width and height in
+  // |max_width| and |max_height| and return true if both width and height are
+  // positive numbers. Return false otherwise.
+  bool IsYUVReprocessingSupported(int* max_width, int* max_height);
+
   // ConstructDefaultRequestSettings asks the camera HAL for the default request
   // settings of the stream in |stream_context_|.
   // OnConstructedDefaultRequestSettings sets the request settings in
diff --git a/media/capture/video/chromeos/request_builder.cc b/media/capture/video/chromeos/request_builder.cc
index b55a93a9..2e9d335 100644
--- a/media/capture/video/chromeos/request_builder.cc
+++ b/media/capture/video/chromeos/request_builder.cc
@@ -15,17 +15,24 @@
 RequestBuilder::RequestBuilder(CameraDeviceContext* device_context,
                                RequestBufferCallback request_buffer_callback)
     : device_context_(device_context),
+      frame_number_(0),
       request_buffer_callback_(std::move(request_buffer_callback)) {}
 
 RequestBuilder::~RequestBuilder() = default;
 
 cros::mojom::Camera3CaptureRequestPtr RequestBuilder::BuildRequest(
     std::set<StreamType> stream_types,
-    cros::mojom::CameraMetadataPtr settings) {
+    cros::mojom::CameraMetadataPtr settings,
+    base::Optional<uint64_t> input_buffer_id) {
   auto capture_request = cros::mojom::Camera3CaptureRequest::New();
   for (StreamType stream_type : stream_types) {
-    base::Optional<BufferInfo> buffer_info =
-        request_buffer_callback_.Run(stream_type);
+    base::Optional<BufferInfo> buffer_info;
+    if (IsInputStream(stream_type)) {
+      DCHECK(input_buffer_id.has_value());
+      buffer_info = request_buffer_callback_.Run(stream_type, input_buffer_id);
+    } else {
+      buffer_info = request_buffer_callback_.Run(stream_type, {});
+    }
     if (!buffer_info) {
       return capture_request;
     }
@@ -33,10 +40,15 @@
     auto buffer_handle = CreateCameraBufferHandle(stream_type, *buffer_info);
     auto stream_buffer =
         CreateStreamBuffer(stream_type, buffer_id, std::move(buffer_handle));
-    capture_request->output_buffers.push_back(std::move(stream_buffer));
+    if (IsInputStream(stream_type)) {
+      capture_request->input_buffer = std::move(stream_buffer);
+    } else {
+      capture_request->output_buffers.push_back(std::move(stream_buffer));
+    }
   }
-
   capture_request->settings = std::move(settings);
+  capture_request->frame_number = frame_number_++;
+
   return capture_request;
 }
 
diff --git a/media/capture/video/chromeos/request_builder.h b/media/capture/video/chromeos/request_builder.h
index 6dbf901..b67d5706 100644
--- a/media/capture/video/chromeos/request_builder.h
+++ b/media/capture/video/chromeos/request_builder.h
@@ -32,8 +32,8 @@
 // HAL process.
 class CAPTURE_EXPORT RequestBuilder {
  public:
-  using RequestBufferCallback =
-      base::RepeatingCallback<base::Optional<BufferInfo>(StreamType)>;
+  using RequestBufferCallback = base::RepeatingCallback<
+      base::Optional<BufferInfo>(StreamType, base::Optional<uint64_t>)>;
 
   RequestBuilder(CameraDeviceContext* device_context,
                  // Callback to request buffer from StreamBufferManager. Having
@@ -42,10 +42,12 @@
                  RequestBufferCallback request_buffer_callback);
   ~RequestBuilder();
 
-  // Builds a capture request by given streams and settings.
+  // Builds a capture request by given streams and settings. The
+  // |input_buffer_id| is used for reprocess request.
   cros::mojom::Camera3CaptureRequestPtr BuildRequest(
       std::set<StreamType> stream_types,
-      cros::mojom::CameraMetadataPtr settings);
+      cros::mojom::CameraMetadataPtr settings,
+      base::Optional<uint64_t> input_buffer_id);
 
  private:
   cros::mojom::CameraBufferHandlePtr CreateCameraBufferHandle(
@@ -59,6 +61,9 @@
 
   CameraDeviceContext* device_context_;
 
+  // The frame number. Increased by one for each capture request sent.
+  uint32_t frame_number_;
+
   RequestBufferCallback request_buffer_callback_;
 };
 }  // namespace media
diff --git a/media/capture/video/chromeos/request_manager.cc b/media/capture/video/chromeos/request_manager.cc
index 3a165f7..35f1ff1 100644
--- a/media/capture/video/chromeos/request_manager.cc
+++ b/media/capture/video/chromeos/request_manager.cc
@@ -5,6 +5,7 @@
 #include "media/capture/video/chromeos/request_manager.h"
 
 #include <sync/sync.h>
+#include <initializer_list>
 #include <map>
 #include <set>
 #include <string>
@@ -17,6 +18,7 @@
 #include "media/capture/video/chromeos/camera_buffer_factory.h"
 #include "media/capture/video/chromeos/camera_device_context.h"
 #include "media/capture/video/chromeos/camera_metadata_utils.h"
+#include "media/capture/video/chromeos/mojo/cros_image_capture.mojom.h"
 #include "mojo/public/cpp/platform/platform_handle.h"
 #include "mojo/public/cpp/system/platform_handle.h"
 
@@ -25,8 +27,15 @@
 namespace {
 
 constexpr uint32_t kUndefinedFrameNumber = 0xFFFFFFFF;
+
+constexpr std::initializer_list<StreamType> kYUVReprocessStreams = {
+    StreamType::kYUVInput, StreamType::kJpegOutput};
 }  // namespace
 
+ReprocessTasksInfo::ReprocessTasksInfo() = default;
+
+ReprocessTasksInfo::~ReprocessTasksInfo() = default;
+
 RequestManager::RequestManager(
     cros::mojom::Camera3CallbackOpsRequest callback_ops_request,
     std::unique_ptr<StreamCaptureInterface> capture_interface,
@@ -43,7 +52,6 @@
       blobify_callback_(std::move(blobify_callback)),
       ipc_task_runner_(std::move(ipc_task_runner)),
       capturing_(false),
-      frame_number_(0),
       partial_result_count_(1),
       first_frame_shutter_time_(base::TimeTicks()),
       weak_ptr_factory_(this) {
@@ -94,6 +102,17 @@
   return stream_buffer_manager_->GetStreamConfiguration(stream_type);
 }
 
+bool RequestManager::HasStreamsConfiguredForTakePhoto() {
+  if (stream_buffer_manager_->IsReprocessSupported()) {
+    return stream_buffer_manager_->HasStreamsConfigured(
+        {StreamType::kPreviewOutput, StreamType::kJpegOutput,
+         StreamType::kYUVInput, StreamType::kYUVOutput});
+  } else {
+    return stream_buffer_manager_->HasStreamsConfigured(
+        {StreamType::kPreviewOutput, StreamType::kJpegOutput});
+  }
+}
+
 void RequestManager::StartPreview(
     cros::mojom::CameraMetadataPtr preview_settings) {
   DCHECK(ipc_task_runner_->BelongsToCurrentThread());
@@ -116,9 +135,24 @@
 }
 
 void RequestManager::TakePhoto(cros::mojom::CameraMetadataPtr settings,
-                               VideoCaptureDevice::TakePhotoCallback callback) {
+                               ReprocessTaskQueue reprocess_tasks) {
   DCHECK(ipc_task_runner_->BelongsToCurrentThread());
 
+  if (stream_buffer_manager_->IsReprocessSupported()) {
+    pending_reprocess_tasks_queue_.push(std::move(reprocess_tasks));
+  } else {
+    // There should be only one reprocess task in the queue which is format
+    // conversion task.
+    DCHECK_EQ(reprocess_tasks.size(), 1lu);
+
+    take_photo_callback_queue_.push(
+        std::move(reprocess_tasks.front().callback));
+  }
+  take_photo_settings_queue_.push(std::move(settings));
+}
+
+void RequestManager::SetJpegOrientation(
+    cros::mojom::CameraMetadataPtr* settings) {
   std::vector<uint8_t> frame_orientation(sizeof(int32_t));
   *reinterpret_cast<int32_t*>(frame_orientation.data()) =
       base::checked_cast<int32_t>(device_context_->GetCameraFrameOrientation());
@@ -128,10 +162,7 @@
   e->type = cros::mojom::EntryType::TYPE_INT32;
   e->count = 1;
   e->data = std::move(frame_orientation);
-  AddOrUpdateMetadataEntry(&settings, std::move(e));
-
-  oneshot_request_settings_.push(std::move(settings));
-  take_photo_callback_queue_.push(std::move(callback));
+  AddOrUpdateMetadataEntry(settings, std::move(e));
 }
 
 void RequestManager::PrepareCaptureRequest() {
@@ -140,57 +171,165 @@
   if (!capturing_) {
     return;
   }
+
+  // There are two types of devices, each has several possible combinations of
+  // streams.
+  //
+  // For device with reprocess capability:
+  // 1. Preview
+  // 2. Capture (YuvOutput)
+  // 3. Preview + Capture (YuvOutput)
+  // 4. Reprocess (YuvInput + BlobOutput)
+  //
+  // For device without reprocess capability:
+  // 1. Preview
+  // 2. Capture (BlobOutput)
+  // 3. Preview + Capture (BlobOutput)
   std::set<StreamType> stream_types;
   cros::mojom::CameraMetadataPtr settings;
+  TakePhotoCallback callback = base::DoNothing();
+  base::Optional<uint64_t> input_buffer_id;
+  cros::mojom::Effect reprocess_effect = cros::mojom::Effect::NO_EFFECT;
 
-  // Reqular request should always have repeating request if the preview is
-  // on.
-  stream_types.insert(StreamType::kPreview);
-  if (!stream_buffer_manager_->HasFreeBuffers(stream_types)) {
-    return;
-  }
-  bool has_still_capture_streams = false;
-  if (!oneshot_request_settings_.empty() &&
-      stream_buffer_manager_->HasFreeBuffers({StreamType::kStillCapture})) {
-    stream_types.insert(StreamType::kStillCapture);
-    settings = std::move(oneshot_request_settings_.front());
-    oneshot_request_settings_.pop();
-    has_still_capture_streams = true;
-  } else {
-    settings = repeating_request_settings_.Clone();
+  bool is_reprocess_request = false;
+  bool is_preview_request = false;
+  bool is_oneshot_request = false;
+
+  // First, check if there are pending reprocess tasks.
+  is_reprocess_request = TryPrepareReprocessRequest(
+      &stream_types, &settings, &callback, &input_buffer_id, &reprocess_effect);
+
+  // If there is no pending reprocess task, then check if there are pending
+  // one-shot requests. And also try to put preview in the request.
+  if (!is_reprocess_request) {
+    is_preview_request = TryPreparePreviewRequest(&stream_types, &settings);
+
+    // Order matters here. If the preview request and oneshot request are both
+    // added in single capture request, the settings will be overridden by the
+    // later.
+    is_oneshot_request =
+        TryPrepareOneShotRequest(&stream_types, &settings, &callback);
   }
 
-  auto capture_request = request_builder_->BuildRequest(std::move(stream_types),
-                                                        std::move(settings));
-  if (has_still_capture_streams) {
-    SendCaptureRequest(std::move(capture_request),
-                       std::move(take_photo_callback_queue_.front()));
-    take_photo_callback_queue_.pop();
-  } else {
-    SendCaptureRequest(std::move(capture_request), base::DoNothing());
-  }
-}
-
-void RequestManager::SendCaptureRequest(
-    cros::mojom::Camera3CaptureRequestPtr capture_request,
-    VideoCaptureDevice::TakePhotoCallback take_photo_callback) {
-  DCHECK(ipc_task_runner_->BelongsToCurrentThread());
-  if (!capturing_) {
+  if (!is_reprocess_request && !is_oneshot_request && !is_preview_request) {
     return;
   }
 
-  CaptureResult& pending_result = pending_results_[frame_number_];
-  pending_result.still_capture_callback = std::move(take_photo_callback);
+  auto capture_request = request_builder_->BuildRequest(
+      std::move(stream_types), std::move(settings), input_buffer_id);
+
+  CaptureResult& pending_result =
+      pending_results_[capture_request->frame_number];
   pending_result.unsubmitted_buffer_count =
       capture_request->output_buffers.size();
+  pending_result.input_buffer_id = input_buffer_id;
+  pending_result.reprocess_effect = reprocess_effect;
+  pending_result.still_capture_callback = std::move(callback);
+
+  // For reprocess supported devices, bind the ReprocessTaskQueue with this
+  // frame number. Once the shot result is returned, we will rebind the
+  // ReprocessTaskQueue with the id of YUV buffer which contains the result.
+  if (is_oneshot_request && stream_buffer_manager_->IsReprocessSupported() &&
+      !pending_reprocess_tasks_queue_.empty()) {
+    frame_number_reprocess_tasks_map_[capture_request->frame_number] =
+        std::move(pending_reprocess_tasks_queue_.front());
+    pending_reprocess_tasks_queue_.pop();
+  }
 
   UpdateCaptureSettings(&capture_request->settings);
-  capture_request->frame_number = frame_number_;
   capture_interface_->ProcessCaptureRequest(
       std::move(capture_request),
-      base::BindOnce(&RequestManager::OnProcessedCaptureRequest,
-                     weak_ptr_factory_.GetWeakPtr()));
-  frame_number_++;
+      base::BindOnce(&RequestManager::OnProcessedCaptureRequest, GetWeakPtr()));
+}
+
+bool RequestManager::TryPrepareReprocessRequest(
+    std::set<StreamType>* stream_types,
+    cros::mojom::CameraMetadataPtr* settings,
+    TakePhotoCallback* callback,
+    base::Optional<uint64_t>* input_buffer_id,
+    cros::mojom::Effect* reprocess_effect) {
+  if (buffer_id_reprocess_tasks_map_.empty() ||
+      !stream_buffer_manager_->HasFreeBuffers(kYUVReprocessStreams)) {
+    return false;
+  }
+
+  // Consume reprocess task.
+  ReprocessTaskQueue* reprocess_task_queue;
+  for (auto& it : buffer_id_reprocess_tasks_map_) {
+    if (processing_buffer_ids_.count(it.first) == 0) {
+      *input_buffer_id = it.first;
+      reprocess_task_queue = &it.second;
+      break;
+    }
+  }
+
+  if (!*input_buffer_id) {
+    return false;
+  }
+
+  ReprocessTask task = std::move(reprocess_task_queue->front());
+  reprocess_task_queue->pop();
+
+  stream_types->insert(kYUVReprocessStreams);
+  // Prepare metadata by adding extra metadata.
+  *settings = repeating_request_settings_.Clone();
+  SetJpegOrientation(settings);
+  for (auto& metadata : task.extra_metadata) {
+    AddOrUpdateMetadataEntry(settings, std::move(metadata));
+  }
+  *callback = std::move(task.callback);
+  *reprocess_effect = task.effect;
+  processing_buffer_ids_.insert(**input_buffer_id);
+
+  // Remove the mapping from map if all tasks consumed.
+  if (reprocess_task_queue->empty()) {
+    buffer_id_reprocess_tasks_map_.erase(**input_buffer_id);
+  }
+  return true;
+}
+
+bool RequestManager::TryPreparePreviewRequest(
+    std::set<StreamType>* stream_types,
+    cros::mojom::CameraMetadataPtr* settings) {
+  if (!stream_buffer_manager_->HasFreeBuffers({StreamType::kPreviewOutput})) {
+    return false;
+  }
+
+  stream_types->insert({StreamType::kPreviewOutput});
+  *settings = repeating_request_settings_.Clone();
+  return true;
+}
+
+bool RequestManager::TryPrepareOneShotRequest(
+    std::set<StreamType>* stream_types,
+    cros::mojom::CameraMetadataPtr* settings,
+    TakePhotoCallback* callback) {
+  if (stream_buffer_manager_->IsReprocessSupported()) {
+    // For devices that support reprocess, fill the frame data in YUV buffer and
+    // reprocess on that YUV buffer.
+    if (take_photo_settings_queue_.empty() ||
+        !stream_buffer_manager_->HasFreeBuffers({StreamType::kYUVOutput})) {
+      return false;
+    }
+    stream_types->insert({StreamType::kYUVOutput});
+    *settings = std::move(take_photo_settings_queue_.front());
+  } else {
+    // For devices that do not support reprocess, fill the frame data in BLOB
+    // buffer and fill the callback.
+    if (take_photo_settings_queue_.empty() ||
+        take_photo_callback_queue_.empty() ||
+        !stream_buffer_manager_->HasFreeBuffers({StreamType::kJpegOutput})) {
+      return false;
+    }
+    stream_types->insert({StreamType::kJpegOutput});
+    *callback = std::move(take_photo_callback_queue_.front());
+    take_photo_callback_queue_.pop();
+
+    *settings = std::move(take_photo_settings_queue_.front());
+    SetJpegOrientation(settings);
+  }
+  take_photo_settings_queue_.pop();
+  return true;
 }
 
 void RequestManager::OnProcessedCaptureRequest(int32_t result) {
@@ -517,16 +656,17 @@
     }
   }
 
+  bool should_release_buffer = true;
   // Deliver the captured data to client.
   if (stream_buffer->status ==
       cros::mojom::Camera3BufferStatus::CAMERA3_BUFFER_STATUS_OK) {
     gfx::GpuMemoryBuffer* buffer =
         stream_buffer_manager_->GetBufferById(stream_type, buffer_id);
-    if (stream_type == StreamType::kPreview) {
+    if (stream_type == StreamType::kPreviewOutput) {
       device_context_->SubmitCapturedData(
           buffer, stream_buffer_manager_->GetStreamCaptureFormat(stream_type),
           pending_result.reference_time, pending_result.timestamp);
-    } else if (stream_type == StreamType::kStillCapture) {
+    } else if (stream_type == StreamType::kJpegOutput) {
       DCHECK(pending_result.still_capture_callback);
       const Camera3JpegBlob* header = reinterpret_cast<Camera3JpegBlob*>(
           reinterpret_cast<uintptr_t>(buffer->memory(0)) +
@@ -543,14 +683,43 @@
           reinterpret_cast<uint8_t*>(buffer->memory(0)), header->jpeg_size,
           stream_buffer_manager_->GetStreamCaptureFormat(stream_type), 0);
       if (blob) {
-        std::move(pending_result.still_capture_callback).Run(std::move(blob));
+        int task_status = kReprocessSuccess;
+        if (stream_buffer_manager_->IsReprocessSupported()) {
+          task_status = ReprocessManager::GetReprocessReturnCode(
+              pending_result.reprocess_effect, &pending_result.metadata);
+        }
+        std::move(pending_result.still_capture_callback)
+            .Run(task_status, std::move(blob));
       } else {
         // TODO(wtlee): If it is fatal, we should set error state here.
         LOG(ERROR) << "Failed to blobify the captured JPEG image";
       }
+
+      if (pending_result.input_buffer_id) {
+        // Remove the id from processing list to run next reprocess task.
+        processing_buffer_ids_.erase(*pending_result.input_buffer_id);
+
+        // If all reprocess tasks are done for this buffer, release the buffer.
+        if (base::ContainsKey(buffer_id_reprocess_tasks_map_,
+                              *pending_result.input_buffer_id)) {
+          stream_buffer_manager_->ReleaseBuffer(
+              StreamType::kYUVOutput, *pending_result.input_buffer_id);
+        }
+      }
+    } else if (stream_type == StreamType::kYUVOutput) {
+      buffer_id_reprocess_tasks_map_[buffer_id] =
+          std::move(frame_number_reprocess_tasks_map_[frame_number]);
+      frame_number_reprocess_tasks_map_.erase(frame_number);
+
+      // Don't release the buffer since we will need it as input buffer for
+      // reprocessing. We will release it until all reprocess tasks for this
+      // buffer are done.
+      should_release_buffer = false;
     }
   }
-  stream_buffer_manager_->ReleaseBuffer(stream_type, buffer_id);
+  if (should_release_buffer) {
+    stream_buffer_manager_->ReleaseBuffer(stream_type, buffer_id);
+  }
   pending_result.unsubmitted_buffer_count--;
 
   if (pending_result.unsubmitted_buffer_count == 0) {
@@ -561,8 +730,8 @@
   PrepareCaptureRequest();
 }
 
-size_t RequestManager::GetNumberOfStreams() {
-  return stream_buffer_manager_->GetNumberOfStreams();
+base::WeakPtr<RequestManager> RequestManager::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
 }
 
 void RequestManager::AddResultMetadataObserver(
diff --git a/media/capture/video/chromeos/request_manager.h b/media/capture/video/chromeos/request_manager.h
index fb9110b4..d6532c7b 100644
--- a/media/capture/video/chromeos/request_manager.h
+++ b/media/capture/video/chromeos/request_manager.h
@@ -10,14 +10,14 @@
 #include <memory>
 #include <queue>
 #include <set>
-#include <unordered_map>
-#include <unordered_set>
 #include <vector>
 
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "media/capture/mojom/image_capture.mojom.h"
 #include "media/capture/video/chromeos/camera_device_delegate.h"
 #include "media/capture/video/chromeos/mojo/camera3.mojom.h"
+#include "media/capture/video/chromeos/reprocess_manager.h"
 #include "media/capture/video/chromeos/request_builder.h"
 #include "media/capture/video/chromeos/stream_buffer_manager.h"
 #include "media/capture/video_capture_types.h"
@@ -36,7 +36,18 @@
   uint32_t jpeg_size;
 };
 
-static const int kMaxConfiguredStreams = 2;
+// Minimum configured streams should at least contain kPreviewOutput.
+constexpr int32_t kMinConfiguredStreams = 1;
+
+// Maximum configured streams could contain two optional YUV streams.
+constexpr int32_t kMaxConfiguredStreams = 4;
+
+struct ReprocessTasksInfo {
+  ReprocessTasksInfo();
+  ~ReprocessTasksInfo();
+  uint64_t input_buffer_id;
+  ReprocessTaskQueue task_queue;
+};
 
 // Interface that provides API to let Camera3AController to update the metadata
 // that will be sent with capture request.
@@ -78,6 +89,8 @@
       const uint32_t bytesused,
       const VideoCaptureFormat& capture_format,
       int screen_rotation)>;
+  using TakePhotoCallback =
+      base::OnceCallback<void(int status, media::mojom::BlobPtr blob_result)>;
 
   // CaptureResult is used to hold the pending capture results for each frame.
   struct CaptureResult {
@@ -103,7 +116,12 @@
     size_t unsubmitted_buffer_count;
     // The callback used to return the captured still capture JPEG buffer.  Set
     // if and only if the capture request was sent with a still capture buffer.
-    VideoCaptureDevice::TakePhotoCallback still_capture_callback;
+    TakePhotoCallback still_capture_callback;
+    // The reprocess effect that this capture request is used. Will be set to
+    // NO_EFFECT if it is not a reprocess request.
+    cros::mojom::Effect reprocess_effect;
+    // The input buffer id for this capture request.
+    base::Optional<uint64_t> input_buffer_id;
   };
 
   RequestManager(cros::mojom::Camera3CallbackOpsRequest callback_ops_request,
@@ -123,26 +141,33 @@
 
   cros::mojom::Camera3StreamPtr GetStreamConfiguration(StreamType stream_type);
 
+  bool HasStreamsConfiguredForTakePhoto();
+
   // StartPreview is the entry point to starting the video capture.  The way
   // the video capture loop works is:
   //
-  //  (1) Preparing capture request by mixing repeating request with still
-  //      capture request if it exists. And build the capture request by
+  //  (1) Preparing capture request by mixing preview request, one-shot request
+  //      and reprocess request if they exists. And build the capture request by
   //      RequestBuilder.
-  //  (2) Once the capture request is built, it triggers SendCaptureRequest() to
-  //      send the capture request and it will go back to (1) to generate next
-  //      request.
+  //  (2) Once the capture request is built, it sends the capture request and
+  //      it will go back to (1) to generate next capture request.
   //  (3) The camera HAL returns the shutter time of a capture request through
-  //      Notify, and the filled buffer through ProcessCaptureResult.
-  //  (4) Once all the result metadata are collected, TrySubmitPendingBuffers()
-  //      is passed and trigger SubmitCaptureResult() to deliver the filled
-  //      buffer to Chrome. After the buffer is consumed by Chrome it is
-  //      enqueued back to the free buffer queue.  Goto (1) to start another
-  //      capture loop.
+  //      Notify(), and the filled buffer through ProcessCaptureResult().
+  //  (4) Once all the result metadata are collected, it would pass
+  //      TrySubmitPendingBuffers() and SubmitCaptureResult() will be triggered
+  //      to deliver the filled buffer to Chrome. After the buffer is consumed
+  //      by Chrome it is enqueued back to the free buffer queue. Goto (1) to
+  //      start another capture loop.
   //
-  // When TakePhoto() is called, an additional BLOB buffer is queued in step (2)
-  // to let the HAL fill the still capture JPEG image.  When the JPEG image is
-  // returned in (4), it's passed to upper layer through the TakePhotoCallback.
+  // When TakePhoto() is called, an additional YUV buffer is queued in step (2)
+  // to let the HAL fill the photo result in YUV format. If it is a regular
+  // capture, only one reprocess task will be added into the queue which asks
+  // HAL to convert YUV photo to JPEG format. If it is a request with
+  // special effect (e.g. Portrait mode shot), there will be more than one
+  // reprocess task added in the queue and it will be processed sequentially.
+  //
+  // For every reprocess task, there is a corresponding callback which will
+  // return the photo result in JPEG format.
   void StartPreview(cros::mojom::CameraMetadataPtr preview_settings);
 
   // Stops the capture loop.  After StopPreview is called |callback_ops_| is
@@ -151,9 +176,9 @@
   void StopPreview(base::OnceCallback<void(int32_t)> callback);
 
   void TakePhoto(cros::mojom::CameraMetadataPtr settings,
-                 VideoCaptureDevice::TakePhotoCallback callback);
+                 ReprocessTaskQueue reprocess_tasks);
 
-  size_t GetNumberOfStreams();
+  base::WeakPtr<RequestManager> GetWeakPtr();
 
   // CaptureMetadataDispatcher implementations.
   void AddResultMetadataObserver(ResultMetadataObserver* observer) override;
@@ -177,15 +202,26 @@
  private:
   friend class RequestManagerTest;
 
-  // Prepares a capture request by mixing repeating request with still capture
-  // request if it exists.
+  // Puts Jpeg orientation information into the metadata.
+  void SetJpegOrientation(cros::mojom::CameraMetadataPtr* settings);
+
+  // Prepares a capture request by mixing repeating request with one-shot
+  // request if it exists. If there are reprocess requests in the queue, just
+  // build the reprocess capture request without mixing the repeating request.
   void PrepareCaptureRequest();
 
-  // Decorates the frame number and settings for the capture request and send it
-  // to HAL.
-  void SendCaptureRequest(
-      cros::mojom::Camera3CaptureRequestPtr capture_request,
-      VideoCaptureDevice::TakePhotoCallback take_photo_callback);
+  bool TryPrepareReprocessRequest(std::set<StreamType>* stream_types,
+                                  cros::mojom::CameraMetadataPtr* settings,
+                                  TakePhotoCallback* callback,
+                                  base::Optional<uint64_t>* input_buffer_id,
+                                  cros::mojom::Effect* reprocess_effect);
+
+  bool TryPreparePreviewRequest(std::set<StreamType>* stream_types,
+                                cros::mojom::CameraMetadataPtr* settings);
+
+  bool TryPrepareOneShotRequest(std::set<StreamType>* stream_types,
+                                cros::mojom::CameraMetadataPtr* settings,
+                                TakePhotoCallback* callback);
 
   // Callback for ProcessCaptureRequest().
   void OnProcessedCaptureRequest(int32_t result);
@@ -243,10 +279,6 @@
   // A flag indicating whether the capture loops is running.
   bool capturing_;
 
-  // The frame number.  Increased by one for each capture request sent; reset
-  // to zero in AllocateAndStart.
-  uint32_t frame_number_;
-
   // The number of partial stages.  |partial_result_count_| is learned by
   // querying |static_metadata_|.  In case the result count is absent in
   // |static_metadata_|, it defaults to one which means all the result
@@ -284,9 +316,29 @@
   // Stores the pending capture results of the current in-flight frames.
   std::map<uint32_t, CaptureResult> pending_results_;
 
+  std::queue<cros::mojom::CameraMetadataPtr> take_photo_settings_queue_;
+
+  // Queue that contains ReprocessTaskQueue that will be consumed by
+  // reprocess-supported devices.
+  std::queue<ReprocessTaskQueue> pending_reprocess_tasks_queue_;
+
   // Callback for TakePhoto(). When preparing capture request, the callback will
   // be popped and moved to CaptureResult.
-  std::queue<VideoCaptureDevice::TakePhotoCallback> take_photo_callback_queue_;
+  std::queue<base::OnceCallback<void(int, mojom::BlobPtr)>>
+      take_photo_callback_queue_;
+
+  // Map that maps buffer id to reprocess task queue. If all reprocess tasks for
+  // specific buffer id are all consumed, release that buffer.
+  std::map<uint64_t, ReprocessTaskQueue> buffer_id_reprocess_tasks_map_;
+
+  // Map that maps frame number to reprocess task queue. We should consume the
+  // content inside this map when preparing capture request.
+  std::map<uint32_t, ReprocessTaskQueue> frame_number_reprocess_tasks_map_;
+
+  // Buffer ids that are currently processing. When preparing capture request,
+  // we will ignore the reprocess task if its corresponding buffer id is in
+  // the set.
+  std::set<uint64_t> processing_buffer_ids_;
 
   // Map for retrieving the last received frame number. It is used to check for
   // duplicate or out of order of frames.
diff --git a/media/capture/video/chromeos/request_manager_unittest.cc b/media/capture/video/chromeos/request_manager_unittest.cc
index f79620d..893dd2fc 100644
--- a/media/capture/video/chromeos/request_manager_unittest.cc
+++ b/media/capture/video/chromeos/request_manager_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "media/capture/video/chromeos/request_manager.h"
+#include "media/capture/video/chromeos/reprocess_manager.h"
 #include "media/capture/video/chromeos/stream_buffer_manager.h"
 
 #include <map>
@@ -184,7 +185,7 @@
     std::vector<cros::mojom::Camera3StreamPtr> streams;
 
     auto preview_stream = cros::mojom::Camera3Stream::New();
-    preview_stream->id = static_cast<uint64_t>(StreamType::kPreview);
+    preview_stream->id = static_cast<uint64_t>(StreamType::kPreviewOutput);
     preview_stream->stream_type =
         cros::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT;
     preview_stream->width = kDefaultCaptureFormat.frame_size.width();
@@ -199,7 +200,7 @@
     streams.push_back(std::move(preview_stream));
 
     auto still_capture_stream = cros::mojom::Camera3Stream::New();
-    still_capture_stream->id = static_cast<uint64_t>(StreamType::kStillCapture);
+    still_capture_stream->id = static_cast<uint64_t>(StreamType::kJpegOutput);
     still_capture_stream->stream_type =
         cros::mojom::Camera3StreamType::CAMERA3_STREAM_OUTPUT;
     still_capture_stream->width = kDefaultCaptureFormat.frame_size.width();
@@ -222,7 +223,8 @@
     auto error_msg = cros::mojom::Camera3ErrorMsg::New();
     error_msg->frame_number = frame_number;
     // There is only the preview stream.
-    error_msg->error_stream_id = static_cast<uint64_t>(StreamType::kPreview);
+    error_msg->error_stream_id =
+        static_cast<uint64_t>(StreamType::kPreviewOutput);
     error_msg->error_code = error_code;
     auto notify_msg = cros::mojom::Camera3NotifyMsg::New();
     notify_msg->message = cros::mojom::Camera3NotifyMsgMessage::New();
@@ -488,24 +490,6 @@
 }
 
 // Test that preview and still capture buffers can be correctly submitted.
-TEST_F(RequestManagerTest, TakePhotoTest) {
-  EXPECT_CALL(*GetMockCaptureInterface(), DoProcessCaptureRequest(_, _))
-      .Times(AtLeast(1))
-      .WillRepeatedly(Invoke(this, &RequestManagerTest::ProcessCaptureRequest));
-
-  request_manager_->SetUpStreamsAndBuffers(
-      kDefaultCaptureFormat,
-      GetFakeStaticMetadata(/* partial_result_count */ 1),
-      PrepareCaptureStream(/* max_buffers */ 1));
-  request_manager_->StartPreview(cros::mojom::CameraMetadata::New());
-  request_manager_->TakePhoto(
-      GetFakeStaticMetadata(/* partial_result_count */ 1),
-      base::BindOnce([](RequestManagerTest* test,
-                        mojom::BlobPtr blob) { test->QuitCaptureLoop(); },
-                     base::Unretained(this)));
-
-  // Wait until a captured frame is received by MockVideoCaptureClient.
-  DoLoop();
-}
+// TODO(crbug.com/917574): Add reprocess tests and take photo test.
 
 }  // namespace media
diff --git a/media/capture/video/chromeos/stream_buffer_manager.cc b/media/capture/video/chromeos/stream_buffer_manager.cc
index 4420ec9..fd76325 100644
--- a/media/capture/video/chromeos/stream_buffer_manager.cc
+++ b/media/capture/video/chromeos/stream_buffer_manager.cc
@@ -57,6 +57,9 @@
 bool StreamBufferManager::HasFreeBuffers(
     const std::set<StreamType>& stream_types) {
   for (auto stream_type : stream_types) {
+    if (IsInputStream(stream_type)) {
+      continue;
+    }
     if (stream_context_[stream_type]->free_buffers.empty()) {
       return false;
     }
@@ -64,6 +67,16 @@
   return true;
 }
 
+bool StreamBufferManager::HasStreamsConfigured(
+    std::initializer_list<StreamType> stream_types) {
+  for (auto stream_type : stream_types) {
+    if (stream_context_.find(stream_type) == stream_context_.end()) {
+      return false;
+    }
+  }
+  return true;
+}
+
 void StreamBufferManager::SetUpStreamsAndBuffers(
     VideoCaptureFormat capture_format,
     const cros::mojom::CameraMetadataPtr& static_metadata,
@@ -100,17 +113,23 @@
     stream_context_[stream_type]->capture_format.pixel_format =
         stream_format.video_format;
 
+    // For input stream, there is no need to allocate buffers.
+    if (IsInputStream(stream_type)) {
+      continue;
+    }
+
     // Allocate buffers.
     size_t num_buffers = stream_context_[stream_type]->stream->max_buffers;
     stream_context_[stream_type]->buffers.resize(num_buffers);
     int32_t buffer_width, buffer_height;
     switch (stream_type) {
-      case StreamType::kPreview: {
+      case StreamType::kPreviewOutput:
+      case StreamType::kYUVOutput: {
         buffer_width = stream_context_[stream_type]->stream->width;
         buffer_height = stream_context_[stream_type]->stream->height;
         break;
       }
-      case StreamType::kStillCapture: {
+      case StreamType::kJpegOutput: {
         const cros::mojom::CameraMetadataEntryPtr* jpeg_max_size =
             GetMetadataEntry(
                 static_metadata,
@@ -160,7 +179,8 @@
 }
 
 base::Optional<BufferInfo> StreamBufferManager::RequestBuffer(
-    StreamType stream_type) {
+    StreamType stream_type,
+    base::Optional<uint64_t> buffer_id) {
   VideoPixelFormat buffer_format =
       stream_context_[stream_type]->capture_format.pixel_format;
   uint32_t drm_format = PixFormatVideoToDrm(buffer_format);
@@ -175,11 +195,25 @@
   }
 
   BufferInfo buffer_info;
-  buffer_info.id = stream_context_[stream_type]->free_buffers.front();
-  stream_context_[stream_type]->free_buffers.pop();
-  buffer_info.gpu_memory_buffer = stream_context_[stream_type]
-                                      ->buffers[GetBufferIndex(buffer_info.id)]
-                                      .get();
+  if (buffer_id.has_value()) {
+    // Currently, only kYUVInput has an associated output buffer which is
+    // kYUVOutput.
+    if (stream_type != StreamType::kYUVInput) {
+      return {};
+    }
+    buffer_info.id = *buffer_id;
+    buffer_info.gpu_memory_buffer =
+        stream_context_[StreamType::kYUVOutput]
+            ->buffers[GetBufferIndex(buffer_info.id)]
+            .get();
+  } else {
+    buffer_info.id = stream_context_[stream_type]->free_buffers.front();
+    stream_context_[stream_type]->free_buffers.pop();
+    buffer_info.gpu_memory_buffer =
+        stream_context_[stream_type]
+            ->buffers[GetBufferIndex(buffer_info.id)]
+            .get();
+  }
   buffer_info.hal_pixel_format = stream_context_[stream_type]->stream->format;
   buffer_info.drm_format = drm_format;
   return buffer_info;
@@ -187,11 +221,14 @@
 
 void StreamBufferManager::ReleaseBuffer(StreamType stream_type,
                                         uint64_t buffer_id) {
+  if (IsInputStream(stream_type)) {
+    return;
+  }
   stream_context_[stream_type]->free_buffers.push(buffer_id);
 }
 
-size_t StreamBufferManager::GetNumberOfStreams() {
-  return stream_context_.size();
+bool StreamBufferManager::IsReprocessSupported() {
+  return stream_context_.find(StreamType::kYUVOutput) != stream_context_.end();
 }
 
 // static
diff --git a/media/capture/video/chromeos/stream_buffer_manager.h b/media/capture/video/chromeos/stream_buffer_manager.h
index a71db10..0d27b005 100644
--- a/media/capture/video/chromeos/stream_buffer_manager.h
+++ b/media/capture/video/chromeos/stream_buffer_manager.h
@@ -51,9 +51,12 @@
   VideoCaptureFormat GetStreamCaptureFormat(StreamType stream_type);
 
   // Checks if all streams are available. For output stream, it is available if
-  // it has free buffers.
+  // it has free buffers. For input stream, it is always available.
   bool HasFreeBuffers(const std::set<StreamType>& stream_types);
 
+  // Checks if the target stream types have been configured or not.
+  bool HasStreamsConfigured(std::initializer_list<StreamType> stream_types);
+
   // Sets up the stream context and allocate buffers according to the
   // configuration specified in |stream|.
   void SetUpStreamsAndBuffers(
@@ -63,13 +66,16 @@
 
   cros::mojom::Camera3StreamPtr GetStreamConfiguration(StreamType stream_type);
 
-  // Requests buffer for specific stream type.
-  base::Optional<BufferInfo> RequestBuffer(StreamType stream_type);
+  // Requests buffer for specific stream type. If the |buffer_id| is provided,
+  // it will use |buffer_id| as buffer id rather than using id from free
+  // buffers.
+  base::Optional<BufferInfo> RequestBuffer(StreamType stream_type,
+                                           base::Optional<uint64_t> buffer_id);
 
   // Releases buffer by marking it as free buffer.
   void ReleaseBuffer(StreamType stream_type, uint64_t buffer_id);
 
-  size_t GetNumberOfStreams();
+  bool IsReprocessSupported();
 
  private:
   friend class RequestManagerTest;
diff --git a/media/learning/common/learning_task_controller.h b/media/learning/common/learning_task_controller.h
index 65cd91f6..506216d 100644
--- a/media/learning/common/learning_task_controller.h
+++ b/media/learning/common/learning_task_controller.h
@@ -40,17 +40,18 @@
   LearningTaskController() = default;
   virtual ~LearningTaskController() = default;
 
-  // TODO(liberato): what is the scope of this id?  can it be local to whoever
-  // owns the LTC?  otherwise, consider making it an unguessable token.
-  // TODO(liberato): consider making a special id that means "i will not send a
+  // TODO(liberato): What is the scope of this id?  Can it be local to whoever
+  // owns the LTC?  Otherwise, consider making it an unguessable token.
+  // TODO(liberato): Consider making a special id that means "I will not send a
   // target value", to save a call to CancelObservation.
   using ObservationId = int32_t;
 
-  // new example.  Call this at the time one would try to predict the
-  // TargetValue.  This lets the framework snapshot any framework-provided
+  // Start a new observation.  Call this at the time one would try to predict
+  // the TargetValue.  This lets the framework snapshot any framework-provided
   // feature values at prediction time.  Later, if you want to turn these
-  // features into an example for training a model, then call the returned CB
-  // with the TargetValue and weight.  Otherwise, you may discard the CB.
+  // features into an example for training a model, then call
+  // CompleteObservation with the same id and an ObservationCompletion.
+  // Otherwise, call CancelObservation with |id|.
   // TODO(liberato): This should optionally take a callback to receive a
   // prediction for the FeatureVector.
   // TODO(liberato): See if this ends up generating smaller code with pass-by-
@@ -63,7 +64,7 @@
   virtual void CompleteObservation(ObservationId id,
                                    const ObservationCompletion& completion) = 0;
 
-  // Notify the LTC that no completion will be sent.
+  // Notify the LearningTaskController that no completion will be sent.
   virtual void CancelObservation(ObservationId id) = 0;
 
  private:
diff --git a/mojo/core/invitation_unittest.cc b/mojo/core/invitation_unittest.cc
index 58603897..dae047a 100644
--- a/mojo/core/invitation_unittest.cc
+++ b/mojo/core/invitation_unittest.cc
@@ -22,6 +22,7 @@
 #include "build/build_config.h"
 #include "mojo/core/test/mojo_test_base.h"
 #include "mojo/public/c/system/invitation.h"
+#include "mojo/public/cpp/platform/features.h"
 #include "mojo/public/cpp/platform/named_platform_channel.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/system/platform_handle.h"
@@ -78,6 +79,19 @@
   std::string value;
 #if defined(OS_FUCHSIA)
   channel->PrepareToPassRemoteEndpoint(&options->handles_to_transfer, &value);
+#elif defined(OS_MACOSX)
+  PlatformChannel::HandlePassingInfo info;
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac))
+    info = options->mach_ports_for_rendezvous;
+  else
+    info = options->fds_to_remap;
+
+  channel->PrepareToPassRemoteEndpoint(&info, &value);
+
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac))
+    options->mach_ports_for_rendezvous = info;
+  else
+    options->fds_to_remap = info;
 #elif defined(OS_POSIX)
   channel->PrepareToPassRemoteEndpoint(&options->fds_to_remap, &value);
 #elif defined(OS_WIN)
diff --git a/mojo/core/test/multiprocess_test_helper.cc b/mojo/core/test/multiprocess_test_helper.cc
index d4af9ff..f5723dc0 100644
--- a/mojo/core/test/multiprocess_test_helper.cc
+++ b/mojo/core/test/multiprocess_test_helper.cc
@@ -26,6 +26,7 @@
 #include "base/task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
+#include "mojo/public/cpp/platform/features.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/platform/platform_channel_endpoint.h"
 #include "mojo/public/cpp/platform/platform_channel_server_endpoint.h"
@@ -124,11 +125,20 @@
     case LaunchType::NAMED_CHILD:
     case LaunchType::NAMED_PEER: {
 #if defined(OS_POSIX)
-      base::FilePath temp_dir;
-      CHECK(base::PathService::Get(base::DIR_TEMP, &temp_dir));
-      server_name =
-          temp_dir.AppendASCII(base::NumberToString(base::RandUint64()))
-              .value();
+#if defined(OS_MACOSX)
+      if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+        server_name = NamedPlatformChannel::ServerNameFromUTF8(
+            "mojo.test." + base::NumberToString(base::RandUint64()));
+      } else {
+#endif  // defined(OS_MACOSX)
+        base::FilePath temp_dir;
+        CHECK(base::PathService::Get(base::DIR_TEMP, &temp_dir));
+        server_name =
+            temp_dir.AppendASCII(base::NumberToString(base::RandUint64()))
+                .value();
+#if defined(OS_MACOSX)
+      }
+#endif  // defined(OS_MACOSX)
 #elif defined(OS_WIN)
       server_name = base::NumberToString16(base::RandUint64());
 #else
diff --git a/mojo/public/cpp/platform/BUILD.gn b/mojo/public/cpp/platform/BUILD.gn
index c20f95bb..79c01760 100644
--- a/mojo/public/cpp/platform/BUILD.gn
+++ b/mojo/public/cpp/platform/BUILD.gn
@@ -38,6 +38,10 @@
     sources += [ "named_platform_channel_posix.cc" ]
   }
 
+  if (is_mac) {
+    sources += [ "named_platform_channel_mac.cc" ]
+  }
+
   if (is_fuchsia) {
     public_deps += [
       "//third_party/fuchsia-sdk/sdk:fdio",
diff --git a/mojo/public/cpp/platform/named_platform_channel_mac.cc b/mojo/public/cpp/platform/named_platform_channel_mac.cc
new file mode 100644
index 0000000..0a2df95
--- /dev/null
+++ b/mojo/public/cpp/platform/named_platform_channel_mac.cc
@@ -0,0 +1,83 @@
+// 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 "mojo/public/cpp/platform/named_platform_channel.h"
+
+#include <mach/port.h>
+#include <servers/bootstrap.h>
+
+#include "base/mac/foundation_util.h"
+#include "base/mac/mach_logging.h"
+#include "base/mac/scoped_mach_port.h"
+#include "base/rand_util.h"
+#include "base/strings/stringprintf.h"
+#include "mojo/public/cpp/platform/platform_channel.h"
+
+namespace mojo {
+
+namespace {
+
+std::string GetBootstrapName(const std::string& name) {
+  if (name.empty()) {
+    return base::StringPrintf("%s.mojo.%llu", base::mac::BaseBundleID(),
+                              base::RandUint64());
+  }
+  return name;
+}
+
+}  // namespace
+
+// TODO(crbug.com/932175): This namespace will go away and these methods
+// will be defined direclty on NamedPlatformChannel.
+namespace NamedPlatformChannelMac {
+
+// static
+COMPONENT_EXPORT(MOJO_CPP_PLATFORM)
+PlatformChannelServerEndpoint CreateServerEndpoint(
+    const NamedPlatformChannel::Options& options,
+    NamedPlatformChannel::ServerName* server_name) {
+  const std::string bootstrap_name = GetBootstrapName(options.server_name);
+  DCHECK_LT(bootstrap_name.length(),
+            static_cast<size_t>(BOOTSTRAP_MAX_NAME_LEN));
+
+  base::mac::ScopedMachReceiveRight receive_right;
+  kern_return_t kr = bootstrap_check_in(
+      bootstrap_port, bootstrap_name.c_str(),
+      base::mac::ScopedMachReceiveRight::Receiver(receive_right).get());
+  if (kr != KERN_SUCCESS) {
+    BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_check_in " << bootstrap_name;
+    return PlatformChannelServerEndpoint();
+  }
+
+  // The mpl_qlimit specified here should stay in sync with PlatformChannel.
+  mach_port_limits_t limits{};
+  limits.mpl_qlimit = MACH_PORT_QLIMIT_LARGE;
+  kr = mach_port_set_attributes(
+      mach_task_self(), receive_right.get(), MACH_PORT_LIMITS_INFO,
+      reinterpret_cast<mach_port_info_t>(&limits), MACH_PORT_LIMITS_INFO_COUNT);
+  MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_set_attributes";
+
+  *server_name = bootstrap_name;
+  return PlatformChannelServerEndpoint(
+      PlatformHandle(std::move(receive_right)));
+}
+
+// static
+COMPONENT_EXPORT(MOJO_CPP_PLATFORM)
+PlatformChannelEndpoint CreateClientEndpoint(
+    const NamedPlatformChannel::ServerName& server_name) {
+  base::mac::ScopedMachSendRight send_right;
+  kern_return_t kr = bootstrap_look_up(
+      bootstrap_port, server_name.c_str(),
+      base::mac::ScopedMachSendRight::Receiver(send_right).get());
+  if (kr != KERN_SUCCESS) {
+    BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_look_up " << server_name;
+    return PlatformChannelEndpoint();
+  }
+
+  return PlatformChannelEndpoint(PlatformHandle(std::move(send_right)));
+}
+
+}  // namespace NamedPlatformChannelMac
+}  // namespace mojo
diff --git a/mojo/public/cpp/platform/named_platform_channel_posix.cc b/mojo/public/cpp/platform/named_platform_channel_posix.cc
index 9082ac4d..d5f82d86 100644
--- a/mojo/public/cpp/platform/named_platform_channel_posix.cc
+++ b/mojo/public/cpp/platform/named_platform_channel_posix.cc
@@ -15,6 +15,8 @@
 #include "base/posix/eintr_wrapper.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "build/build_config.h"
+#include "mojo/public/cpp/platform/features.h"
 
 namespace mojo {
 
@@ -77,10 +79,26 @@
 
 }  // namespace
 
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+// Temporarily forward declare named_platform_channel_mac.cc symbols.
+namespace NamedPlatformChannelMac {
+PlatformChannelServerEndpoint CreateServerEndpoint(
+    const NamedPlatformChannel::Options& options,
+    NamedPlatformChannel::ServerName* server_name);
+PlatformChannelEndpoint CreateClientEndpoint(
+    const NamedPlatformChannel::ServerName& server_name);
+}  // namespace NamedPlatformChannelMac
+#endif
+
 // static
 PlatformChannelServerEndpoint NamedPlatformChannel::CreateServerEndpoint(
     const Options& options,
     ServerName* server_name) {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+    return NamedPlatformChannelMac::CreateServerEndpoint(options, server_name);
+  }
+#endif
   ServerName name = options.server_name;
   if (name.empty())
     name = GenerateRandomServerName(options);
@@ -128,6 +146,11 @@
 // static
 PlatformChannelEndpoint NamedPlatformChannel::CreateClientEndpoint(
     const ServerName& server_name) {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+    return NamedPlatformChannelMac::CreateClientEndpoint(server_name);
+  }
+#endif
   DCHECK(!server_name.empty());
 
   struct sockaddr_un unix_addr;
diff --git a/mojo/public/cpp/platform/platform_channel.cc b/mojo/public/cpp/platform/platform_channel.cc
index fd73f96..8502ae3 100644
--- a/mojo/public/cpp/platform/platform_channel.cc
+++ b/mojo/public/cpp/platform/platform_channel.cc
@@ -7,6 +7,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <string>
+#include <utility>
 
 #include "base/logging.h"
 #include "base/rand_util.h"
@@ -15,6 +16,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "mojo/public/cpp/platform/features.h"
 
 #if defined(OS_WIN)
 #include <windows.h>
@@ -35,6 +37,13 @@
 #include "base/posix/global_descriptors.h"
 #endif
 
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+#include <mach/port.h>
+
+#include "base/mac/mach_logging.h"
+#include "base/mac/scoped_mach_port.h"
+#endif
+
 #if defined(OS_POSIX) && !defined(OS_NACL_SFI)
 #include <sys/socket.h>
 #elif defined(OS_NACL_SFI)
@@ -95,6 +104,28 @@
 }
 #elif defined(OS_POSIX)
 
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+// TODO(crbug.com/932175): This will be renamed CreateChannel().
+void CreateMachChannel(PlatformHandle* local_endpoint,
+                       PlatformHandle* remote_endpoint) {
+  // Mach messaging is simplex; and in order to enable full-duplex
+  // communication, the Mojo channel implementation performs an internal
+  // handshake with its peer to establish two sets of Mach receive and send
+  // rights. The handshake process starts with the creation of one
+  // PlatformChannel endpoint.
+  base::mac::ScopedMachReceiveRight receive;
+  base::mac::ScopedMachSendRight send;
+  // The mpl_qlimit specified here should stay in sync with
+  // NamedPlatformChannel.
+  CHECK(base::mac::CreateMachPort(&receive, &send, MACH_PORT_QLIMIT_LARGE));
+
+  // In a reverse of Mach messaging semantics, in Mojo the "local" endpoint is
+  // the send right, while the "remote" end is the receive right.
+  *local_endpoint = PlatformHandle(std::move(send));
+  *remote_endpoint = PlatformHandle(std::move(receive));
+}
+#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
+
 #if defined(OS_ANDROID)
 // Leave room for any other descriptors defined in content for example.
 // TODO(https://crbug.com/676442): Consider changing base::GlobalDescriptors to
@@ -114,6 +145,11 @@
 
 void CreateChannel(PlatformHandle* local_endpoint,
                    PlatformHandle* remote_endpoint) {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+    return CreateMachChannel(local_endpoint, remote_endpoint);
+  }
+#endif
   int fds[2];
 #if defined(OS_NACL_SFI)
   PCHECK(imc_socketpair(fds) == 0);
@@ -163,9 +199,12 @@
 
 PlatformChannel& PlatformChannel::operator=(PlatformChannel&& other) = default;
 
-void PlatformChannel::PrepareToPassRemoteEndpoint(HandlePassingInfo* info,
+void PlatformChannel::PrepareToPassRemoteEndpoint(HandlePassingInfo* info_input,
                                                   std::string* value) {
+#if !defined(OS_MACOSX) || defined(OS_IOS)
+  auto* info = info_input;
   DCHECK(info);
+#endif
   DCHECK(value);
   DCHECK(remote_endpoint_.is_valid());
 
@@ -183,6 +222,26 @@
   info->emplace_back(fd, mapped_fd);
   *value = base::NumberToString(mapped_fd);
 #elif defined(OS_POSIX)
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+    auto* info = static_cast<base::MachPortsForRendezvous*>(info_input);
+    DCHECK(remote_endpoint_.platform_handle().is_mach_receive());
+    base::mac::ScopedMachReceiveRight receive_right =
+        remote_endpoint_.TakePlatformHandle().TakeMachReceiveRight();
+    base::MachPortsForRendezvous::key_type rendezvous_key = 0;
+    do {
+      rendezvous_key =
+          static_cast<decltype(rendezvous_key)>(base::RandUint64());
+    } while (info->find(rendezvous_key) != info->end());
+    auto it = info->insert(std::make_pair(
+        rendezvous_key, base::MachRendezvousPort(std::move(receive_right))));
+    DCHECK(it.second) << "Failed to insert port for rendezvous.";
+    *value = base::NumberToString(rendezvous_key);
+    return;
+  }
+
+  auto* info = static_cast<base::FileHandleMappingVector*>(info_input);
+#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
   // Arbitrary sanity check to ensure the loop below terminates reasonably
   // quickly.
   CHECK_LT(info->size(), 1000u);
@@ -215,6 +274,19 @@
   PrepareToPassRemoteEndpoint(&options->handles_to_inherit, command_line);
 #elif defined(OS_FUCHSIA)
   PrepareToPassRemoteEndpoint(&options->handles_to_transfer, command_line);
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+  HandlePassingInfo info;
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac))
+    info = options->mach_ports_for_rendezvous;
+  else
+    info = options->fds_to_remap;
+
+  PrepareToPassRemoteEndpoint(&info, command_line);
+
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac))
+    options->mach_ports_for_rendezvous = info;
+  else
+    options->fds_to_remap = info;
 #elif defined(OS_POSIX)
   PrepareToPassRemoteEndpoint(&options->fds_to_remap, command_line);
 #else
@@ -262,6 +334,26 @@
   return PlatformChannelEndpoint(PlatformHandle(
       base::ScopedFD(base::GlobalDescriptors::GetInstance()->Get(key))));
 #elif defined(OS_POSIX)
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+  if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+    auto* client = base::MachPortRendezvousClient::GetInstance();
+    if (!client) {
+      DLOG(ERROR) << "Mach rendezvous failed.";
+      return PlatformChannelEndpoint();
+    }
+    uint32_t rendezvous_key = 0;
+    if (value.empty() || !base::StringToUint(value, &rendezvous_key)) {
+      DLOG(ERROR) << "Invalid PlatformChannel rendezvous key.";
+      return PlatformChannelEndpoint();
+    }
+    auto receive = client->TakeReceiveRight(rendezvous_key);
+    if (!receive.is_valid()) {
+      DLOG(ERROR) << "Invalid PlatformChannel receive right.";
+      return PlatformChannelEndpoint();
+    }
+    return PlatformChannelEndpoint(PlatformHandle(std::move(receive)));
+  }
+#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
   int fd = -1;
   if (value.empty() || !base::StringToInt(value, &fd) ||
       fd < base::GlobalDescriptors::kBaseDescriptor) {
diff --git a/mojo/public/cpp/platform/platform_channel.h b/mojo/public/cpp/platform/platform_channel.h
index 534c6bbf..d31668a3 100644
--- a/mojo/public/cpp/platform/platform_channel.h
+++ b/mojo/public/cpp/platform/platform_channel.h
@@ -41,6 +41,18 @@
   using HandlePassingInfo = base::HandlesToInheritVector;
 #elif defined(OS_FUCHSIA)
   using HandlePassingInfo = base::HandlesToTransferVector;
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+  // This type represents a union between MachPortsForRendezvous and
+  // FileHandleMappingVector, so that the type to use can be determined at run-
+  // time.
+  // TODO(crbug.com/932175): This will become a typedef to
+  // base::MachPortsForRendezvous in the future.
+  class HandlePassingInfo : public base::MachPortsForRendezvous,
+                            public base::FileHandleMappingVector {
+   public:
+    using base::MachPortsForRendezvous::operator=;
+    using base::FileHandleMappingVector::operator=;
+  };
 #elif defined(OS_POSIX)
   using HandlePassingInfo = base::FileHandleMappingVector;
 #else
diff --git a/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
index fa6bd2e7..98b6f1fb 100644
--- a/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
@@ -3,7 +3,7 @@
  * @const { {{constant.kind|lite_closure_type_with_nullability}} }
  * @export
  */
-{{module.namespace}}.{{struct.name}}.{{constant.name}} =
+{{module.namespace}}.{{struct.name}}_{{constant.name}} =
     {{constant.value|expression_to_text_lite}};
 {%  endfor %}
 
diff --git a/net/BUILD.gn b/net/BUILD.gn
index ac6024ea..08d0947 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -391,7 +391,6 @@
     "//net/dns",
     "//net/dns:dns_client",
     "//net/dns:host_resolver",
-    "//net/dns:host_resolver_impl",
     "//net/dns:mdns_client",
     "//net/dns/public",
   ]
@@ -400,7 +399,6 @@
     "//net/dns",
     "//net/dns:dns_client",
     "//net/dns:host_resolver",
-    "//net/dns:host_resolver_impl",
     "//net/dns:mdns_client",
     "//net/dns/public",
   ]
@@ -454,6 +452,7 @@
       "base/hex_utils.h",
       "base/host_mapping_rules.cc",
       "base/host_mapping_rules.h",
+      "base/http_user_agent_settings.h",
       "base/ip_pattern.cc",
       "base/ip_pattern.h",
       "base/layered_network_delegate.cc",
@@ -1102,6 +1101,7 @@
       "spdy/platform/impl/spdy_export_impl.h",
       "spdy/platform/impl/spdy_flags_impl.cc",
       "spdy/platform/impl/spdy_flags_impl.h",
+      "spdy/platform/impl/spdy_logging_impl.h",
       "spdy/platform/impl/spdy_macros_impl.h",
       "spdy/platform/impl/spdy_mem_slice_impl.cc",
       "spdy/platform/impl/spdy_mem_slice_impl.h",
@@ -1719,7 +1719,6 @@
       "third_party/quiche/src/spdy/platform/api/spdy_unsafe_arena.h",
       "url_request/data_protocol_handler.cc",
       "url_request/data_protocol_handler.h",
-      "url_request/http_user_agent_settings.h",
       "url_request/redirect_info.cc",
       "url_request/redirect_info.h",
       "url_request/redirect_util.cc",
@@ -2226,7 +2225,6 @@
     "//net/dns",
     "//net/dns:dns_client",
     "//net/dns:host_resolver",
-    "//net/dns:host_resolver_impl",
     "//net/dns:mdns_client",
     "//net/dns/public",
   ]
@@ -2294,7 +2292,6 @@
     "//net/dns",
     "//net/dns:dns_client",
     "//net/dns:host_resolver",
-    "//net/dns:host_resolver_impl",
     "//net/dns:mdns_client",
     "//net/dns/public",
   ]
@@ -3061,8 +3058,8 @@
       "third_party/quic/core/quic_epoll_connection_helper.h",
       "third_party/quic/core/quic_packet_reader.cc",
       "third_party/quic/core/quic_packet_reader.h",
-      "third_party/quic/platform/api/quic_default_buffer_allocator.h",
       "third_party/quic/platform/api/quic_default_proof_providers.h",
+      "third_party/quic/platform/api/quic_stream_buffer_allocator.h",
       "third_party/quic/platform/api/quic_system_event_loop.h",
       "third_party/quic/platform/impl/batch_writer/quic_batch_writer_base.cc",
       "third_party/quic/platform/impl/batch_writer/quic_batch_writer_base.h",
@@ -3072,7 +3069,6 @@
       "third_party/quic/platform/impl/batch_writer/quic_gso_batch_writer.h",
       "third_party/quic/platform/impl/batch_writer/quic_sendmmsg_batch_writer.cc",
       "third_party/quic/platform/impl/batch_writer/quic_sendmmsg_batch_writer.h",
-      "third_party/quic/platform/impl/quic_default_buffer_allocator_impl.h",
       "third_party/quic/platform/impl/quic_default_proof_providers_impl.cc",
       "third_party/quic/platform/impl/quic_default_proof_providers_impl.h",
       "third_party/quic/platform/impl/quic_epoll_clock.cc",
@@ -3081,6 +3077,7 @@
       "third_party/quic/platform/impl/quic_linux_socket_utils.h",
       "third_party/quic/platform/impl/quic_socket_utils.cc",
       "third_party/quic/platform/impl/quic_socket_utils.h",
+      "third_party/quic/platform/impl/quic_stream_buffer_allocator_impl.h",
       "third_party/quic/platform/impl/quic_system_event_loop_impl.h",
       "third_party/quic/tools/quic_client.cc",
       "third_party/quic/tools/quic_client.h",
diff --git a/net/url_request/http_user_agent_settings.h b/net/base/http_user_agent_settings.h
similarity index 82%
rename from net/url_request/http_user_agent_settings.h
rename to net/base/http_user_agent_settings.h
index 487f235..eb3b2d0 100644
--- a/net/url_request/http_user_agent_settings.h
+++ b/net/base/http_user_agent_settings.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef NET_URL_REQUEST_HTTP_USER_AGENT_SETTINGS_H_
-#define NET_URL_REQUEST_HTTP_USER_AGENT_SETTINGS_H_
+#ifndef NET_BASE_HTTP_USER_AGENT_SETTINGS_H_
+#define NET_BASE_HTTP_USER_AGENT_SETTINGS_H_
 
 #include <string>
 
@@ -31,4 +31,4 @@
 
 }  // namespace net
 
-#endif  // NET_URL_REQUEST_HTTP_USER_AGENT_SETTINGS_H_
+#endif  // NET_BASE_HTTP_USER_AGENT_SETTINGS_H_
diff --git a/net/base/network_change_notifier.h b/net/base/network_change_notifier.h
index 63e661a4..997fc2b 100644
--- a/net/base/network_change_notifier.h
+++ b/net/base/network_change_notifier.h
@@ -550,7 +550,7 @@
   static ConnectionType ConnectionTypeFromInterfaces();
 
  private:
-  friend class HostResolverImplDnsTest;
+  friend class HostResolverManagerDnsTest;
   friend class NetworkChangeNotifierAndroidTest;
   friend class NetworkChangeNotifierLinuxTest;
   friend class NetworkChangeNotifierWinTest;
diff --git a/net/data/fuzzer_dictionaries/net_host_resolver_impl_fuzzer.dict b/net/data/fuzzer_dictionaries/net_host_resolver_manager_fuzzer.dict
similarity index 100%
rename from net/data/fuzzer_dictionaries/net_host_resolver_impl_fuzzer.dict
rename to net/data/fuzzer_dictionaries/net_host_resolver_manager_fuzzer.dict
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
index 0e71ba1..ac1ff228 100644
--- a/net/dns/BUILD.gn
+++ b/net/dns/BUILD.gn
@@ -55,7 +55,8 @@
       "dns_transaction.cc",
       "host_cache.cc",
       "host_resolver.cc",
-      "host_resolver_impl.cc",
+      "host_resolver_manager.cc",
+      "host_resolver_manager.h",
       "host_resolver_mdns_listener_impl.cc",
       "host_resolver_mdns_listener_impl.h",
       "host_resolver_mdns_task.cc",
@@ -105,7 +106,6 @@
   public_deps = [
     ":dns_client",
     ":host_resolver",
-    ":host_resolver_impl",
     ":mdns_client",
     "//net:net_public_deps",
   ]
@@ -113,7 +113,6 @@
   allow_circular_includes_from = [
     ":dns_client",
     ":host_resolver",
-    ":host_resolver_impl",
     ":mdns_client",
   ]
 }
@@ -131,7 +130,6 @@
   # restriction.
   visibility = [
     ":dns",
-    ":host_resolver_impl",
     ":mdns_client",
     "//net",
   ]
@@ -196,51 +194,6 @@
   ]
 }
 
-# Overridable implementation details of HostResolver.
-source_set("host_resolver_impl") {
-  # Due to circular dependencies, should only be depended on through //net.
-  # Limit visibility to //net and other source_sets with the same access
-  # restriction.
-  visibility = [
-    ":dns",
-    "//net",
-  ]
-
-  # Whitelist-only access so we can keep track of all usage external to the
-  # network stack.
-  friend = [
-    # chromeos/network/network_change_notifier_posix.cc
-    # ChromeOS-specific change notifier with some overrides for DnsConfigService
-    # TODO(crbug.com/882610): Remove/cleanup once we figure out servicification.
-    "//chromeos/network",
-
-    # Network stack/service
-    "//components/cronet/*",
-    "//net/*",
-    "//services/network:tests",
-  ]
-
-  sources = []
-  public = []
-
-  if (!is_nacl) {
-    sources += [ "host_resolver_impl.h" ]
-
-    if (is_posix || is_fuchsia) {
-      sources += [ "dns_config_service_posix.h" ]
-    }
-  }
-
-  deps = [
-    ":host_resolver",
-    "//net:net_deps",
-    "//net/dns/public",
-  ]
-  public_deps = [
-    "//net:net_public_deps",
-  ]
-}
-
 # DnsClient interfaces. Primarily intended as part of the implementation of the
 # standard HostResolver interface, but can be used as an alternative external
 # interface for advanced usage.
@@ -368,7 +321,7 @@
     "dns_transaction_unittest.cc",
     "dns_util_unittest.cc",
     "host_cache_unittest.cc",
-    "host_resolver_impl_unittest.cc",
+    "host_resolver_manager_unittest.cc",
     "mapped_host_resolver_unittest.cc",
     "record_parsed_unittest.cc",
     "record_rdata_unittest.cc",
@@ -493,9 +446,9 @@
   dict = "//net/data/fuzzer_dictionaries/net_dns_record_fuzzer.dict"
 }
 
-fuzzer_test("net_host_resolver_impl_fuzzer") {
+fuzzer_test("net_host_resolver_manager_fuzzer") {
   sources = [
-    "host_resolver_impl_fuzzer.cc",
+    "host_resolver_manager_fuzzer.cc",
   ]
   deps = [
     "//base",
@@ -503,7 +456,7 @@
     "//net:net_fuzzer_test_support",
     "//net:test_support",
   ]
-  dict = "//net/data/fuzzer_dictionaries/net_host_resolver_impl_fuzzer.dict"
+  dict = "//net/data/fuzzer_dictionaries/net_host_resolver_manager_fuzzer.dict"
 }
 
 if (is_win) {
diff --git a/net/dns/context_host_resolver.cc b/net/dns/context_host_resolver.cc
index f7b74aa7..7802c13 100644
--- a/net/dns/context_host_resolver.cc
+++ b/net/dns/context_host_resolver.cc
@@ -10,12 +10,13 @@
 #include "base/time/tick_clock.h"
 #include "net/dns/dns_client.h"
 #include "net/dns/dns_config.h"
-#include "net/dns/host_resolver_impl.h"
+#include "net/dns/host_resolver_manager.h"
 #include "net/dns/host_resolver_proc.h"
 
 namespace net {
 
-ContextHostResolver::ContextHostResolver(std::unique_ptr<HostResolverImpl> impl)
+ContextHostResolver::ContextHostResolver(
+    std::unique_ptr<HostResolverManager> impl)
     : impl_(std::move(impl)) {}
 
 ContextHostResolver::~ContextHostResolver() = default;
diff --git a/net/dns/context_host_resolver.h b/net/dns/context_host_resolver.h
index c200ded..fddfaa2 100644
--- a/net/dns/context_host_resolver.h
+++ b/net/dns/context_host_resolver.h
@@ -19,10 +19,10 @@
 
 class DnsClient;
 struct DnsConfig;
-class HostResolverImpl;
+class HostResolverManager;
 struct ProcTaskParams;
 
-// Wrapper for HostResolverImpl that sets per-context parameters for created
+// Wrapper for HostResolverManager that sets per-context parameters for created
 // requests. Except for tests, typically only interacted with through the
 // HostResolver interface.
 //
@@ -34,7 +34,7 @@
  public:
   // Creates a ContextHostResolver that forwards all of its requests through
   // |impl|.
-  explicit ContextHostResolver(std::unique_ptr<HostResolverImpl> impl);
+  explicit ContextHostResolver(std::unique_ptr<HostResolverManager> impl);
   ~ContextHostResolver() override;
 
   // HostResolver methods:
@@ -74,7 +74,7 @@
  private:
   // TODO(crbug.com/934402): Make this a non-owned pointer to the singleton
   // resolver.
-  std::unique_ptr<HostResolverImpl> impl_;
+  std::unique_ptr<HostResolverManager> impl_;
 };
 
 }  // namespace net
diff --git a/net/dns/fuzzed_context_host_resolver.cc b/net/dns/fuzzed_context_host_resolver.cc
index 933f626..85cc76c 100644
--- a/net/dns/fuzzed_context_host_resolver.cc
+++ b/net/dns/fuzzed_context_host_resolver.cc
@@ -29,7 +29,7 @@
 #include "net/dns/dns_client.h"
 #include "net/dns/dns_config.h"
 #include "net/dns/dns_hosts.h"
-#include "net/dns/host_resolver_impl.h"
+#include "net/dns/host_resolver_manager.h"
 #include "net/dns/host_resolver_proc.h"
 #include "net/dns/mdns_client.h"
 #include "net/dns/public/util.h"
@@ -297,13 +297,13 @@
   base::FuzzedDataProvider* const data_provider_;
 };
 
-class FuzzedHostResolverImpl : public HostResolverImpl {
+class FuzzedHostResolverManager : public HostResolverManager {
  public:
   // |data_provider| and |net_log| must outlive the FuzzedHostResolver.
-  FuzzedHostResolverImpl(const Options& options,
-                         NetLog* net_log,
-                         base::FuzzedDataProvider* data_provider)
-      : HostResolverImpl(options, net_log),
+  FuzzedHostResolverManager(const Options& options,
+                            NetLog* net_log,
+                            base::FuzzedDataProvider* data_provider)
+      : HostResolverManager(options, net_log),
         data_provider_(data_provider),
         is_ipv6_reachable_(data_provider->ConsumeBool()),
         data_provider_weak_factory_(data_provider) {
@@ -318,10 +318,10 @@
         std::make_unique<FuzzedMdnsSocketFactory>(data_provider_));
   }
 
-  ~FuzzedHostResolverImpl() override = default;
+  ~FuzzedHostResolverManager() override = default;
 
  private:
-  // HostResolverImpl implementation:
+  // HostResolverManager implementation:
   bool IsGloballyReachable(const IPAddress& dest,
                            const NetLogWithSource& net_log) override {
     return is_ipv6_reachable_;
@@ -338,7 +338,7 @@
 
   base::WeakPtrFactory<base::FuzzedDataProvider> data_provider_weak_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(FuzzedHostResolverImpl);
+  DISALLOW_COPY_AND_ASSIGN(FuzzedHostResolverManager);
 };
 
 }  // namespace
@@ -348,9 +348,9 @@
     NetLog* net_log,
     base::FuzzedDataProvider* data_provider)
     : ContextHostResolver(
-          std::make_unique<FuzzedHostResolverImpl>(options,
-                                                   net_log,
-                                                   data_provider)),
+          std::make_unique<FuzzedHostResolverManager>(options,
+                                                      net_log,
+                                                      data_provider)),
       data_provider_(data_provider),
       socket_factory_(data_provider),
       net_log_(net_log) {}
diff --git a/net/dns/host_resolver.cc b/net/dns/host_resolver.cc
index 2f13cc4..32dffe4 100644
--- a/net/dns/host_resolver.cc
+++ b/net/dns/host_resolver.cc
@@ -19,7 +19,7 @@
 #include "net/dns/dns_client.h"
 #include "net/dns/dns_util.h"
 #include "net/dns/host_cache.h"
-#include "net/dns/host_resolver_impl.h"
+#include "net/dns/host_resolver_manager.h"
 
 namespace net {
 
@@ -153,7 +153,7 @@
     const Options& options,
     NetLog* net_log) {
   return std::make_unique<ContextHostResolver>(
-      std::make_unique<HostResolverImpl>(options, net_log));
+      std::make_unique<HostResolverManager>(options, net_log));
 }
 
 // static
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_manager.cc
similarity index 94%
rename from net/dns/host_resolver_impl.cc
rename to net/dns/host_resolver_manager.cc
index 7e95f8c6..9a997a2 100644
--- a/net/dns/host_resolver_impl.cc
+++ b/net/dns/host_resolver_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "net/dns/host_resolver_impl.h"
+#include "net/dns/host_resolver_manager.h"
 
 #if defined(OS_WIN)
 #include <Winsock2.h>
@@ -118,9 +118,9 @@
 const int kIPv6ProbePeriodMs = 1000;
 
 // Google DNS address used for IPv6 probes.
-const uint8_t kIPv6ProbeAddress[] =
-    { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 };
+const uint8_t kIPv6ProbeAddress[] = {0x20, 0x01, 0x48, 0x60, 0x48, 0x60,
+                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                     0x00, 0x00, 0x88, 0x88};
 
 enum DnsResolveStatus {
   RESOLVE_STATUS_DNS_SUCCESS = 0,
@@ -159,11 +159,11 @@
   const size_t kSuffixLenTrimmed = kSuffixLen - 1;
   if (hostname.back() == '.') {
     return hostname.size() > kSuffixLen &&
-        !hostname.compare(hostname.size() - kSuffixLen, kSuffixLen, kSuffix);
+           !hostname.compare(hostname.size() - kSuffixLen, kSuffixLen, kSuffix);
   }
   return hostname.size() > kSuffixLenTrimmed &&
-      !hostname.compare(hostname.size() - kSuffixLenTrimmed, kSuffixLenTrimmed,
-                        kSuffix, kSuffixLenTrimmed);
+         !hostname.compare(hostname.size() - kSuffixLenTrimmed,
+                           kSuffixLenTrimmed, kSuffix, kSuffixLenTrimmed);
 }
 
 bool ConfigureAsyncDnsNoFallbackFieldTrial() {
@@ -236,8 +236,7 @@
   }
 
   bool result = true;
-  for (struct ifaddrs* interface = interface_addr;
-       interface != NULL;
+  for (struct ifaddrs* interface = interface_addr; interface != NULL;
        interface = interface->ifa_next) {
     if (!(IFF_UP & interface->ifa_flags))
       continue;
@@ -287,7 +286,7 @@
                   os_error,
                   0,  // Use default language.
                   (LPWSTR)&error_string,
-                  0,  // Buffer size.
+                  0,   // Buffer size.
                   0);  // Arguments (unused).
     dict->SetString("os_error_string", base::WideToUTF8(error_string));
     LocalFree(error_string);
@@ -329,7 +328,7 @@
   return std::move(dict);
 }
 
-// Creates NetLog parameters for the creation of a HostResolverImpl::Job.
+// Creates NetLog parameters for the creation of a HostResolverManager::Job.
 std::unique_ptr<base::Value> NetLogJobCreationCallback(
     const NetLogSource& source,
     const std::string* host,
@@ -401,13 +400,9 @@
     memset(counts_, 0, sizeof(counts_));
   }
 
-  RequestPriority highest_priority() const {
-    return highest_priority_;
-  }
+  RequestPriority highest_priority() const { return highest_priority_; }
 
-  size_t total_count() const {
-    return total_count_;
-  }
+  size_t total_count() const { return total_count_; }
 
   void Add(RequestPriority req_priority) {
     ++total_count_;
@@ -481,7 +476,7 @@
   return true;
 }
 
-const unsigned HostResolverImpl::kMaximumDnsFailures = 16;
+const unsigned HostResolverManager::kMaximumDnsFailures = 16;
 
 // Holds the callback and request parameters for an outstanding request.
 //
@@ -493,14 +488,14 @@
 // other. Care must be taken to clear the corresponding pointer when
 // cancellation is initiated by the Job (OnJobCancelled) vs by the end user
 // (~RequestImpl).
-class HostResolverImpl::RequestImpl
+class HostResolverManager::RequestImpl
     : public HostResolver::ResolveHostRequest,
-      public base::LinkNode<HostResolverImpl::RequestImpl> {
+      public base::LinkNode<HostResolverManager::RequestImpl> {
  public:
   RequestImpl(const NetLogWithSource& source_net_log,
               const HostPortPair& request_host,
               const base::Optional<ResolveHostParameters>& optional_parameters,
-              base::WeakPtr<HostResolverImpl> resolver)
+              base::WeakPtr<HostResolverManager> resolver)
       : source_net_log_(source_net_log),
         request_host_(request_host),
         parameters_(optional_parameters ? optional_parameters.value()
@@ -656,7 +651,7 @@
 
   // The resolve job that this request is dependent on.
   Job* job_;
-  base::WeakPtr<HostResolverImpl> resolver_;
+  base::WeakPtr<HostResolverManager> resolver_;
 
   // The user's callback to invoke when the request completes.
   CompletionOnceCallback callback_;
@@ -685,7 +680,7 @@
 //
 // TODO(szym): Move to separate source file for testing and mocking.
 //
-class HostResolverImpl::ProcTask {
+class HostResolverManager::ProcTask {
  public:
   typedef base::OnceCallback<void(int net_error, const AddressList& addr_list)>
       Callback;
@@ -900,7 +895,7 @@
 // transactions are scheduled separately and started separately.
 //
 // TODO(szym): This could be moved to separate source file as well.
-class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> {
+class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
  public:
   class Delegate {
    public:
@@ -1388,12 +1383,12 @@
 //-----------------------------------------------------------------------------
 
 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch.
-class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
-                              public HostResolverImpl::DnsTask::Delegate {
+class HostResolverManager::Job : public PrioritizedDispatcher::Job,
+                                 public HostResolverManager::DnsTask::Delegate {
  public:
   // Creates new job for |key| where |request_net_log| is bound to the
   // request that spawned it.
-  Job(const base::WeakPtr<HostResolverImpl>& resolver,
+  Job(const base::WeakPtr<HostResolverManager>& resolver,
       const Key& key,
       RequestPriority priority,
       scoped_refptr<base::TaskRunner> proc_task_runner,
@@ -1556,8 +1551,8 @@
     }
   }
 
-  // Called by HostResolverImpl when this job is evicted due to queue overflow.
-  // Completes all requests and destroys the job.
+  // Called by HostResolverManager when this job is evicted due to queue
+  // overflow. Completes all requests and destroys the job.
   void OnEvicted() {
     DCHECK(!is_running());
     DCHECK(is_queued());
@@ -1585,9 +1580,7 @@
 
   const Key& key() const { return key_; }
 
-  bool is_queued() const {
-    return !handle_.is_null();
-  }
+  bool is_queued() const { return !handle_.is_null(); }
 
   bool is_running() const {
     return is_dns_running() || is_mdns_running() || is_proc_running();
@@ -1809,7 +1802,7 @@
     }
   }
 
-  // HostResolverImpl::DnsTask::Delegate implementation:
+  // HostResolverManager::DnsTask::Delegate implementation:
 
   void OnDnsTaskComplete(base::TimeTicks start_time,
                          const HostCache::Entry& results,
@@ -2069,9 +2062,7 @@
   }
 
   // Number of non-canceled requests in |requests_|.
-  size_t num_active_requests() const {
-    return priority_tracker_.total_count();
-  }
+  size_t num_active_requests() const { return priority_tracker_.total_count(); }
 
   bool is_dns_running() const { return !!dns_task_; }
 
@@ -2079,7 +2070,7 @@
 
   bool is_proc_running() const { return !!proc_task_; }
 
-  base::WeakPtr<HostResolverImpl> resolver_;
+  base::WeakPtr<HostResolverManager> resolver_;
 
   Key key_;
 
@@ -2114,7 +2105,7 @@
   // All Requests waiting for the result of this Job. Some can be canceled.
   base::LinkedList<RequestImpl> requests_;
 
-  // A handle used in |HostResolverImpl::dispatcher_|.
+  // A handle used in |HostResolverManager::dispatcher_|.
   PrioritizedDispatcher::Handle handle_;
 
   base::WeakPtrFactory<Job> weak_ptr_factory_;
@@ -2122,7 +2113,8 @@
 
 //-----------------------------------------------------------------------------
 
-HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log)
+HostResolverManager::HostResolverManager(const Options& options,
+                                         NetLog* net_log)
     : max_queued_jobs_(0),
       proc_params_(NULL, options.max_retry_attempts),
       net_log_(net_log),
@@ -2178,7 +2170,7 @@
   allow_fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial();
 }
 
-HostResolverImpl::~HostResolverImpl() {
+HostResolverManager::~HostResolverManager() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // Prevent the dispatcher from starting new jobs.
   dispatcher_->SetLimitsToZero();
@@ -2191,7 +2183,7 @@
   NetworkChangeNotifier::RemoveDNSObserver(this);
 }
 
-void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) {
+void HostResolverManager::SetDnsClient(std::unique_ptr<DnsClient> dns_client) {
   // DnsClient and config must be updated before aborting DnsTasks, since doing
   // so may start new jobs.
   dns_client_ = std::move(dns_client);
@@ -2211,7 +2203,7 @@
 }
 
 std::unique_ptr<HostResolver::ResolveHostRequest>
-HostResolverImpl::CreateRequest(
+HostResolverManager::CreateRequest(
     const HostPortPair& host,
     const NetLogWithSource& net_log,
     const base::Optional<ResolveHostParameters>& optional_parameters) {
@@ -2220,8 +2212,8 @@
 }
 
 std::unique_ptr<HostResolver::MdnsListener>
-HostResolverImpl::CreateMdnsListener(const HostPortPair& host,
-                                     DnsQueryType query_type) {
+HostResolverManager::CreateMdnsListener(const HostPortPair& host,
+                                        DnsQueryType query_type) {
   DCHECK_NE(DnsQueryType::UNSPECIFIED, query_type);
 
   auto listener =
@@ -2235,25 +2227,25 @@
   return listener;
 }
 
-void HostResolverImpl::SetDnsClientEnabled(bool enabled) {
+void HostResolverManager::SetDnsClientEnabled(bool enabled) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 #if defined(ENABLE_BUILT_IN_DNS)
   if (enabled && !dns_client_) {
     SetDnsClient(DnsClient::CreateClient(net_log_));
   } else if (!enabled && dns_client_) {
-    SetDnsClient(std::unique_ptr<DnsClient>());
+    SetDnsClient(nullptr);
   }
 #endif
 }
 
-HostCache* HostResolverImpl::GetHostCache() {
+HostCache* HostResolverManager::GetHostCache() {
   return cache_.get();
 }
 
-bool HostResolverImpl::HasCached(base::StringPiece hostname,
-                                 HostCache::Entry::Source* source_out,
-                                 HostCache::EntryStaleness* stale_out,
-                                 bool* secure_out) const {
+bool HostResolverManager::HasCached(base::StringPiece hostname,
+                                    HostCache::Entry::Source* source_out,
+                                    HostCache::EntryStaleness* stale_out,
+                                    bool* secure_out) const {
   if (!cache_)
     return false;
 
@@ -2264,7 +2256,7 @@
   return !!key;
 }
 
-std::unique_ptr<base::Value> HostResolverImpl::GetDnsConfigAsValue() const {
+std::unique_ptr<base::Value> HostResolverManager::GetDnsConfigAsValue() const {
   // Check if async DNS is disabled.
   if (!dns_client_.get())
     return nullptr;
@@ -2278,28 +2270,28 @@
   return dns_config->ToValue();
 }
 
-size_t HostResolverImpl::LastRestoredCacheSize() const {
+size_t HostResolverManager::LastRestoredCacheSize() const {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   return cache_ ? cache_->last_restore_size() : 0;
 }
 
-size_t HostResolverImpl::CacheSize() const {
+size_t HostResolverManager::CacheSize() const {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   return cache_ ? cache_->size() : 0;
 }
 
-void HostResolverImpl::SetNoIPv6OnWifi(bool no_ipv6_on_wifi) {
+void HostResolverManager::SetNoIPv6OnWifi(bool no_ipv6_on_wifi) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   assume_ipv6_failure_on_wifi_ = no_ipv6_on_wifi;
 }
 
-bool HostResolverImpl::GetNoIPv6OnWifi() {
+bool HostResolverManager::GetNoIPv6OnWifi() {
   return assume_ipv6_failure_on_wifi_;
 }
 
-void HostResolverImpl::SetDnsConfigOverrides(
+void HostResolverManager::SetDnsConfigOverrides(
     const DnsConfigOverrides& overrides) {
   if (dns_config_overrides_ == overrides)
     return;
@@ -2309,14 +2301,14 @@
     UpdateDNSConfig(true);
 }
 
-void HostResolverImpl::SetRequestContext(URLRequestContext* context) {
+void HostResolverManager::SetRequestContext(URLRequestContext* context) {
   if (context != url_request_context_) {
     url_request_context_ = context;
   }
 }
 
 const std::vector<DnsConfig::DnsOverHttpsServerConfig>*
-HostResolverImpl::GetDnsOverHttpsServersForTesting() const {
+HostResolverManager::GetDnsOverHttpsServersForTesting() const {
   if (!dns_config_overrides_.dns_over_https_servers ||
       dns_config_overrides_.dns_over_https_servers.value().empty()) {
     return nullptr;
@@ -2324,19 +2316,19 @@
   return &dns_config_overrides_.dns_over_https_servers.value();
 }
 
-void HostResolverImpl::SetTickClockForTesting(
+void HostResolverManager::SetTickClockForTesting(
     const base::TickClock* tick_clock) {
   tick_clock_ = tick_clock;
   cache_->set_tick_clock_for_testing(tick_clock);
 }
 
-void HostResolverImpl::SetMaxQueuedJobsForTesting(size_t value) {
+void HostResolverManager::SetMaxQueuedJobsForTesting(size_t value) {
   DCHECK_EQ(0u, dispatcher_->num_queued_jobs());
   DCHECK_GE(value, 0u);
   max_queued_jobs_ = value;
 }
 
-void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) {
+void HostResolverManager::SetHaveOnlyLoopbackAddresses(bool result) {
   if (result) {
     additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
   } else {
@@ -2344,29 +2336,29 @@
   }
 }
 
-void HostResolverImpl::SetMdnsSocketFactoryForTesting(
+void HostResolverManager::SetMdnsSocketFactoryForTesting(
     std::unique_ptr<MDnsSocketFactory> socket_factory) {
   DCHECK(!mdns_client_);
   mdns_socket_factory_ = std::move(socket_factory);
 }
 
-void HostResolverImpl::SetMdnsClientForTesting(
+void HostResolverManager::SetMdnsClientForTesting(
     std::unique_ptr<MDnsClient> client) {
   mdns_client_ = std::move(client);
 }
 
-void HostResolverImpl::SetBaseDnsConfigForTesting(
+void HostResolverManager::SetBaseDnsConfigForTesting(
     const DnsConfig& base_config) {
   test_base_config_ = base_config;
   UpdateDNSConfig(true);
 }
 
-void HostResolverImpl::SetTaskRunnerForTesting(
+void HostResolverManager::SetTaskRunnerForTesting(
     scoped_refptr<base::TaskRunner> task_runner) {
   proc_task_runner_ = std::move(task_runner);
 }
 
-int HostResolverImpl::Resolve(RequestImpl* request) {
+int HostResolverManager::Resolve(RequestImpl* request) {
   // Request should not yet have a scheduled Job.
   DCHECK(!request->job());
   // Request may only be resolved once.
@@ -2410,7 +2402,7 @@
   return rv;
 }
 
-HostCache::Entry HostResolverImpl::ResolveLocally(
+HostCache::Entry HostResolverManager::ResolveLocally(
     const std::string& hostname,
     DnsQueryType dns_query_type,
     HostResolverSource source,
@@ -2488,7 +2480,8 @@
   return HostCache::Entry(ERR_DNS_CACHE_MISS, HostCache::Entry::SOURCE_UNKNOWN);
 }
 
-int HostResolverImpl::CreateAndStartJob(const Key& key, RequestImpl* request) {
+int HostResolverManager::CreateAndStartJob(const Key& key,
+                                           RequestImpl* request) {
   auto jobit = jobs_.find(key);
   Job* job;
   if (jobit == jobs_.end()) {
@@ -2519,7 +2512,7 @@
   return ERR_IO_PENDING;
 }
 
-base::Optional<HostCache::Entry> HostResolverImpl::ResolveAsIP(
+base::Optional<HostCache::Entry> HostResolverManager::ResolveAsIP(
     const Key& key,
     const IPAddress* ip_address) {
   if (ip_address == nullptr || !IsAddressType(key.dns_query_type))
@@ -2540,7 +2533,7 @@
                           HostCache::Entry::SOURCE_UNKNOWN);
 }
 
-base::Optional<HostCache::Entry> HostResolverImpl::ServeFromCache(
+base::Optional<HostCache::Entry> HostResolverManager::ServeFromCache(
     const Key& key,
     bool allow_stale,
     base::Optional<HostCache::EntryStaleness>* out_stale_info) {
@@ -2572,7 +2565,7 @@
   return cache_result->second;
 }
 
-base::Optional<HostCache::Entry> HostResolverImpl::ServeFromHosts(
+base::Optional<HostCache::Entry> HostResolverManager::ServeFromHosts(
     const Key& key) {
   if (!HaveDnsConfig() || !IsAddressType(key.dns_query_type))
     return base::nullopt;
@@ -2622,7 +2615,7 @@
   return base::nullopt;
 }
 
-base::Optional<HostCache::Entry> HostResolverImpl::ServeLocalhost(
+base::Optional<HostCache::Entry> HostResolverManager::ServeLocalhost(
     const Key& key) {
   AddressList resolved_addresses;
   if (!IsAddressType(key.dns_query_type) ||
@@ -2653,18 +2646,18 @@
                           HostCache::Entry::SOURCE_UNKNOWN);
 }
 
-void HostResolverImpl::CacheResult(const Key& key,
-                                   const HostCache::Entry& entry,
-                                   base::TimeDelta ttl) {
+void HostResolverManager::CacheResult(const Key& key,
+                                      const HostCache::Entry& entry,
+                                      base::TimeDelta ttl) {
   // Don't cache an error unless it has a positive TTL.
   if (cache_.get() && (entry.error() == OK || ttl > base::TimeDelta()))
     cache_->Set(key, entry, tick_clock_->NowTicks(), ttl);
 }
 
 // Record time from Request creation until a valid DNS response.
-void HostResolverImpl::RecordTotalTime(bool speculative,
-                                       bool from_cache,
-                                       base::TimeDelta duration) const {
+void HostResolverManager::RecordTotalTime(bool speculative,
+                                          bool from_cache,
+                                          base::TimeDelta duration) const {
   if (!speculative) {
     UMA_HISTOGRAM_LONG_TIMES_100("Net.DNS.TotalTime", duration);
 
@@ -2694,7 +2687,8 @@
   }
 }
 
-std::unique_ptr<HostResolverImpl::Job> HostResolverImpl::RemoveJob(Job* job) {
+std::unique_ptr<HostResolverManager::Job> HostResolverManager::RemoveJob(
+    Job* job) {
   DCHECK(job);
   std::unique_ptr<Job> retval;
   auto it = jobs_.find(job->key());
@@ -2705,7 +2699,7 @@
   return retval;
 }
 
-HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
+HostResolverManager::Key HostResolverManager::GetEffectiveKeyForRequest(
     const std::string& hostname,
     DnsQueryType dns_query_type,
     HostResolverSource source,
@@ -2731,7 +2725,7 @@
   return Key(hostname, effective_query_type, effective_flags, source);
 }
 
-bool HostResolverImpl::IsIPv6Reachable(const NetLogWithSource& net_log) {
+bool HostResolverManager::IsIPv6Reachable(const NetLogWithSource& net_log) {
   // Don't bother checking if the device is on WiFi and IPv6 is assumed to not
   // work on WiFi.
   if (assume_ipv6_failure_on_wifi_ &&
@@ -2756,8 +2750,8 @@
   return last_ipv6_probe_result_;
 }
 
-bool HostResolverImpl::IsGloballyReachable(const IPAddress& dest,
-                                           const NetLogWithSource& net_log) {
+bool HostResolverManager::IsGloballyReachable(const IPAddress& dest,
+                                              const NetLogWithSource& net_log) {
   std::unique_ptr<DatagramClientSocket> socket(
       ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket(
           DatagramSocket::DEFAULT_BIND, net_log.net_log(), net_log.source()));
@@ -2783,18 +2777,18 @@
   return true;
 }
 
-void HostResolverImpl::RunLoopbackProbeJob() {
+void HostResolverManager::RunLoopbackProbeJob() {
   // Run this asynchronously as it can take 40-100ms and should not block
   // initialization.
   base::PostTaskWithTraitsAndReplyWithResult(
       FROM_HERE,
       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
       base::BindOnce(&HaveOnlyLoopbackAddresses),
-      base::BindOnce(&HostResolverImpl::SetHaveOnlyLoopbackAddresses,
+      base::BindOnce(&HostResolverManager::SetHaveOnlyLoopbackAddresses,
                      weak_ptr_factory_.GetWeakPtr()));
 }
 
-void HostResolverImpl::AbortAllInProgressJobs() {
+void HostResolverManager::AbortAllInProgressJobs() {
   // In Abort, a Request callback could spawn new Jobs with matching keys, so
   // first collect and remove all running jobs from |jobs_|.
   std::vector<std::unique_ptr<Job>> jobs_to_abort;
@@ -2818,7 +2812,7 @@
       PrioritizedDispatcher::Limits(limits.reserved_slots.size(), 0));
 
   // Life check to bail once |this| is deleted.
-  base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr();
+  base::WeakPtr<HostResolverManager> self = weak_ptr_factory_.GetWeakPtr();
 
   // Then Abort them.
   for (size_t i = 0; self.get() && i < jobs_to_abort.size(); ++i) {
@@ -2829,7 +2823,7 @@
     dispatcher_->SetLimits(limits);
 }
 
-void HostResolverImpl::AbortDnsTasks(int error, bool fallback_only) {
+void HostResolverManager::AbortDnsTasks(int error, bool fallback_only) {
   // Aborting jobs potentially modifies |jobs_| and may even delete some jobs.
   // Create safe closures of all current jobs.
   std::vector<base::OnceClosure> job_abort_closures;
@@ -2851,7 +2845,7 @@
   dispatcher_->SetLimits(limits);
 }
 
-void HostResolverImpl::TryServingAllJobsFromHosts() {
+void HostResolverManager::TryServingAllJobsFromHosts() {
   if (!HaveDnsConfig())
     return;
 
@@ -2859,7 +2853,7 @@
   // http://crbug.com/117655
 
   // Life check to bail once |this| is deleted.
-  base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr();
+  base::WeakPtr<HostResolverManager> self = weak_ptr_factory_.GetWeakPtr();
 
   for (auto it = jobs_.begin(); self.get() && it != jobs_.end();) {
     Job* job = it->second.get();
@@ -2869,7 +2863,7 @@
   }
 }
 
-void HostResolverImpl::OnIPAddressChanged() {
+void HostResolverManager::OnIPAddressChanged() {
   last_ipv6_probe_time_ = base::TimeTicks();
   // Abandon all ProbeJobs.
   probe_weak_ptr_factory_.InvalidateWeakPtrs();
@@ -2883,7 +2877,7 @@
   // |this| may be deleted inside AbortAllInProgressJobs().
 }
 
-void HostResolverImpl::OnConnectionTypeChanged(
+void HostResolverManager::OnConnectionTypeChanged(
     NetworkChangeNotifier::ConnectionType type) {
   proc_params_.unresponsive_delay =
       GetTimeDeltaForConnectionTypeFromFieldTrialOrDefault(
@@ -2891,11 +2885,11 @@
           ProcTaskParams::kDnsDefaultUnresponsiveDelay, type);
 }
 
-void HostResolverImpl::OnInitialDNSConfigRead() {
+void HostResolverManager::OnInitialDNSConfigRead() {
   UpdateDNSConfig(false);
 }
 
-void HostResolverImpl::OnDNSChanged() {
+void HostResolverManager::OnDNSChanged() {
   // Ignore changes if we're using a test config or if we have overriding
   // configuration that overrides everything from the base config.
   if (test_base_config_ || dns_config_overrides_.OverridesEverything())
@@ -2904,7 +2898,7 @@
   UpdateDNSConfig(true);
 }
 
-DnsConfig HostResolverImpl::GetBaseDnsConfig(bool log_to_net_log) {
+DnsConfig HostResolverManager::GetBaseDnsConfig(bool log_to_net_log) {
   DnsConfig dns_config;
 
   // Skip retrieving the base config if all values will be overridden.
@@ -2928,7 +2922,7 @@
   return dns_config_overrides_.ApplyOverrides(dns_config);
 }
 
-void HostResolverImpl::UpdateDNSConfig(bool config_changed) {
+void HostResolverManager::UpdateDNSConfig(bool config_changed) {
   DnsConfig dns_config = GetBaseDnsConfig(true);
 
   // Conservatively assume local IPv6 is needed when DnsConfig is not valid.
@@ -2956,7 +2950,7 @@
       cache_->OnNetworkChange();
 
     // Life check to bail once |this| is deleted.
-    base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr();
+    base::WeakPtr<HostResolverManager> self = weak_ptr_factory_.GetWeakPtr();
 
     // Existing jobs will have been sent to the original server so they need to
     // be aborted.
@@ -2970,7 +2964,7 @@
   UpdateModeForHistogram(dns_config);
 }
 
-bool HostResolverImpl::HaveDnsConfig() const {
+bool HostResolverManager::HaveDnsConfig() const {
   // Use DnsClient only if it's fully configured and there is no override by
   // ScopedDefaultHostResolverProc.
   // The alternative is to use NetworkChangeNotifier to override DnsConfig,
@@ -2979,12 +2973,12 @@
          (proc_params_.resolver_proc || !HostResolverProc::GetDefault());
 }
 
-void HostResolverImpl::OnDnsTaskResolve() {
+void HostResolverManager::OnDnsTaskResolve() {
   DCHECK(dns_client_);
   num_dns_failures_ = 0;
 }
 
-void HostResolverImpl::OnFallbackResolve(int dns_task_error) {
+void HostResolverManager::OnFallbackResolve(int dns_task_error) {
   DCHECK(dns_client_);
   DCHECK_NE(OK, dns_task_error);
 
@@ -3002,7 +2996,7 @@
   AbortDnsTasks(ERR_FAILED, true /* fallback_only */);
 }
 
-MDnsClient* HostResolverImpl::GetOrCreateMdnsClient() {
+MDnsClient* HostResolverManager::GetOrCreateMdnsClient() {
 #if BUILDFLAG(ENABLE_MDNS)
   if (!mdns_client_) {
     if (!mdns_socket_factory_)
@@ -3021,7 +3015,7 @@
 #endif
 }
 
-void HostResolverImpl::UpdateModeForHistogram(const DnsConfig& dns_config) {
+void HostResolverManager::UpdateModeForHistogram(const DnsConfig& dns_config) {
   // Resolving with Async DNS resolver?
   if (HaveDnsConfig()) {
     mode_for_histogram_ = MODE_FOR_HISTOGRAM_ASYNC_DNS;
@@ -3052,12 +3046,12 @@
   }
 }
 
-HostResolverImpl::RequestImpl::~RequestImpl() {
+HostResolverManager::RequestImpl::~RequestImpl() {
   if (job_)
     job_->CancelRequest(this);
 }
 
-void HostResolverImpl::RequestImpl::ChangeRequestPriority(
+void HostResolverManager::RequestImpl::ChangeRequestPriority(
     RequestPriority priority) {
   DCHECK(job_);
   job_->ChangeRequestPriority(this, priority);
diff --git a/net/dns/host_resolver_impl.h b/net/dns/host_resolver_manager.h
similarity index 93%
rename from net/dns/host_resolver_impl.h
rename to net/dns/host_resolver_manager.h
index 24380e6..62612547 100644
--- a/net/dns/host_resolver_impl.h
+++ b/net/dns/host_resolver_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef NET_DNS_HOST_RESOLVER_IMPL_H_
-#define NET_DNS_HOST_RESOLVER_IMPL_H_
+#ifndef NET_DNS_HOST_RESOLVER_MANAGER_H_
+#define NET_DNS_HOST_RESOLVER_MANAGER_H_
 
 #include <stddef.h>
 #include <stdint.h>
@@ -50,7 +50,7 @@
 // though the HostResolver interface).
 //
 // For each hostname that is requested, HostResolver creates a
-// HostResolverImpl::Job. When this job gets dispatched it creates a task
+// HostResolverManager::Job. When this job gets dispatched it creates a task
 // (ProcTask for the system resolver or DnsTask for the async resolver) which
 // resolves the hostname. If requests for that same host are made during the
 // job's lifetime, they are attached to the existing job rather than creating a
@@ -59,7 +59,7 @@
 // The way these classes fit together is illustrated by:
 //
 //
-//            +----------- HostResolverImpl -------------+
+//            +----------- HostResolverManager ----------+
 //            |                    |                     |
 //           Job                  Job                   Job
 //    (for host1, fam1)    (for host2, fam2)     (for hostx, famx)
@@ -67,17 +67,17 @@
 //   Request ... Request  Request ... Request   Request ... Request
 //  (port1)     (port2)  (port3)      (port4)  (port5)      (portX)
 //
-// When a HostResolverImpl::Job finishes, the callbacks of each waiting request
-// are run on the origin thread.
+// When a HostResolverManager::Job finishes, the callbacks of each waiting
+// request are run on the origin thread.
 //
 // Thread safety: This class is not threadsafe, and must only be called
 // from one thread!
 //
-// The HostResolverImpl enforces limits on the maximum number of concurrent
+// The HostResolverManager enforces limits on the maximum number of concurrent
 // threads using PrioritizedDispatcher::Limits.
 //
 // Jobs are ordered in the queue based on their priority and order of arrival.
-class NET_EXPORT HostResolverImpl
+class NET_EXPORT HostResolverManager
     : public NetworkChangeNotifier::IPAddressObserver,
       public NetworkChangeNotifier::ConnectionTypeObserver,
       public NetworkChangeNotifier::DNSObserver {
@@ -97,13 +97,13 @@
   // the resolver will run at once. This upper-bounds the total number of
   // outstanding DNS transactions (not counting retransmissions and retries).
   //
-  // |net_log| must remain valid for the life of the HostResolverImpl.
-  HostResolverImpl(const Options& options, NetLog* net_log);
+  // |net_log| must remain valid for the life of the HostResolverManager.
+  HostResolverManager(const Options& options, NetLog* net_log);
 
   // If any completion callbacks are pending when the resolver is destroyed,
   // the host resolutions are cancelled, and the completion callbacks will not
   // be called.
-  ~HostResolverImpl() override;
+  ~HostResolverManager() override;
 
   // Set the DnsClient to be used for resolution. In case of failure, the
   // HostResolverProc from ProcTaskParams will be queried. If the DnsClient is
@@ -167,8 +167,8 @@
   void SetTaskRunnerForTesting(scoped_refptr<base::TaskRunner> task_runner);
 
  private:
-  friend class HostResolverImplTest;
-  FRIEND_TEST_ALL_PREFIXES(HostResolverImplDnsTest, ModeForHistogram);
+  friend class HostResolverManagerTest;
+  FRIEND_TEST_ALL_PREFIXES(HostResolverManagerDnsTest, ModeForHistogram);
   class Job;
   class ProcTask;
   class LoopbackProbeJob;
@@ -333,7 +333,7 @@
   MDnsClient* GetOrCreateMdnsClient();
 
   // Allows the tests to catch slots leaking out of the dispatcher.  One
-  // HostResolverImpl::Job could occupy multiple PrioritizedDispatcher job
+  // HostResolverManager::Job could occupy multiple PrioritizedDispatcher job
   // slots.
   size_t num_running_dispatcher_jobs_for_tests() const {
     return dispatcher_->num_running_jobs();
@@ -421,11 +421,11 @@
 
   THREAD_CHECKER(thread_checker_);
 
-  base::WeakPtrFactory<HostResolverImpl> weak_ptr_factory_;
+  base::WeakPtrFactory<HostResolverManager> weak_ptr_factory_;
 
-  base::WeakPtrFactory<HostResolverImpl> probe_weak_ptr_factory_;
+  base::WeakPtrFactory<HostResolverManager> probe_weak_ptr_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(HostResolverImpl);
+  DISALLOW_COPY_AND_ASSIGN(HostResolverManager);
 };
 
 // Resolves a local hostname (such as "localhost" or "localhost6") into
@@ -435,10 +435,10 @@
 // resolve to both IPv4 and IPv6.
 // This function is only exposed so it can be unit-tested.
 // TODO(tfarina): It would be better to change the tests so this function
-// gets exercised indirectly through HostResolverImpl.
+// gets exercised indirectly through HostResolverManager.
 NET_EXPORT_PRIVATE bool ResolveLocalHostname(base::StringPiece host,
                                              AddressList* address_list);
 
 }  // namespace net
 
-#endif  // NET_DNS_HOST_RESOLVER_IMPL_H_
+#endif  // NET_DNS_HOST_RESOLVER_MANAGER_H_
diff --git a/net/dns/host_resolver_impl_fuzzer.cc b/net/dns/host_resolver_manager_fuzzer.cc
similarity index 99%
rename from net/dns/host_resolver_impl_fuzzer.cc
rename to net/dns/host_resolver_manager_fuzzer.cc
index 20f33e4..b12a064f 100644
--- a/net/dns/host_resolver_impl_fuzzer.cc
+++ b/net/dns/host_resolver_manager_fuzzer.cc
@@ -172,9 +172,7 @@
   }
 
   // Cancel the request, if not already completed. Otherwise, does nothing.
-  void Cancel() {
-    request_.reset();
-  }
+  void Cancel() { request_.reset(); }
 
   net::HostResolver* host_resolver_;
   base::FuzzedDataProvider* data_provider_;
diff --git a/net/dns/host_resolver_impl_unittest.cc b/net/dns/host_resolver_manager_unittest.cc
similarity index 95%
rename from net/dns/host_resolver_impl_unittest.cc
rename to net/dns/host_resolver_manager_unittest.cc
index 19f8ef7..626a2e6 100644
--- a/net/dns/host_resolver_impl_unittest.cc
+++ b/net/dns/host_resolver_manager_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "net/dns/host_resolver_impl.h"
+#include "net/dns/host_resolver_manager.h"
 
 #include <algorithm>
 #include <string>
@@ -113,8 +113,7 @@
         num_requests_waiting_(0),
         num_slots_available_(0),
         requests_waiting_(&lock_),
-        slots_available_(&lock_) {
-  }
+        slots_available_(&lock_) {}
 
   // Waits until |count| calls to |Resolve| are blocked. Returns false when
   // timed out.
@@ -414,21 +413,22 @@
   base::ConditionVariable blocked_attempt_signal_;
 };
 
-// TestHostResolverImpl's sole purpose is to mock the IPv6 reachability test.
+// TestHostResolverManager's sole purpose is to mock the IPv6 reachability test.
 // By default, this pretends that IPv6 is globally reachable.
 // This class is necessary so unit tests run the same on dual-stack machines as
 // well as IPv4 only machines.
-class TestHostResolverImpl : public HostResolverImpl {
+class TestHostResolverManager : public HostResolverManager {
  public:
-  TestHostResolverImpl(const Options& options, NetLog* net_log)
-      : TestHostResolverImpl(options, net_log, true) {}
+  TestHostResolverManager(const Options& options, NetLog* net_log)
+      : TestHostResolverManager(options, net_log, true) {}
 
-  TestHostResolverImpl(const Options& options,
-                       NetLog* net_log,
-                       bool ipv6_reachable)
-      : HostResolverImpl(options, net_log), ipv6_reachable_(ipv6_reachable) {}
+  TestHostResolverManager(const Options& options,
+                          NetLog* net_log,
+                          bool ipv6_reachable)
+      : HostResolverManager(options, net_log),
+        ipv6_reachable_(ipv6_reachable) {}
 
-  ~TestHostResolverImpl() override = default;
+  ~TestHostResolverManager() override = default;
 
  private:
   const bool ipv6_reachable_;
@@ -464,19 +464,19 @@
 
 }  // namespace
 
-class HostResolverImplTest : public TestWithScopedTaskEnvironment {
+class HostResolverManagerTest : public TestWithScopedTaskEnvironment {
  public:
   static const int kDefaultPort = 80;
 
-  HostResolverImplTest() : proc_(new MockHostResolverProc()) {}
+  HostResolverManagerTest() : proc_(new MockHostResolverProc()) {}
 
   void CreateResolver() {
     CreateResolverWithLimitsAndParams(kMaxJobs, DefaultParams(proc_.get()),
                                       true /* ipv6_reachable */);
   }
 
-  // This HostResolverImpl will only allow 1 outstanding resolve at a time and
-  // perform no retries.
+  // This HostResolverManager will only allow 1 outstanding resolve at a time
+  // and perform no retries.
   void CreateSerialResolver() {
     ProcTaskParams params = DefaultParams(proc_.get());
     params.max_retry_attempts = 0u;
@@ -496,9 +496,9 @@
   virtual void CreateResolverWithLimitsAndParams(size_t max_concurrent_resolves,
                                                  const ProcTaskParams& params,
                                                  bool ipv6_reachable) {
-    HostResolverImpl::Options options = DefaultOptions();
+    HostResolverManager::Options options = DefaultOptions();
     options.max_concurrent_resolves = max_concurrent_resolves;
-    resolver_.reset(new TestHostResolverImpl(options, NULL, ipv6_reachable));
+    resolver_.reset(new TestHostResolverManager(options, NULL, ipv6_reachable));
     resolver_->set_proc_params_for_test(params);
   }
 
@@ -514,7 +514,7 @@
   }
 
   static unsigned maximum_dns_failures() {
-    return HostResolverImpl::kMaximumDnsFailures;
+    return HostResolverManager::kMaximumDnsFailures;
   }
 
   bool IsIPv6Reachable(const NetLogWithSource& net_log) {
@@ -541,10 +541,10 @@
   }
 
   scoped_refptr<MockHostResolverProc> proc_;
-  std::unique_ptr<HostResolverImpl> resolver_;
+  std::unique_ptr<HostResolverManager> resolver_;
 };
 
-TEST_F(HostResolverImplTest, AsynchronousLookup) {
+TEST_F(HostResolverManagerTest, AsynchronousLookup) {
   proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42");
   proc_->SignalMultiple(1u);
 
@@ -565,7 +565,7 @@
   EXPECT_TRUE(cache_result);
 }
 
-TEST_F(HostResolverImplTest, DnsQueryType) {
+TEST_F(HostResolverManagerTest, DnsQueryType) {
   proc_->AddRule("host", ADDRESS_FAMILY_IPV4, "192.168.1.20");
   proc_->AddRule("host", ADDRESS_FAMILY_IPV6, "::5");
 
@@ -590,7 +590,7 @@
               testing::ElementsAre(CreateExpected("::5", 80)));
 }
 
-TEST_F(HostResolverImplTest, LocalhostIPV4IPV6Lookup) {
+TEST_F(HostResolverManagerTest, LocalhostIPV4IPV6Lookup) {
   HostResolver::ResolveHostParameters parameters;
 
   parameters.dns_query_type = DnsQueryType::A;
@@ -637,7 +637,7 @@
                                     CreateExpected("::1", 80)));
 }
 
-TEST_F(HostResolverImplTest, ResolveIPLiteralWithHostResolverSystemOnly) {
+TEST_F(HostResolverManagerTest, ResolveIPLiteralWithHostResolverSystemOnly) {
   const char kIpLiteral[] = "178.78.32.1";
   // Add a mapping to tell if the resolver proc was called (if it was called,
   // then the result will be the remapped value. Otherwise it will be the IP
@@ -657,7 +657,7 @@
   EXPECT_FALSE(response.request()->GetStaleInfo());
 }
 
-TEST_F(HostResolverImplTest, EmptyListMeansNameNotResolved) {
+TEST_F(HostResolverManagerTest, EmptyListMeansNameNotResolved) {
   proc_->AddRuleForAllFamilies("just.testing", "");
   proc_->SignalMultiple(1u);
 
@@ -671,7 +671,7 @@
   EXPECT_EQ("just.testing", proc_->GetCaptureList()[0].hostname);
 }
 
-TEST_F(HostResolverImplTest, FailedAsynchronousLookup) {
+TEST_F(HostResolverManagerTest, FailedAsynchronousLookup) {
   proc_->AddRuleForAllFamilies(std::string(),
                                "0.0.0.0");  // Default to failures.
   proc_->SignalMultiple(1u);
@@ -692,7 +692,7 @@
   EXPECT_FALSE(cache_result);
 }
 
-TEST_F(HostResolverImplTest, AbortedAsynchronousLookup) {
+TEST_F(HostResolverManagerTest, AbortedAsynchronousLookup) {
   ResolveHostResponseHelper response0(resolver_->CreateRequest(
       HostPortPair("just.testing", 80), NetLogWithSource(), base::nullopt));
   ASSERT_FALSE(response0.complete());
@@ -716,7 +716,7 @@
   EXPECT_FALSE(response0.complete());
 }
 
-TEST_F(HostResolverImplTest, NumericIPv4Address) {
+TEST_F(HostResolverManagerTest, NumericIPv4Address) {
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("127.1.2.3", 5555), NetLogWithSource(), base::nullopt));
 
@@ -725,7 +725,7 @@
               testing::ElementsAre(CreateExpected("127.1.2.3", 5555)));
 }
 
-TEST_F(HostResolverImplTest, NumericIPv6Address) {
+TEST_F(HostResolverManagerTest, NumericIPv6Address) {
   // Resolve a plain IPv6 address.  Don't worry about [brackets], because
   // the caller should have removed them.
   ResolveHostResponseHelper response(resolver_->CreateRequest(
@@ -736,7 +736,7 @@
               testing::ElementsAre(CreateExpected("2001:db8::1", 5555)));
 }
 
-TEST_F(HostResolverImplTest, EmptyHost) {
+TEST_F(HostResolverManagerTest, EmptyHost) {
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair(std::string(), 5555), NetLogWithSource(), base::nullopt));
 
@@ -744,7 +744,7 @@
   EXPECT_FALSE(response.request()->GetAddressResults());
 }
 
-TEST_F(HostResolverImplTest, EmptyDotsHost) {
+TEST_F(HostResolverManagerTest, EmptyDotsHost) {
   for (int i = 0; i < 16; ++i) {
     ResolveHostResponseHelper response(
         resolver_->CreateRequest(HostPortPair(std::string(i, '.'), 5555),
@@ -755,7 +755,7 @@
   }
 }
 
-TEST_F(HostResolverImplTest, LongHost) {
+TEST_F(HostResolverManagerTest, LongHost) {
   ResolveHostResponseHelper response(
       resolver_->CreateRequest(HostPortPair(std::string(4097, 'a'), 5555),
                                NetLogWithSource(), base::nullopt));
@@ -764,7 +764,7 @@
   EXPECT_FALSE(response.request()->GetAddressResults());
 }
 
-TEST_F(HostResolverImplTest, DeDupeRequests) {
+TEST_F(HostResolverManagerTest, DeDupeRequests) {
   // Start 5 requests, duplicating hosts "a" and "b". Since the resolver_proc is
   // blocked, these should all pile up until we signal it.
   std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses;
@@ -795,7 +795,7 @@
   }
 }
 
-TEST_F(HostResolverImplTest, CancelMultipleRequests) {
+TEST_F(HostResolverManagerTest, CancelMultipleRequests) {
   std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses;
   responses.emplace_back(
       std::make_unique<ResolveHostResponseHelper>(resolver_->CreateRequest(
@@ -833,7 +833,7 @@
   EXPECT_FALSE(responses[4]->complete());
 }
 
-TEST_F(HostResolverImplTest, CanceledRequestsReleaseJobSlots) {
+TEST_F(HostResolverManagerTest, CanceledRequestsReleaseJobSlots) {
   std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses;
 
   // Fill up the dispatcher and queue.
@@ -871,7 +871,7 @@
   }
 }
 
-TEST_F(HostResolverImplTest, CancelWithinCallback) {
+TEST_F(HostResolverManagerTest, CancelWithinCallback) {
   std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses;
   auto custom_callback = base::BindLambdaForTesting(
       [&](CompletionOnceCallback completion_callback, int error) {
@@ -911,7 +911,7 @@
   }
 }
 
-TEST_F(HostResolverImplTest, DeleteWithinCallback) {
+TEST_F(HostResolverManagerTest, DeleteWithinCallback) {
   std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses;
   auto custom_callback = base::BindLambdaForTesting(
       [&](CompletionOnceCallback completion_callback, int error) {
@@ -958,7 +958,7 @@
 #else
 #define MAYBE_DeleteWithinAbortedCallback DeleteWithinAbortedCallback
 #endif
-TEST_F(HostResolverImplTest, MAYBE_DeleteWithinAbortedCallback) {
+TEST_F(HostResolverManagerTest, MAYBE_DeleteWithinAbortedCallback) {
   std::vector<std::unique_ptr<ResolveHostResponseHelper>> responses;
   ResolveHostResponseHelper::Callback custom_callback =
       base::BindLambdaForTesting(
@@ -1002,7 +1002,7 @@
   }
 }
 
-TEST_F(HostResolverImplTest, StartWithinCallback) {
+TEST_F(HostResolverManagerTest, StartWithinCallback) {
   std::unique_ptr<ResolveHostResponseHelper> new_response;
   auto custom_callback = base::BindLambdaForTesting(
       [&](CompletionOnceCallback completion_callback, int error) {
@@ -1023,7 +1023,7 @@
   EXPECT_THAT(new_response->result_error(), IsOk());
 }
 
-TEST_F(HostResolverImplTest, BypassCache) {
+TEST_F(HostResolverManagerTest, BypassCache) {
   proc_->SignalMultiple(2u);
 
   ResolveHostResponseHelper initial_response(resolver_->CreateRequest(
@@ -1049,7 +1049,7 @@
 
 // Test that IP address changes flush the cache but initial DNS config reads
 // do not.
-TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange) {
+TEST_F(HostResolverManagerTest, FlushCacheOnIPAddressChange) {
   proc_->SignalMultiple(2u);  // One before the flush, one after.
 
   ResolveHostResponseHelper initial_response(resolver_->CreateRequest(
@@ -1082,7 +1082,7 @@
 }
 
 // Test that IP address changes send ERR_NETWORK_CHANGED to pending requests.
-TEST_F(HostResolverImplTest, AbortOnIPAddressChanged) {
+TEST_F(HostResolverManagerTest, AbortOnIPAddressChanged) {
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host1", 70), NetLogWithSource(), base::nullopt));
 
@@ -1100,7 +1100,7 @@
 }
 
 // Test that initial DNS config read signals do not abort pending requests.
-TEST_F(HostResolverImplTest, DontAbortOnInitialDNSConfigRead) {
+TEST_F(HostResolverManagerTest, DontAbortOnInitialDNSConfigRead) {
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host1", 70), NetLogWithSource(), base::nullopt));
 
@@ -1117,7 +1117,7 @@
 }
 
 // Obey pool constraints after IP address has changed.
-TEST_F(HostResolverImplTest, ObeyPoolConstraintsAfterIPAddressChange) {
+TEST_F(HostResolverManagerTest, ObeyPoolConstraintsAfterIPAddressChange) {
   // Runs at most one job at a time.
   CreateSerialResolver();
 
@@ -1157,7 +1157,7 @@
 
 // Tests that a new Request made from the callback of a previously aborted one
 // will not be aborted.
-TEST_F(HostResolverImplTest, AbortOnlyExistingRequestsOnIPAddressChange) {
+TEST_F(HostResolverManagerTest, AbortOnlyExistingRequestsOnIPAddressChange) {
   auto custom_callback_template = base::BindLambdaForTesting(
       [&](const HostPortPair& next_host,
           std::unique_ptr<ResolveHostResponseHelper>* next_response,
@@ -1218,7 +1218,7 @@
 
 // Tests that when the maximum threads is set to 1, requests are dequeued
 // in order of priority.
-TEST_F(HostResolverImplTest, HigherPriorityRequestsStartedFirst) {
+TEST_F(HostResolverManagerTest, HigherPriorityRequestsStartedFirst) {
   CreateSerialResolver();
 
   HostResolver::ResolveHostParameters low_priority;
@@ -1286,7 +1286,7 @@
 }
 
 // Test that changing a job's priority affects the dequeueing order.
-TEST_F(HostResolverImplTest, ChangePriority) {
+TEST_F(HostResolverManagerTest, ChangePriority) {
   CreateSerialResolver();
 
   HostResolver::ResolveHostParameters lowest_priority;
@@ -1333,7 +1333,7 @@
 }
 
 // Try cancelling a job which has not started yet.
-TEST_F(HostResolverImplTest, CancelPendingRequest) {
+TEST_F(HostResolverManagerTest, CancelPendingRequest) {
   CreateSerialResolver();
 
   HostResolver::ResolveHostParameters lowest_priority;
@@ -1402,7 +1402,7 @@
 }
 
 // Test that when too many requests are enqueued, old ones start to be aborted.
-TEST_F(HostResolverImplTest, QueueOverflow) {
+TEST_F(HostResolverManagerTest, QueueOverflow) {
   CreateSerialResolver();
 
   // Allow only 3 queued jobs.
@@ -1498,7 +1498,7 @@
 }
 
 // Tests that jobs can self-evict by setting the max queue to 0.
-TEST_F(HostResolverImplTest, QueueOverflow_SelfEvict) {
+TEST_F(HostResolverManagerTest, QueueOverflow_SelfEvict) {
   CreateSerialResolver();
   resolver_->SetMaxQueuedJobsForTesting(0);
 
@@ -1522,7 +1522,7 @@
 
 // Make sure that the dns query type parameter is respected when raw IPs are
 // passed in.
-TEST_F(HostResolverImplTest, AddressFamilyWithRawIPs) {
+TEST_F(HostResolverManagerTest, AddressFamilyWithRawIPs) {
   HostResolver::ResolveHostParameters v4_parameters;
   v4_parameters.dns_query_type = DnsQueryType::A;
 
@@ -1564,7 +1564,7 @@
       testing::ElementsAre(CreateExpected("::1", 80)));
 }
 
-TEST_F(HostResolverImplTest, LocalOnly_FromCache) {
+TEST_F(HostResolverManagerTest, LocalOnly_FromCache) {
   proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42");
   proc_->SignalMultiple(1u);  // Need only one.
 
@@ -1598,7 +1598,7 @@
   EXPECT_FALSE(cache_hit_request.request()->GetStaleInfo().value().is_stale());
 }
 
-TEST_F(HostResolverImplTest, LocalOnly_StaleEntry) {
+TEST_F(HostResolverManagerTest, LocalOnly_StaleEntry) {
   proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42");
   proc_->SignalMultiple(1u);  // Need only one.
 
@@ -1632,7 +1632,7 @@
   EXPECT_FALSE(stale_request.request()->GetStaleInfo());
 }
 
-TEST_F(HostResolverImplTest, LocalOnly_FromIp) {
+TEST_F(HostResolverManagerTest, LocalOnly_FromIp) {
   HostResolver::ResolveHostParameters source_none_parameters;
   source_none_parameters.source = HostResolverSource::LOCAL_ONLY;
 
@@ -1647,7 +1647,7 @@
   EXPECT_FALSE(response.request()->GetStaleInfo());
 }
 
-TEST_F(HostResolverImplTest, LocalOnly_InvalidName) {
+TEST_F(HostResolverManagerTest, LocalOnly_InvalidName) {
   proc_->AddRuleForAllFamilies("foo,bar.com", "192.168.1.42");
 
   HostResolver::ResolveHostParameters source_none_parameters;
@@ -1664,7 +1664,7 @@
   EXPECT_FALSE(response.request()->GetStaleInfo());
 }
 
-TEST_F(HostResolverImplTest, LocalOnly_InvalidLocalhost) {
+TEST_F(HostResolverManagerTest, LocalOnly_InvalidLocalhost) {
   HostResolver::ResolveHostParameters source_none_parameters;
   source_none_parameters.source = HostResolverSource::LOCAL_ONLY;
 
@@ -1679,7 +1679,7 @@
   EXPECT_FALSE(response.request()->GetStaleInfo());
 }
 
-TEST_F(HostResolverImplTest, StaleAllowed) {
+TEST_F(HostResolverManagerTest, StaleAllowed) {
   proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42");
   proc_->SignalMultiple(1u);  // Need only one.
 
@@ -1716,7 +1716,7 @@
   EXPECT_TRUE(stale_request.request()->GetStaleInfo().value().is_stale());
 }
 
-TEST_F(HostResolverImplTest, StaleAllowed_NonLocal) {
+TEST_F(HostResolverManagerTest, StaleAllowed_NonLocal) {
   proc_->AddRuleForAllFamilies("just.testing", "192.168.2.42");
   proc_->SignalMultiple(1u);  // Need only one.
 
@@ -1735,7 +1735,7 @@
   EXPECT_FALSE(response.request()->GetStaleInfo());
 }
 
-TEST_F(HostResolverImplTest, StaleAllowed_FromIp) {
+TEST_F(HostResolverManagerTest, StaleAllowed_FromIp) {
   HostResolver::ResolveHostParameters stale_allowed_parameters;
   stale_allowed_parameters.cache_usage =
       HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
@@ -1756,7 +1756,7 @@
 // https://crbug.com/115051 is fixed.
 
 // Test the retry attempts simulating host resolver proc that takes too long.
-TEST_F(HostResolverImplTest, MultipleAttempts) {
+TEST_F(HostResolverManagerTest, MultipleAttempts) {
   // Total number of attempts would be 3 and we want the 3rd attempt to resolve
   // the host. First and second attempt will be forced to wait until they get
   // word that a resolution has completed. The 3rd resolution attempt will try
@@ -1821,7 +1821,7 @@
 // an error. 127.0.53.53 is a localhost address, however it has been given a
 // special significance by ICANN to help surface name collision resulting from
 // the new gTLDs.
-TEST_F(HostResolverImplTest, NameCollisionIcann) {
+TEST_F(HostResolverManagerTest, NameCollisionIcann) {
   proc_->AddRuleForAllFamilies("single", "127.0.53.53");
   proc_->AddRuleForAllFamilies("multiple", "127.0.0.1,127.0.53.53");
   proc_->AddRuleForAllFamilies("ipv6", "::127.0.53.53");
@@ -1876,10 +1876,10 @@
   EXPECT_THAT(similar_response3.result_error(), IsOk());
 }
 
-TEST_F(HostResolverImplTest, IsIPv6Reachable) {
-  // The real HostResolverImpl is needed since TestHostResolverImpl will
+TEST_F(HostResolverManagerTest, IsIPv6Reachable) {
+  // The real HostResolverManager is needed since TestHostResolverManager will
   // bypass the IPv6 reachability tests.
-  resolver_.reset(new HostResolverImpl(DefaultOptions(), nullptr));
+  resolver_.reset(new HostResolverManager(DefaultOptions(), nullptr));
 
   // Verify that two consecutive calls return the same value.
   TestNetLog test_net_log;
@@ -1909,7 +1909,7 @@
   EXPECT_TRUE(cached);
 }
 
-TEST_F(HostResolverImplTest, IncludeCanonicalName) {
+TEST_F(HostResolverManagerTest, IncludeCanonicalName) {
   proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42",
                                HOST_RESOLVER_CANONNAME, "canon.name");
   proc_->SignalMultiple(2u);
@@ -1930,7 +1930,7 @@
   EXPECT_THAT(response_no_flag.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
 }
 
-TEST_F(HostResolverImplTest, LoopbackOnly) {
+TEST_F(HostResolverManagerTest, LoopbackOnly) {
   proc_->AddRuleForAllFamilies("otherlocal", "127.0.0.1",
                                HOST_RESOLVER_LOOPBACK_ONLY);
   proc_->SignalMultiple(2u);
@@ -1949,7 +1949,7 @@
   EXPECT_THAT(response_no_flag.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
 }
 
-TEST_F(HostResolverImplTest, IsSpeculative) {
+TEST_F(HostResolverManagerTest, IsSpeculative) {
   proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42");
   proc_->SignalMultiple(1u);
 
@@ -2059,8 +2059,7 @@
 
     // 000a:0000:0000:0000:0001:0002:0003:0004
     0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
-    0x00, 0x03, 0x00, 0x04,
-};
+    0x00, 0x03, 0x00, 0x04};
 
 // An MDNS response indicating that the responder owns the hostname, but the
 // specific requested type (AAAA) does not exist because the responder only has
@@ -2109,8 +2108,7 @@
     // "foo"
     0x03, 0x66, 0x6f, 0x6f,
     // "bar"
-    0x03, 0x62, 0x61, 0x72,
-};
+    0x03, 0x62, 0x61, 0x72};
 
 const uint8_t kMdnsResponsePtr[] = {
     // Header
@@ -2179,7 +2177,7 @@
     // "foo.com."
     0x03, 'f', 'o', 'o', 0x03, 'c', 'o', 'm', 0x00};
 
-TEST_F(HostResolverImplTest, Mdns) {
+TEST_F(HostResolverManagerTest, Mdns) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2206,7 +2204,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplTest, Mdns_AaaaOnly) {
+TEST_F(HostResolverManagerTest, Mdns_AaaaOnly) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2229,7 +2227,7 @@
                   "000a:0000:0000:0000:0001:0002:0003:0004", 80)));
 }
 
-TEST_F(HostResolverImplTest, Mdns_Txt) {
+TEST_F(HostResolverManagerTest, Mdns_Txt) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2253,7 +2251,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplTest, Mdns_Ptr) {
+TEST_F(HostResolverManagerTest, Mdns_Ptr) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2278,7 +2276,7 @@
       testing::Optional(testing::ElementsAre(HostPortPair("foo.com", 83))));
 }
 
-TEST_F(HostResolverImplTest, Mdns_Srv) {
+TEST_F(HostResolverManagerTest, Mdns_Srv) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2305,7 +2303,7 @@
 
 // Test multicast DNS handling of NSEC responses (used for explicit negative
 // response).
-TEST_F(HostResolverImplTest, Mdns_Nsec) {
+TEST_F(HostResolverManagerTest, Mdns_Nsec) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2326,7 +2324,7 @@
   EXPECT_FALSE(response.request()->GetAddressResults());
 }
 
-TEST_F(HostResolverImplTest, Mdns_NoResponse) {
+TEST_F(HostResolverManagerTest, Mdns_NoResponse) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2362,7 +2360,7 @@
   test_task_runner->FastForwardUntilNoTasksRemain();
 }
 
-TEST_F(HostResolverImplTest, Mdns_WrongType) {
+TEST_F(HostResolverManagerTest, Mdns_WrongType) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2405,7 +2403,7 @@
 
 // Test for a request for both A and AAAA results where results only exist for
 // one type.
-TEST_F(HostResolverImplTest, Mdns_PartialResults) {
+TEST_F(HostResolverManagerTest, Mdns_PartialResults) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2442,7 +2440,7 @@
   test_task_runner->FastForwardUntilNoTasksRemain();
 }
 
-TEST_F(HostResolverImplTest, Mdns_Cancel) {
+TEST_F(HostResolverManagerTest, Mdns_Cancel) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2467,7 +2465,7 @@
 
 // Test for a two-transaction query where the first fails to start. The second
 // should be cancelled.
-TEST_F(HostResolverImplTest, Mdns_PartialFailure) {
+TEST_F(HostResolverManagerTest, Mdns_PartialFailure) {
   // Setup a mock MDnsClient where the first transaction will always return
   // |false| immediately on Start(). Second transaction may or may not be
   // created, but if it is, Start() not expected to be called because the
@@ -2563,7 +2561,7 @@
   std::multiset<UpdateKey> unhandled_results_;
 };
 
-TEST_F(HostResolverImplTest, MdnsListener) {
+TEST_F(HostResolverManagerTest, MdnsListener) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   base::SimpleTestClock clock;
   clock.SetNow(base::Time::Now());
@@ -2613,7 +2611,7 @@
 
 // Test that removal notifications are sent on natural expiration of MDNS
 // records.
-TEST_F(HostResolverImplTest, MdnsListener_Expiration) {
+TEST_F(HostResolverManagerTest, MdnsListener_Expiration) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   base::SimpleTestClock clock;
   clock.SetNow(base::Time::Now());
@@ -2657,7 +2655,7 @@
   EXPECT_THAT(delegate.unhandled_results(), testing::IsEmpty());
 }
 
-TEST_F(HostResolverImplTest, MdnsListener_Txt) {
+TEST_F(HostResolverManagerTest, MdnsListener_Txt) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2687,7 +2685,7 @@
   EXPECT_THAT(delegate.unhandled_results(), testing::IsEmpty());
 }
 
-TEST_F(HostResolverImplTest, MdnsListener_Ptr) {
+TEST_F(HostResolverManagerTest, MdnsListener_Ptr) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2714,7 +2712,7 @@
   EXPECT_THAT(delegate.unhandled_results(), testing::IsEmpty());
 }
 
-TEST_F(HostResolverImplTest, MdnsListener_Srv) {
+TEST_F(HostResolverManagerTest, MdnsListener_Srv) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2742,7 +2740,7 @@
 }
 
 // Ensure query types we are not listening for do not affect MdnsListener.
-TEST_F(HostResolverImplTest, MdnsListener_NonListeningTypes) {
+TEST_F(HostResolverManagerTest, MdnsListener_NonListeningTypes) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2763,7 +2761,7 @@
   EXPECT_THAT(delegate.unhandled_results(), testing::IsEmpty());
 }
 
-TEST_F(HostResolverImplTest, MdnsListener_RootDomain) {
+TEST_F(HostResolverManagerTest, MdnsListener_RootDomain) {
   auto socket_factory = std::make_unique<MockMDnsSocketFactory>();
   MockMDnsSocketFactory* socket_factory_ptr = socket_factory.get();
   resolver_->SetMdnsSocketFactoryForTesting(std::move(socket_factory));
@@ -2798,28 +2796,26 @@
 }
 
 // Specialized fixture for tests of DnsTask.
-class HostResolverImplDnsTest : public HostResolverImplTest {
+class HostResolverManagerDnsTest : public HostResolverManagerTest {
  public:
-  HostResolverImplDnsTest() : dns_client_(NULL) {}
+  HostResolverManagerDnsTest() : dns_client_(NULL) {}
 
  protected:
   // testing::Test implementation:
-  void SetUp() override {
-    CreateResolver();
-  }
+  void SetUp() override { CreateResolver(); }
 
   void TearDown() override {
-    HostResolverImplTest::TearDown();
+    HostResolverManagerTest::TearDown();
     ChangeDnsConfig(DnsConfig());
   }
 
-  // HostResolverImplTest implementation:
+  // HostResolverManagerTest implementation:
   void CreateResolverWithLimitsAndParams(size_t max_concurrent_resolves,
                                          const ProcTaskParams& params,
                                          bool ipv6_reachable) override {
-    HostResolverImpl::Options options = DefaultOptions();
+    HostResolverManager::Options options = DefaultOptions();
     options.max_concurrent_resolves = max_concurrent_resolves;
-    resolver_.reset(new TestHostResolverImpl(options, NULL, ipv6_reachable));
+    resolver_.reset(new TestHostResolverManager(options, NULL, ipv6_reachable));
     resolver_->set_proc_params_for_test(params);
     UseMockDnsClient(DnsConfig(), CreateDefaultDnsRules());
   }
@@ -2972,7 +2968,7 @@
 };
 
 // RFC 6761 localhost names should always resolve to loopback.
-TEST_F(HostResolverImplDnsTest, LocalhostLookup) {
+TEST_F(HostResolverManagerDnsTest, LocalhostLookup) {
   // Add a rule resolving localhost names to a non-loopback IP and test
   // that they still resolves to loopback.
   proc_->AddRuleForAllFamilies("foo.localhost", "192.168.1.42");
@@ -3003,7 +2999,7 @@
 
 // RFC 6761 localhost names should always resolve to loopback, even if a HOSTS
 // file is active.
-TEST_F(HostResolverImplDnsTest, LocalhostLookupWithHosts) {
+TEST_F(HostResolverManagerDnsTest, LocalhostLookupWithHosts) {
   DnsHosts hosts;
   hosts[DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4)] =
       IPAddress({192, 168, 1, 1});
@@ -3029,8 +3025,8 @@
                                             CreateExpected("::1", 80)));
 }
 
-// Test successful and fallback resolutions in HostResolverImpl::DnsTask.
-TEST_F(HostResolverImplDnsTest, DnsTask) {
+// Test successful and fallback resolutions in HostResolverManager::DnsTask.
+TEST_F(HostResolverManagerDnsTest, DnsTask) {
   proc_->AddRuleForAllFamilies("nx_succeed", "192.168.1.102");
   // All other hostnames will fail in proc_.
 
@@ -3067,9 +3063,9 @@
               testing::ElementsAre(CreateExpected("192.168.1.102", 80)));
 }
 
-// Test successful and failing resolutions in HostResolverImpl::DnsTask when
+// Test successful and failing resolutions in HostResolverManager::DnsTask when
 // fallback to ProcTask is disabled.
-TEST_F(HostResolverImplDnsTest, NoFallbackToProcTask) {
+TEST_F(HostResolverManagerDnsTest, NoFallbackToProcTask) {
   set_allow_fallback_to_proctask(false);
 
   proc_->AddRuleForAllFamilies("nx_succeed", "192.168.1.102");
@@ -3122,7 +3118,7 @@
 }
 
 // Test behavior of OnDnsTaskFailure when Job is aborted.
-TEST_F(HostResolverImplDnsTest, OnDnsTaskFailureAbortedJob) {
+TEST_F(HostResolverManagerDnsTest, OnDnsTaskFailureAbortedJob) {
   ChangeDnsConfig(CreateValidDnsConfig());
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("nx_abort", 80), NetLogWithSource(), base::nullopt));
@@ -3149,7 +3145,7 @@
 }
 
 // Fallback to proc allowed with ANY source.
-TEST_F(HostResolverImplDnsTest, FallbackBySource_Any) {
+TEST_F(HostResolverManagerDnsTest, FallbackBySource_Any) {
   // Ensure fallback is otherwise allowed by resolver settings.
   set_allow_fallback_to_proctask(true);
 
@@ -3171,7 +3167,7 @@
 }
 
 // Fallback to proc not allowed with DNS source.
-TEST_F(HostResolverImplDnsTest, FallbackBySource_Dns) {
+TEST_F(HostResolverManagerDnsTest, FallbackBySource_Dns) {
   // Ensure fallback is otherwise allowed by resolver settings.
   set_allow_fallback_to_proctask(true);
 
@@ -3195,7 +3191,7 @@
 }
 
 // Fallback to proc on DnsClient change allowed with ANY source.
-TEST_F(HostResolverImplDnsTest, FallbackOnAbortBySource_Any) {
+TEST_F(HostResolverManagerDnsTest, FallbackOnAbortBySource_Any) {
   // Ensure fallback is otherwise allowed by resolver settings.
   set_allow_fallback_to_proctask(true);
 
@@ -3222,7 +3218,7 @@
 }
 
 // Fallback to proc on DnsClient change not allowed with DNS source.
-TEST_F(HostResolverImplDnsTest, FallbackOnAbortBySource_Dns) {
+TEST_F(HostResolverManagerDnsTest, FallbackOnAbortBySource_Dns) {
   // Ensure fallback is otherwise allowed by resolver settings.
   set_allow_fallback_to_proctask(true);
 
@@ -3250,7 +3246,7 @@
   EXPECT_THAT(response1.result_error(), IsError(ERR_NETWORK_CHANGED));
 }
 
-TEST_F(HostResolverImplDnsTest, DnsTaskUnspec) {
+TEST_F(HostResolverManagerDnsTest, DnsTaskUnspec) {
   ChangeDnsConfig(CreateValidDnsConfig());
 
   proc_->AddRuleForAllFamilies("4nx", "192.168.1.101");
@@ -3287,7 +3283,7 @@
               testing::ElementsAre(CreateExpected("192.168.1.101", 80)));
 }
 
-TEST_F(HostResolverImplDnsTest, NameCollisionIcann) {
+TEST_F(HostResolverManagerDnsTest, NameCollisionIcann) {
   ChangeDnsConfig(CreateValidDnsConfig());
 
   // When the resolver returns an A record with 127.0.53.53 it should be
@@ -3307,7 +3303,7 @@
               testing::ElementsAre(CreateExpected("::127.0.53.53", 80)));
 }
 
-TEST_F(HostResolverImplDnsTest, ServeFromHosts) {
+TEST_F(HostResolverManagerDnsTest, ServeFromHosts) {
   // Initially, use empty HOSTS file.
   DnsConfig config = CreateValidDnsConfig();
   ChangeDnsConfig(config);
@@ -3383,7 +3379,7 @@
               testing::ElementsAre(CreateExpected("127.0.0.1", 80)));
 }
 
-TEST_F(HostResolverImplDnsTest, CacheHostsLookupOnConfigChange) {
+TEST_F(HostResolverManagerDnsTest, CacheHostsLookupOnConfigChange) {
   // Only allow 1 resolution at a time, so that the second lookup is queued and
   // occurs when the DNS config changes.
   CreateResolverWithLimitsAndParams(1u, DefaultParams(proc_.get()),
@@ -3429,7 +3425,7 @@
 
 // Test that hosts ending in ".local" or ".local." are resolved using the system
 // resolver.
-TEST_F(HostResolverImplDnsTest, BypassDnsTask) {
+TEST_F(HostResolverManagerDnsTest, BypassDnsTask) {
   ChangeDnsConfig(CreateValidDnsConfig());
 
   proc_->AddRuleForAllFamilies(std::string(),
@@ -3465,7 +3461,7 @@
 #if BUILDFLAG(ENABLE_MDNS)
 // Test that non-address queries for hosts ending in ".local" are resolved using
 // the MDNS resolver.
-TEST_F(HostResolverImplDnsTest, BypassDnsToMdnsWithNonAddress) {
+TEST_F(HostResolverManagerDnsTest, BypassDnsToMdnsWithNonAddress) {
   // Ensure DNS task and system (proc) requests will fail.
   MockDnsClientRuleList rules;
   rules.emplace_back(
@@ -3499,7 +3495,7 @@
 
 // Test that DNS task is always used when explicitly requested as the source,
 // even with a case that would normally bypass it eg hosts ending in ".local".
-TEST_F(HostResolverImplDnsTest, DnsNotBypassedWhenDnsSource) {
+TEST_F(HostResolverManagerDnsTest, DnsNotBypassedWhenDnsSource) {
   // Ensure DNS task requests will succeed and system (proc) requests will fail.
   ChangeDnsConfig(CreateValidDnsConfig());
   proc_->AddRuleForAllFamilies(std::string(), std::string());
@@ -3522,7 +3518,7 @@
               IsError(ERR_NAME_NOT_RESOLVED));
 }
 
-TEST_F(HostResolverImplDnsTest, SystemOnlyBypassesDnsTask) {
+TEST_F(HostResolverManagerDnsTest, SystemOnlyBypassesDnsTask) {
   // Ensure DNS task requests will succeed and system (proc) requests will fail.
   ChangeDnsConfig(CreateValidDnsConfig());
   proc_->AddRuleForAllFamilies(std::string(), std::string());
@@ -3541,7 +3537,7 @@
   EXPECT_THAT(system_response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
 }
 
-TEST_F(HostResolverImplDnsTest, DisableDnsClientOnPersistentFailure) {
+TEST_F(HostResolverManagerDnsTest, DisableDnsClientOnPersistentFailure) {
   ChangeDnsConfig(CreateValidDnsConfig());
 
   proc_->AddRuleForAllFamilies(std::string(),
@@ -3588,7 +3584,7 @@
   EXPECT_THAT(reenabled_response.result_error(), IsOk());
 }
 
-TEST_F(HostResolverImplDnsTest, DontDisableDnsClientOnSporadicFailure) {
+TEST_F(HostResolverManagerDnsTest, DontDisableDnsClientOnSporadicFailure) {
   ChangeDnsConfig(CreateValidDnsConfig());
 
   // |proc_| defaults to successes.
@@ -3621,7 +3617,7 @@
 // Confirm that resolving "localhost" is unrestricted even if there are no
 // global IPv6 address. See SystemHostResolverCall for rationale.
 // Test both the DnsClient and system host resolver paths.
-TEST_F(HostResolverImplDnsTest, DualFamilyLocalhost) {
+TEST_F(HostResolverManagerDnsTest, DualFamilyLocalhost) {
   CreateResolverWithLimitsAndParams(kMaxJobs, DefaultParams(proc_.get()),
                                     false /* ipv6_reachable */);
 
@@ -3663,7 +3659,7 @@
 }
 
 // Cancel a request with a single DNS transaction active.
-TEST_F(HostResolverImplDnsTest, CancelWithOneTransactionActive) {
+TEST_F(HostResolverManagerDnsTest, CancelWithOneTransactionActive) {
   // Disable ipv6 to ensure we'll only try a single transaction for the host.
   CreateResolverWithLimitsAndParams(kMaxJobs, DefaultParams(proc_.get()),
                                     false /* ipv6_reachable */);
@@ -3684,7 +3680,7 @@
 }
 
 // Cancel a request with a single DNS transaction active and another pending.
-TEST_F(HostResolverImplDnsTest, CancelWithOneTransactionActiveOnePending) {
+TEST_F(HostResolverManagerDnsTest, CancelWithOneTransactionActiveOnePending) {
   CreateSerialResolver();
   ChangeDnsConfig(CreateValidDnsConfig());
 
@@ -3700,7 +3696,7 @@
 }
 
 // Cancel a request with two DNS transactions active.
-TEST_F(HostResolverImplDnsTest, CancelWithTwoTransactionsActive) {
+TEST_F(HostResolverManagerDnsTest, CancelWithTwoTransactionsActive) {
   ChangeDnsConfig(CreateValidDnsConfig());
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
@@ -3715,7 +3711,7 @@
 }
 
 // Delete a resolver with some active requests and some queued requests.
-TEST_F(HostResolverImplDnsTest, DeleteWithActiveTransactions) {
+TEST_F(HostResolverManagerDnsTest, DeleteWithActiveTransactions) {
   // At most 10 Jobs active at once.
   CreateResolverWithLimitsAndParams(10u, DefaultParams(proc_.get()),
                                     true /* ipv6_reachable */);
@@ -3741,7 +3737,7 @@
 }
 
 // Cancel a request with only the IPv6 transaction active.
-TEST_F(HostResolverImplDnsTest, CancelWithIPv6TransactionActive) {
+TEST_F(HostResolverManagerDnsTest, CancelWithIPv6TransactionActive) {
   ChangeDnsConfig(CreateValidDnsConfig());
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
@@ -3760,7 +3756,7 @@
 }
 
 // Cancel a request with only the IPv4 transaction pending.
-TEST_F(HostResolverImplDnsTest, CancelWithIPv4TransactionPending) {
+TEST_F(HostResolverManagerDnsTest, CancelWithIPv4TransactionPending) {
   set_allow_fallback_to_proctask(false);
   ChangeDnsConfig(CreateValidDnsConfig());
 
@@ -3778,7 +3774,7 @@
 }
 
 // Test cases where AAAA completes first.
-TEST_F(HostResolverImplDnsTest, AAAACompletesFirst) {
+TEST_F(HostResolverManagerDnsTest, AAAACompletesFirst) {
   set_allow_fallback_to_proctask(false);
   ChangeDnsConfig(CreateValidDnsConfig());
 
@@ -3819,7 +3815,7 @@
 }
 
 // Test cases where transactions return secure or mixed secure/insecure results.
-TEST_F(HostResolverImplDnsTest, SecureOrMixedSecurityResults) {
+TEST_F(HostResolverManagerDnsTest, SecureOrMixedSecurityResults) {
   MockDnsClientRuleList rules;
   AddSecureDnsRule(&rules, "secure", dns_protocol::kTypeA,
                    MockDnsClientRule::OK, false /* delay */);
@@ -3942,7 +3938,7 @@
 }
 
 // Test the case where only a single transaction slot is available.
-TEST_F(HostResolverImplDnsTest, SerialResolver) {
+TEST_F(HostResolverManagerDnsTest, SerialResolver) {
   CreateSerialResolver();
   set_allow_fallback_to_proctask(false);
   ChangeDnsConfig(CreateValidDnsConfig());
@@ -3963,7 +3959,7 @@
 // Test the case where subsequent transactions are handled on transaction
 // completion when only part of a multi-transaction request could be initially
 // started.
-TEST_F(HostResolverImplDnsTest, AAAAStartsAfterOtherJobFinishes) {
+TEST_F(HostResolverManagerDnsTest, AAAAStartsAfterOtherJobFinishes) {
   CreateResolverWithLimitsAndParams(3u, DefaultParams(proc_.get()),
                                     true /* ipv6_reachable */);
   set_allow_fallback_to_proctask(false);
@@ -3992,7 +3988,7 @@
 
 // Tests the case that a Job with a single transaction receives an empty address
 // list, triggering fallback to ProcTask.
-TEST_F(HostResolverImplDnsTest, IPv4EmptyFallback) {
+TEST_F(HostResolverManagerDnsTest, IPv4EmptyFallback) {
   // Disable ipv6 to ensure we'll only try a single transaction for the host.
   CreateResolverWithLimitsAndParams(kMaxJobs, DefaultParams(proc_.get()),
                                     false /* ipv6_reachable */);
@@ -4013,7 +4009,7 @@
 
 // Tests the case that a Job with two transactions receives two empty address
 // lists, triggering fallback to ProcTask.
-TEST_F(HostResolverImplDnsTest, UnspecEmptyFallback) {
+TEST_F(HostResolverManagerDnsTest, UnspecEmptyFallback) {
   ChangeDnsConfig(CreateValidDnsConfig());
   proc_->AddRuleForAllFamilies("empty_fallback", "192.168.0.1");
   proc_->SignalMultiple(1u);
@@ -4027,9 +4023,9 @@
 }
 
 // Tests getting a new invalid DnsConfig while there are active DnsTasks.
-TEST_F(HostResolverImplDnsTest, InvalidDnsConfigWithPendingRequests) {
+TEST_F(HostResolverManagerDnsTest, InvalidDnsConfigWithPendingRequests) {
   // At most 3 jobs active at once.  This number is important, since we want
-  // to make sure that aborting the first HostResolverImpl::Job does not
+  // to make sure that aborting the first HostResolverManager::Job does not
   // trigger another DnsTransaction on the second Job when it releases its
   // second prioritized dispatcher slot.
   CreateResolverWithLimitsAndParams(3u, DefaultParams(proc_.get()),
@@ -4078,7 +4074,7 @@
 
 // Test that initial DNS config read signals do not abort pending requests
 // when using DnsClient.
-TEST_F(HostResolverImplDnsTest, DontAbortOnInitialDNSConfigRead) {
+TEST_F(HostResolverManagerDnsTest, DontAbortOnInitialDNSConfigRead) {
   // DnsClient is enabled, but there's no DnsConfig, so the request should start
   // using ProcTask.
   ResolveHostResponseHelper response(resolver_->CreateRequest(
@@ -4095,7 +4091,7 @@
 
 // Tests the case that DnsClient is automatically disabled due to failures
 // while there are active DnsTasks.
-TEST_F(HostResolverImplDnsTest,
+TEST_F(HostResolverManagerDnsTest,
        AutomaticallyDisableDnsClientWithPendingRequests) {
   // Trying different limits is important for this test:  Different limits
   // result in different behavior when aborting in-progress DnsTasks.  Having
@@ -4184,9 +4180,10 @@
 }
 
 // Tests a call to SetDnsClient while there are active DnsTasks.
-TEST_F(HostResolverImplDnsTest, ManuallyDisableDnsClientWithPendingRequests) {
+TEST_F(HostResolverManagerDnsTest,
+       ManuallyDisableDnsClientWithPendingRequests) {
   // At most 3 jobs active at once.  This number is important, since we want to
-  // make sure that aborting the first HostResolverImpl::Job does not trigger
+  // make sure that aborting the first HostResolverManager::Job does not trigger
   // another DnsTransaction on the second Job when it releases its second
   // prioritized dispatcher slot.
   CreateResolverWithLimitsAndParams(3u, DefaultParams(proc_.get()),
@@ -4236,7 +4233,7 @@
               testing::ElementsAre(CreateExpected("192.168.0.3", 80)));
 }
 
-TEST_F(HostResolverImplDnsTest, NoIPv6OnWifi) {
+TEST_F(HostResolverManagerDnsTest, NoIPv6OnWifi) {
   // CreateSerialResolver will destroy the current resolver_ which will attempt
   // to remove itself from the NetworkChangeNotifier. If this happens after a
   // new NetworkChangeNotifier is active, then it will not remove itself from
@@ -4314,7 +4311,7 @@
       testing::ElementsAre(CreateExpected("::2", 80)));
 }
 
-TEST_F(HostResolverImplDnsTest, NotFoundTTL) {
+TEST_F(HostResolverManagerDnsTest, NotFoundTTL) {
   CreateResolver();
   set_allow_fallback_to_proctask(false);
   ChangeDnsConfig(CreateValidDnsConfig());
@@ -4349,7 +4346,7 @@
   EXPECT_THAT(cache_result->second.ttl(), base::TimeDelta::FromSeconds(86400));
 }
 
-TEST_F(HostResolverImplDnsTest, CachedError) {
+TEST_F(HostResolverManagerDnsTest, CachedError) {
   CreateResolver();
   set_allow_fallback_to_proctask(false);
   ChangeDnsConfig(CreateValidDnsConfig());
@@ -4377,7 +4374,7 @@
   EXPECT_FALSE(cache_hit_response.request()->GetStaleInfo().value().is_stale());
 }
 
-TEST_F(HostResolverImplDnsTest, NoCanonicalName) {
+TEST_F(HostResolverManagerDnsTest, NoCanonicalName) {
   MockDnsClientRuleList rules;
   AddDnsRule(&rules, "alias", dns_protocol::kTypeA, IPAddress::IPv4Localhost(),
              "canonical", false /* delay */);
@@ -4398,7 +4395,7 @@
   EXPECT_TRUE(result_name.empty() || result_name == "canonical");
 }
 
-TEST_F(HostResolverImplDnsTest, CanonicalName) {
+TEST_F(HostResolverManagerDnsTest, CanonicalName) {
   MockDnsClientRuleList rules;
   AddDnsRule(&rules, "alias", dns_protocol::kTypeA, IPAddress::IPv4Localhost(),
              "canonical", false /* delay */);
@@ -4420,7 +4417,7 @@
             "canonical");
 }
 
-TEST_F(HostResolverImplDnsTest, CanonicalName_PreferV6) {
+TEST_F(HostResolverManagerDnsTest, CanonicalName_PreferV6) {
   MockDnsClientRuleList rules;
   AddDnsRule(&rules, "alias", dns_protocol::kTypeA, IPAddress::IPv4Localhost(),
              "wrong", false /* delay */);
@@ -4444,7 +4441,7 @@
             "correct");
 }
 
-TEST_F(HostResolverImplDnsTest, CanonicalName_V4Only) {
+TEST_F(HostResolverManagerDnsTest, CanonicalName_V4Only) {
   MockDnsClientRuleList rules;
   AddDnsRule(&rules, "alias", dns_protocol::kTypeA, IPAddress::IPv4Localhost(),
              "correct", false /* delay */);
@@ -4465,7 +4462,7 @@
 
 // Test that without specifying source, a request that would otherwise be
 // handled by DNS is sent to the system resolver if cannonname is requested.
-TEST_F(HostResolverImplDnsTest, CanonicalNameForcesProc) {
+TEST_F(HostResolverManagerDnsTest, CanonicalNameForcesProc) {
   // Disable fallback to ensure system resolver is used directly, not via
   // fallback.
   set_allow_fallback_to_proctask(false);
@@ -4486,7 +4483,7 @@
             "canonical");
 }
 
-TEST_F(HostResolverImplTest, ResolveLocalHostname) {
+TEST_F(HostResolverManagerTest, ResolveLocalHostname) {
   AddressList addresses;
 
   TestBothLoopbackIPs("localhost");
@@ -4529,7 +4526,7 @@
   EXPECT_FALSE(ResolveLocalHostname("foo.localhoste", &addresses));
 }
 
-TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerAfterConfig) {
+TEST_F(HostResolverManagerDnsTest, AddDnsOverHttpsServerAfterConfig) {
   resolver_ = nullptr;
   test::ScopedMockNetworkChangeNotifier notifier;
   CreateSerialResolver();  // To guarantee order of resolutions.
@@ -4566,7 +4563,7 @@
   EXPECT_EQ(server_template, server);
 }
 
-TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerBeforeConfig) {
+TEST_F(HostResolverManagerDnsTest, AddDnsOverHttpsServerBeforeConfig) {
   resolver_ = nullptr;
   test::ScopedMockNetworkChangeNotifier notifier;
   CreateSerialResolver();  // To guarantee order of resolutions.
@@ -4603,7 +4600,7 @@
   EXPECT_EQ(server_template, server);
 }
 
-TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerBeforeClient) {
+TEST_F(HostResolverManagerDnsTest, AddDnsOverHttpsServerBeforeClient) {
   resolver_ = nullptr;
   test::ScopedMockNetworkChangeNotifier notifier;
   CreateSerialResolver();  // To guarantee order of resolutions.
@@ -4641,7 +4638,7 @@
   EXPECT_EQ(server_template, server);
 }
 
-TEST_F(HostResolverImplDnsTest, AddDnsOverHttpsServerAndThenRemove) {
+TEST_F(HostResolverManagerDnsTest, AddDnsOverHttpsServerAndThenRemove) {
   resolver_ = nullptr;
   test::ScopedMockNetworkChangeNotifier notifier;
   CreateSerialResolver();  // To guarantee order of resolutions.
@@ -4691,7 +4688,7 @@
   EXPECT_EQ(doh_servers->GetSize(), 0u);
 }
 
-TEST_F(HostResolverImplDnsTest, SetDnsConfigOverrides) {
+TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides) {
   DnsConfig original_config = CreateValidDnsConfig();
   ChangeDnsConfig(original_config);
 
@@ -4741,7 +4738,7 @@
   EXPECT_EQ(dns_over_https_servers, overridden_config->dns_over_https_servers);
 }
 
-TEST_F(HostResolverImplDnsTest,
+TEST_F(HostResolverManagerDnsTest,
        SetDnsConfigOverrides_OverrideEverythingCreation) {
   DnsConfig original_config = CreateValidDnsConfig();
   ChangeDnsConfig(original_config);
@@ -4766,7 +4763,7 @@
   EXPECT_TRUE(dns_client_->GetConfig()->Equals(DnsConfig(expected)));
 }
 
-TEST_F(HostResolverImplDnsTest, SetDnsConfigOverrides_PartialOverride) {
+TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides_PartialOverride) {
   DnsConfig original_config = CreateValidDnsConfig();
   ChangeDnsConfig(original_config);
 
@@ -4799,7 +4796,7 @@
 
 // Test that overridden configs are reapplied over a changed underlying system
 // config.
-TEST_F(HostResolverImplDnsTest, SetDnsConfigOverrides_NewConfig) {
+TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides_NewConfig) {
   DnsConfig original_config = CreateValidDnsConfig();
   ChangeDnsConfig(original_config);
 
@@ -4824,7 +4821,7 @@
   EXPECT_EQ(new_config.attempts, overridden_config->attempts);
 }
 
-TEST_F(HostResolverImplDnsTest, SetDnsConfigOverrides_ClearOverrides) {
+TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides_ClearOverrides) {
   DnsConfig original_config = CreateValidDnsConfig();
   ChangeDnsConfig(original_config);
 
@@ -4840,7 +4837,7 @@
 
 // Test that even when using config overrides, a change to the base system
 // config cancels pending requests.
-TEST_F(HostResolverImplDnsTest, CancellationOnBaseConfigChange) {
+TEST_F(HostResolverManagerDnsTest, CancellationOnBaseConfigChange) {
   DnsConfig original_config = CreateValidDnsConfig();
   ChangeDnsConfig(original_config);
 
@@ -4862,7 +4859,7 @@
 
 // Test that when all configuration is overridden, system configuration changes
 // do not cancel requests.
-TEST_F(HostResolverImplDnsTest,
+TEST_F(HostResolverManagerDnsTest,
        CancellationOnBaseConfigChange_OverridesEverything) {
   DnsConfig original_config = CreateValidDnsConfig();
   ChangeDnsConfig(original_config);
@@ -4887,7 +4884,7 @@
 
 // Test that in-progress queries are cancelled on applying new DNS config
 // overrides, same as receiving a new DnsConfig from the system.
-TEST_F(HostResolverImplDnsTest, CancelQueriesOnSettingOverrides) {
+TEST_F(HostResolverManagerDnsTest, CancelQueriesOnSettingOverrides) {
   ChangeDnsConfig(CreateValidDnsConfig());
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("4slow_ok", 80), NetLogWithSource(), base::nullopt));
@@ -4901,7 +4898,8 @@
 }
 
 // Queries should not be cancelled if equal overrides are set.
-TEST_F(HostResolverImplDnsTest, CancelQueriesOnSettingOverrides_SameOverrides) {
+TEST_F(HostResolverManagerDnsTest,
+       CancelQueriesOnSettingOverrides_SameOverrides) {
   ChangeDnsConfig(CreateValidDnsConfig());
   DnsConfigOverrides overrides;
   overrides.attempts = 123;
@@ -4919,7 +4917,7 @@
 
 // Test that in-progress queries are cancelled on clearing DNS config overrides,
 // same as receiving a new DnsConfig from the system.
-TEST_F(HostResolverImplDnsTest, CancelQueriesOnClearingOverrides) {
+TEST_F(HostResolverManagerDnsTest, CancelQueriesOnClearingOverrides) {
   ChangeDnsConfig(CreateValidDnsConfig());
   DnsConfigOverrides overrides;
   overrides.attempts = 123;
@@ -4936,7 +4934,8 @@
 
 // Queries should not be cancelled on clearing overrides if there were not any
 // overrides.
-TEST_F(HostResolverImplDnsTest, CancelQueriesOnClearingOverrides_NoOverrides) {
+TEST_F(HostResolverManagerDnsTest,
+       CancelQueriesOnClearingOverrides_NoOverrides) {
   ChangeDnsConfig(CreateValidDnsConfig());
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("4slow_ok", 80), NetLogWithSource(), base::nullopt));
@@ -4948,12 +4947,12 @@
   EXPECT_THAT(response.result_error(), IsOk());
 }
 
-// Test HostResolverImpl::UpdateModeForHistogram.
-TEST_F(HostResolverImplDnsTest, ModeForHistogram) {
+// Test HostResolverManager::UpdateModeForHistogram.
+TEST_F(HostResolverManagerDnsTest, ModeForHistogram) {
   // Test Async resolver is detected.
   ChangeDnsConfig(CreateValidDnsConfig());
   EXPECT_EQ(resolver_->mode_for_histogram_,
-            HostResolverImpl::MODE_FOR_HISTOGRAM_ASYNC_DNS);
+            HostResolverManager::MODE_FOR_HISTOGRAM_ASYNC_DNS);
 
   // Test upgradability is detected for async DNS.
   static const std::vector<const char*> upgradable_servers(
@@ -4972,14 +4971,14 @@
     ChangeDnsConfig(dns_config);
     EXPECT_EQ(
         resolver_->mode_for_histogram_,
-        HostResolverImpl::MODE_FOR_HISTOGRAM_ASYNC_DNS_PRIVATE_SUPPORTS_DOH);
+        HostResolverManager::MODE_FOR_HISTOGRAM_ASYNC_DNS_PRIVATE_SUPPORTS_DOH);
   }
 
   // Test system resolver is detected.
   resolver_->SetDnsClient(nullptr);
   ChangeDnsConfig(CreateValidDnsConfig());
   EXPECT_EQ(resolver_->mode_for_histogram_,
-            HostResolverImpl::MODE_FOR_HISTOGRAM_SYSTEM);
+            HostResolverManager::MODE_FOR_HISTOGRAM_SYSTEM);
 
   // Test upgradability is detected for system resolver.
   for (const char* upgradable_server : upgradable_servers) {
@@ -4990,11 +4989,11 @@
         IPEndPoint(ip_address, dns_protocol::kDefaultPort));
     ChangeDnsConfig(dns_config);
     EXPECT_EQ(resolver_->mode_for_histogram_,
-              HostResolverImpl::MODE_FOR_HISTOGRAM_SYSTEM_SUPPORTS_DOH);
+              HostResolverManager::MODE_FOR_HISTOGRAM_SYSTEM_SUPPORTS_DOH);
   }
 }
 
-TEST_F(HostResolverImplDnsTest, TxtQuery) {
+TEST_F(HostResolverManagerDnsTest, TxtQuery) {
   // Simulate two separate DNS records, each with multiple strings.
   std::vector<std::string> foo_records = {"foo1", "foo2", "foo3"};
   std::vector<std::string> bar_records = {"bar1", "bar2"};
@@ -5032,7 +5031,7 @@
                                        bar_records.begin(), bar_records.end()));
 }
 
-TEST_F(HostResolverImplDnsTest, TxtQuery_NonexistentDomain) {
+TEST_F(HostResolverManagerDnsTest, TxtQuery_NonexistentDomain) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5057,7 +5056,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, TxtQuery_Failure) {
+TEST_F(HostResolverManagerDnsTest, TxtQuery_Failure) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5082,7 +5081,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, TxtQuery_Timeout) {
+TEST_F(HostResolverManagerDnsTest, TxtQuery_Timeout) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5107,7 +5106,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, TxtQuery_Empty) {
+TEST_F(HostResolverManagerDnsTest, TxtQuery_Empty) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5132,7 +5131,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, TxtQuery_Malformed) {
+TEST_F(HostResolverManagerDnsTest, TxtQuery_Malformed) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5157,7 +5156,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, TxtQuery_MismatchedName) {
+TEST_F(HostResolverManagerDnsTest, TxtQuery_MismatchedName) {
   std::vector<std::vector<std::string>> text_records = {{"text"}};
   MockDnsClientRuleList rules;
   rules.emplace_back("host", dns_protocol::kTypeTXT, SecureDnsMode::AUTOMATIC,
@@ -5179,7 +5178,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, TxtQuery_WrongType) {
+TEST_F(HostResolverManagerDnsTest, TxtQuery_WrongType) {
   // Respond to a TXT query with an A response.
   MockDnsClientRuleList rules;
   rules.emplace_back("host", dns_protocol::kTypeTXT, SecureDnsMode::AUTOMATIC,
@@ -5206,7 +5205,7 @@
 // on automatic determination.  Expect same results since DNS should be what we
 // automatically determine, but some slightly different logic paths are
 // involved.
-TEST_F(HostResolverImplDnsTest, TxtDnsQuery) {
+TEST_F(HostResolverManagerDnsTest, TxtDnsQuery) {
   // Simulate two separate DNS records, each with multiple strings.
   std::vector<std::string> foo_records = {"foo1", "foo2", "foo3"};
   std::vector<std::string> bar_records = {"bar1", "bar2"};
@@ -5245,7 +5244,7 @@
                                        bar_records.begin(), bar_records.end()));
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery) {
   MockDnsClientRuleList rules;
   rules.emplace_back("host", dns_protocol::kTypePTR, SecureDnsMode::AUTOMATIC,
                      MockDnsClientRule::Result(BuildTestDnsPointerResponse(
@@ -5270,7 +5269,7 @@
                   HostPortPair("foo.com", 108), HostPortPair("bar.com", 108))));
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery_Ip) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery_Ip) {
   MockDnsClientRuleList rules;
   rules.emplace_back("8.8.8.8", dns_protocol::kTypePTR,
                      SecureDnsMode::AUTOMATIC,
@@ -5296,7 +5295,7 @@
                   HostPortPair("foo.com", 108), HostPortPair("bar.com", 108))));
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery_NonexistentDomain) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery_NonexistentDomain) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5321,7 +5320,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery_Failure) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery_Failure) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5346,7 +5345,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery_Timeout) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery_Timeout) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5371,7 +5370,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery_Empty) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery_Empty) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5396,7 +5395,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery_Malformed) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery_Malformed) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5421,7 +5420,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery_MismatchedName) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery_MismatchedName) {
   std::vector<std::string> ptr_records = {{"foo.com"}};
   MockDnsClientRuleList rules;
   rules.emplace_back("host", dns_protocol::kTypePTR, SecureDnsMode::AUTOMATIC,
@@ -5443,7 +5442,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, PtrQuery_WrongType) {
+TEST_F(HostResolverManagerDnsTest, PtrQuery_WrongType) {
   // Respond to a TXT query with an A response.
   MockDnsClientRuleList rules;
   rules.emplace_back("host", dns_protocol::kTypePTR, SecureDnsMode::AUTOMATIC,
@@ -5470,7 +5469,7 @@
 // on automatic determination.  Expect same results since DNS should be what we
 // automatically determine, but some slightly different logic paths are
 // involved.
-TEST_F(HostResolverImplDnsTest, PtrDnsQuery) {
+TEST_F(HostResolverManagerDnsTest, PtrDnsQuery) {
   MockDnsClientRuleList rules;
   rules.emplace_back("host", dns_protocol::kTypePTR, SecureDnsMode::AUTOMATIC,
                      MockDnsClientRule::Result(BuildTestDnsPointerResponse(
@@ -5496,7 +5495,7 @@
                   HostPortPair("foo.com", 108), HostPortPair("bar.com", 108))));
 }
 
-TEST_F(HostResolverImplDnsTest, SrvQuery) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery) {
   const TestServiceRecord kRecord1 = {2, 3, 1223, "foo.com"};
   const TestServiceRecord kRecord2 = {5, 10, 80, "bar.com"};
   const TestServiceRecord kRecord3 = {5, 1, 5, "google.com"};
@@ -5541,7 +5540,7 @@
 
 // 0-weight services are allowed. Ensure that we can handle such records,
 // especially the case where all entries have weight 0.
-TEST_F(HostResolverImplDnsTest, SrvQuery_ZeroWeight) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery_ZeroWeight) {
   const TestServiceRecord kRecord1 = {5, 0, 80, "bar.com"};
   const TestServiceRecord kRecord2 = {5, 0, 5, "google.com"};
   MockDnsClientRuleList rules;
@@ -5568,7 +5567,7 @@
                   HostPortPair("bar.com", 80), HostPortPair("google.com", 5))));
 }
 
-TEST_F(HostResolverImplDnsTest, SrvQuery_NonexistentDomain) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery_NonexistentDomain) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5593,7 +5592,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, SrvQuery_Failure) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery_Failure) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5618,7 +5617,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, SrvQuery_Timeout) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery_Timeout) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5643,7 +5642,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, SrvQuery_Empty) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery_Empty) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5668,7 +5667,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, SrvQuery_Malformed) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery_Malformed) {
   // Setup fallback to confirm it is not used for non-address results.
   set_allow_fallback_to_proctask(true);
   proc_->AddRuleForAllFamilies("host", "192.168.1.102");
@@ -5693,7 +5692,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, SrvQuery_MismatchedName) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery_MismatchedName) {
   std::vector<TestServiceRecord> srv_records = {{1, 2, 3, "foo.com"}};
   MockDnsClientRuleList rules;
   rules.emplace_back("host", dns_protocol::kTypeSRV, SecureDnsMode::AUTOMATIC,
@@ -5715,7 +5714,7 @@
   EXPECT_FALSE(response.request()->GetHostnameResults());
 }
 
-TEST_F(HostResolverImplDnsTest, SrvQuery_WrongType) {
+TEST_F(HostResolverManagerDnsTest, SrvQuery_WrongType) {
   // Respond to a SRV query with an A response.
   MockDnsClientRuleList rules;
   rules.emplace_back("host", dns_protocol::kTypeSRV, SecureDnsMode::AUTOMATIC,
@@ -5742,7 +5741,7 @@
 // on automatic determination.  Expect same results since DNS should be what we
 // automatically determine, but some slightly different logic paths are
 // involved.
-TEST_F(HostResolverImplDnsTest, SrvDnsQuery) {
+TEST_F(HostResolverManagerDnsTest, SrvDnsQuery) {
   const TestServiceRecord kRecord1 = {2, 3, 1223, "foo.com"};
   const TestServiceRecord kRecord2 = {5, 10, 80, "bar.com"};
   const TestServiceRecord kRecord3 = {5, 1, 5, "google.com"};
diff --git a/net/dns/host_resolver_proc.h b/net/dns/host_resolver_proc.h
index 36bdb1f..fd2b8f0 100644
--- a/net/dns/host_resolver_proc.h
+++ b/net/dns/host_resolver_proc.h
@@ -18,9 +18,9 @@
 class AddressList;
 
 // Interface for a getaddrinfo()-like procedure. This is used by unit-tests
-// to control the underlying resolutions in HostResolverImpl. HostResolverProcs
-// can be chained together; they fallback to the next procedure in the chain
-// by calling ResolveUsingPrevious().
+// to control the underlying resolutions in HostResolverManager.
+// HostResolverProcs can be chained together; they fallback to the next
+// procedure in the chain by calling ResolveUsingPrevious().
 //
 // Note that implementations of HostResolverProc *MUST BE THREADSAFE*, since
 // the HostResolver implementation using them can be multi-threaded.
@@ -52,7 +52,7 @@
                            int* os_error);
 
  private:
-  friend class HostResolverImpl;
+  friend class HostResolverManager;
   friend class MockHostResolverBase;
   friend class ScopedDefaultHostResolverProc;
 
@@ -68,10 +68,10 @@
   // NULL iff |proc| is NULL.
   static HostResolverProc* GetLastProc(HostResolverProc* proc);
 
-  // Sets the default host resolver procedure that is used by HostResolverImpl.
-  // This can be used through ScopedDefaultHostResolverProc to set a catch-all
-  // DNS block in unit-tests (individual tests should use MockHostResolver to
-  // prevent hitting the network).
+  // Sets the default host resolver procedure that is used by
+  // HostResolverManager. This can be used through ScopedDefaultHostResolverProc
+  // to set a catch-all DNS block in unit-tests (individual tests should use
+  // MockHostResolver to prevent hitting the network).
   static HostResolverProc* SetDefault(HostResolverProc* proc);
   static HostResolverProc* GetDefault();
 
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 2cf4002..a8a02507 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -59,7 +59,8 @@
       context.transport_security_state, context.cert_transparency_verifier,
       context.ct_policy_enforcer, ssl_client_session_cache,
       ssl_client_session_cache_privacy_mode, context.ssl_config_service,
-      websocket_endpoint_lock_manager, context.proxy_delegate, pool_type);
+      websocket_endpoint_lock_manager, context.proxy_delegate,
+      context.http_user_agent_settings, pool_type);
 }
 
 }  // unnamed namespace
@@ -165,6 +166,7 @@
       ct_policy_enforcer(nullptr),
       proxy_resolution_service(nullptr),
       proxy_delegate(nullptr),
+      http_user_agent_settings(nullptr),
       ssl_config_service(nullptr),
       http_auth_handler_factory(nullptr),
       net_log(nullptr),
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 3b0bc86a..9fe908a 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -61,6 +61,7 @@
 class HttpNetworkSessionPeer;
 class HttpResponseBodyDrainer;
 class HttpServerProperties;
+class HttpUserAgentSettings;
 class NetLog;
 #if BUILDFLAG(ENABLE_REPORTING)
 class NetworkErrorLoggingService;
@@ -257,6 +258,7 @@
     CTPolicyEnforcer* ct_policy_enforcer;
     ProxyResolutionService* proxy_resolution_service;
     ProxyDelegate* proxy_delegate;
+    const HttpUserAgentSettings* http_user_agent_settings;
     SSLConfigService* ssl_config_service;
     HttpAuthHandlerFactory* http_auth_handler_factory;
     HttpServerProperties* http_server_properties;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 06726c2..7a60a67 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -27,6 +27,7 @@
 #include "base/stl_util.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_task_environment.h"
@@ -103,6 +104,7 @@
 #include "net/test/test_with_scoped_task_environment.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "net/url_request/static_http_user_agent_settings.h"
 #include "net/websockets/websocket_handshake_stream_base.h"
 #include "net/websockets/websocket_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -708,6 +710,7 @@
                  NULL,
                  NULL,
                  NULL,
+                 NULL,
                  NULL) {}
 
 //-----------------------------------------------------------------------------
@@ -10482,43 +10485,73 @@
 }
 
 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
-  HttpRequestInfo request;
-  request.method = "GET";
-  request.url = GURL("https://www.example.org/");
-  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
-                                  "Chromium Ultra Awesome X Edition");
-  request.traffic_annotation =
-      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+  // Test user agent values, used both for the request header of the original
+  // request, and the value returned by the HttpUserAgentSettings. nullptr means
+  // no request header / no HttpUserAgentSettings object.
+  const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
 
-  session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
-      "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
-  std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-  HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+  for (const char* setting_user_agent : kTestUserAgents) {
+    if (!setting_user_agent) {
+      session_deps_.http_user_agent_settings.reset();
+    } else {
+      session_deps_.http_user_agent_settings =
+          std::make_unique<StaticHttpUserAgentSettings>(
+              std::string() /* accept-language */, setting_user_agent);
+    }
+    session_deps_.proxy_resolution_service =
+        ProxyResolutionService::CreateFixed("myproxy:70",
+                                            TRAFFIC_ANNOTATION_FOR_TESTS);
+    std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+    for (const char* request_user_agent : kTestUserAgents) {
+      HttpRequestInfo request;
+      request.method = "GET";
+      request.url = GURL("https://www.example.org/");
+      if (request_user_agent) {
+        request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
+                                        request_user_agent);
+      }
+      request.traffic_annotation =
+          net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
 
-  MockWrite data_writes[] = {
-      MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
-                "Host: www.example.org:443\r\n"
-                "Proxy-Connection: keep-alive\r\n"
-                "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
-  };
-  MockRead data_reads[] = {
-    // Return an error, so the transaction stops here (this test isn't
-    // interested in the rest).
-    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
-    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
-    MockRead("Proxy-Connection: close\r\n\r\n"),
-  };
+      HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
 
-  StaticSocketDataProvider data(data_reads, data_writes);
-  session_deps_.socket_factory->AddSocketDataProvider(&data);
+      std::string expected_request;
+      if (!setting_user_agent || strlen(setting_user_agent) == 0) {
+        expected_request =
+            "CONNECT www.example.org:443 HTTP/1.1\r\n"
+            "Host: www.example.org:443\r\n"
+            "Proxy-Connection: keep-alive\r\n\r\n";
+      } else {
+        expected_request = base::StringPrintf(
+            "CONNECT www.example.org:443 HTTP/1.1\r\n"
+            "Host: www.example.org:443\r\n"
+            "Proxy-Connection: keep-alive\r\n"
+            "User-Agent: %s\r\n\r\n",
+            setting_user_agent);
+      }
+      MockWrite data_writes[] = {
+          MockWrite(expected_request.c_str()),
+      };
+      MockRead data_reads[] = {
+          // Return an error, so the transaction stops here (this test isn't
+          // interested in the rest).
+          MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
+          MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
+          MockRead("Proxy-Connection: close\r\n\r\n"),
+      };
 
-  TestCompletionCallback callback;
+      StaticSocketDataProvider data(data_reads, data_writes);
+      session_deps_.socket_factory->AddSocketDataProvider(&data);
 
-  int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
-  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+      TestCompletionCallback callback;
 
-  rv = callback.WaitForResult();
-  EXPECT_THAT(rv, IsOk());
+      int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
+      EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+      rv = callback.WaitForResult();
+      EXPECT_THAT(rv, IsOk());
+    }
+  }
 }
 
 TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
@@ -14374,8 +14407,8 @@
       1,                                 // Max sockets per group
       base::TimeDelta::FromSeconds(10),  // unused_idle_socket_timeout
       session_deps_.socket_factory.get(), session_deps_.host_resolver.get(),
-      nullptr /* proxy_delegate */, session_deps_.cert_verifier.get(),
-      session_deps_.channel_id_service.get(),
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      session_deps_.cert_verifier.get(), session_deps_.channel_id_service.get(),
       session_deps_.transport_security_state.get(),
       session_deps_.cert_transparency_verifier.get(),
       session_deps_.ct_policy_enforcer.get(),
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc
index f3344d5..47558d33 100644
--- a/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -79,6 +79,7 @@
             &socket_factory_,
             session_deps_.host_resolver.get(),
             nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
             session_deps_.cert_verifier.get(),
             session_deps_.channel_id_service.get(),
             session_deps_.transport_security_state.get(),
@@ -100,6 +101,7 @@
     pool_ = std::make_unique<TransportClientSocketPool>(
         kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
         &socket_factory_, session_deps_.host_resolver.get(), proxy_delegate,
+        nullptr /* http_user_agent_settings */,
         session_deps_.cert_verifier.get(),
         session_deps_.channel_id_service.get(),
         session_deps_.transport_security_state.get(),
@@ -151,7 +153,7 @@
         CreateFromHttpProxySocketParams(
             base::MakeRefCounted<HttpProxySocketParams>(
                 CreateHttpProxyParams(), CreateHttpsProxyParams(),
-                quic::QUIC_VERSION_UNSUPPORTED, std::string(),
+                quic::QUIC_VERSION_UNSUPPORTED,
                 HostPortPair("www.google.com", tunnel ? 443 : 80),
                 session_->http_auth_cache(),
                 session_->http_auth_handler_factory(),
diff --git a/net/http/http_proxy_client_socket_wrapper.cc b/net/http/http_proxy_client_socket_wrapper.cc
index 46139820..28177f1 100644
--- a/net/http/http_proxy_client_socket_wrapper.cc
+++ b/net/http/http_proxy_client_socket_wrapper.cc
@@ -14,6 +14,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/proxy_delegate.h"
 #include "net/http/http_proxy_client_socket.h"
 #include "net/http/http_response_info.h"
@@ -47,7 +48,6 @@
     const scoped_refptr<TransportSocketParams>& transport_params,
     const scoped_refptr<SSLSocketParams>& ssl_params,
     quic::QuicTransportVersion quic_version,
-    const std::string& user_agent,
     const HostPortPair& endpoint,
     HttpAuthCache* http_auth_cache,
     HttpAuthHandlerFactory* http_auth_handler_factory,
@@ -57,8 +57,8 @@
     bool tunnel,
     const NetworkTrafficAnnotationTag& traffic_annotation,
     const NetLogWithSource& net_log)
-    : on_proxy_auth_callback_(on_proxy_auth_callback),
-      next_state_(STATE_NONE),
+    : next_state_(STATE_NONE),
+      on_proxy_auth_callback_(on_proxy_auth_callback),
       priority_(priority),
       socket_tag_(socket_tag),
       connect_timeout_duration_(connect_timeout_duration),
@@ -66,7 +66,6 @@
       transport_params_(transport_params),
       ssl_params_(ssl_params),
       quic_version_(quic_version),
-      user_agent_(user_agent),
       endpoint_(endpoint),
       spdy_session_pool_(spdy_session_pool),
       has_restarted_(false),
@@ -654,7 +653,7 @@
   transport_socket_ =
       common_connect_job_params_->client_socket_factory
           ->CreateProxyClientSocket(
-              nested_connect_job_->PassSocket(), user_agent_, endpoint_,
+              nested_connect_job_->PassSocket(), GetUserAgent(), endpoint_,
               ProxyServer(GetProxyServerScheme(), GetDestination()),
               http_auth_controller_.get(), tunnel_, using_spdy_,
               negotiated_protocol_, common_connect_job_params_->proxy_delegate,
@@ -725,8 +724,9 @@
   spdy_stream_request_.reset();
   DCHECK(stream.get());
   // |transport_socket_| will set itself as |stream|'s delegate.
-  transport_socket_.reset(new SpdyProxyClientSocket(
-      stream, user_agent_, endpoint_, net_log_, http_auth_controller_.get()));
+  transport_socket_.reset(
+      new SpdyProxyClientSocket(stream, GetUserAgent(), endpoint_, net_log_,
+                                http_auth_controller_.get()));
   return transport_socket_->Connect(base::Bind(
       &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)));
 }
@@ -779,8 +779,8 @@
   quic_stream->SetPriority(spdy_priority);
 
   transport_socket_.reset(new QuicProxyClientSocket(
-      std::move(quic_stream), std::move(quic_session_), user_agent_, endpoint_,
-      net_log_, http_auth_controller_.get()));
+      std::move(quic_stream), std::move(quic_session_), GetUserAgent(),
+      endpoint_, net_log_, http_auth_controller_.get()));
   return transport_socket_->Connect(base::Bind(
       &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)));
 }
@@ -882,4 +882,10 @@
   }
 }
 
+std::string HttpProxyClientSocketWrapper::GetUserAgent() const {
+  if (!common_connect_job_params_->http_user_agent_settings)
+    return std::string();
+  return common_connect_job_params_->http_user_agent_settings->GetUserAgent();
+}
+
 }  // namespace net
diff --git a/net/http/http_proxy_client_socket_wrapper.h b/net/http/http_proxy_client_socket_wrapper.h
index 2882f00..dbc56af 100644
--- a/net/http/http_proxy_client_socket_wrapper.h
+++ b/net/http/http_proxy_client_socket_wrapper.h
@@ -72,7 +72,6 @@
       const scoped_refptr<TransportSocketParams>& transport_params,
       const scoped_refptr<SSLSocketParams>& ssl_params,
       quic::QuicTransportVersion quic_version,
-      const std::string& user_agent,
       const HostPortPair& endpoint,
       HttpAuthCache* http_auth_cache,
       HttpAuthHandlerFactory* http_auth_handler_factory,
@@ -202,10 +201,12 @@
 
   const HostPortPair& GetDestination();
 
-  const OnProxyAuthChallengeCallback on_proxy_auth_callback_;
+  std::string GetUserAgent() const;
 
   State next_state_;
 
+  const OnProxyAuthChallengeCallback on_proxy_auth_callback_;
+
   RequestPriority priority_;
   const SocketTag socket_tag_;
   const base::TimeDelta connect_timeout_duration_;
@@ -216,7 +217,6 @@
 
   quic::QuicTransportVersion quic_version_;
 
-  const std::string user_agent_;
   const HostPortPair endpoint_;
   SpdySessionPool* const spdy_session_pool_;
 
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc
index 6e1ed3d4..4ca5587 100644
--- a/net/http/http_proxy_connect_job.cc
+++ b/net/http/http_proxy_connect_job.cc
@@ -128,7 +128,6 @@
     const scoped_refptr<TransportSocketParams>& transport_params,
     const scoped_refptr<SSLSocketParams>& ssl_params,
     quic::QuicTransportVersion quic_version,
-    const std::string& user_agent,
     const HostPortPair& endpoint,
     HttpAuthCache* http_auth_cache,
     HttpAuthHandlerFactory* http_auth_handler_factory,
@@ -142,7 +141,6 @@
       quic_version_(quic_version),
       spdy_session_pool_(spdy_session_pool),
       quic_stream_factory_(quic_stream_factory),
-      user_agent_(user_agent),
       endpoint_(endpoint),
       http_auth_cache_(tunnel ? http_auth_cache : NULL),
       http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL),
@@ -192,7 +190,6 @@
           params->transport_params(),
           params->ssl_params(),
           params->quic_version(),
-          params->user_agent(),
           params->endpoint(),
           params->http_auth_cache(),
           params->http_auth_handler_factory(),
diff --git a/net/http/http_proxy_connect_job.h b/net/http/http_proxy_connect_job.h
index 6082729..2f3743a9 100644
--- a/net/http/http_proxy_connect_job.h
+++ b/net/http/http_proxy_connect_job.h
@@ -45,7 +45,6 @@
       const scoped_refptr<TransportSocketParams>& transport_params,
       const scoped_refptr<SSLSocketParams>& ssl_params,
       quic::QuicTransportVersion quic_version,
-      const std::string& user_agent,
       const HostPortPair& endpoint,
       HttpAuthCache* http_auth_cache,
       HttpAuthHandlerFactory* http_auth_handler_factory,
@@ -62,7 +61,6 @@
     return ssl_params_;
   }
   quic::QuicTransportVersion quic_version() const { return quic_version_; }
-  const std::string& user_agent() const { return user_agent_; }
   const HostPortPair& endpoint() const { return endpoint_; }
   HttpAuthCache* http_auth_cache() const { return http_auth_cache_; }
   HttpAuthHandlerFactory* http_auth_handler_factory() const {
@@ -87,7 +85,6 @@
   quic::QuicTransportVersion quic_version_;
   SpdySessionPool* spdy_session_pool_;
   QuicStreamFactory* quic_stream_factory_;
-  const std::string user_agent_;
   const HostPortPair endpoint_;
   HttpAuthCache* const http_auth_cache_;
   HttpAuthHandlerFactory* const http_auth_handler_factory_;
diff --git a/net/http/http_proxy_connect_job_unittest.cc b/net/http/http_proxy_connect_job_unittest.cc
index 4000f8a..0c6b62f 100644
--- a/net/http/http_proxy_connect_job_unittest.cc
+++ b/net/http/http_proxy_connect_job_unittest.cc
@@ -133,7 +133,7 @@
   scoped_refptr<HttpProxySocketParams> CreateParams(bool tunnel) {
     return base::MakeRefCounted<HttpProxySocketParams>(
         CreateHttpProxyParams(), CreateHttpsProxyParams(),
-        quic::QUIC_VERSION_UNSUPPORTED, std::string(),
+        quic::QUIC_VERSION_UNSUPPORTED,
         HostPortPair(kEndpointHost, tunnel ? 443 : 80),
         session_->http_auth_cache(), session_->http_auth_handler_factory(),
         session_->spdy_session_pool(), session_->quic_stream_factory(),
@@ -175,7 +175,7 @@
   void InitCommonConnectJobParams() {
     common_connect_job_params_ = std::make_unique<CommonConnectJobParams>(
         &socket_factory_, session_deps_.host_resolver.get(),
-        proxy_delegate_.get(),
+        proxy_delegate_.get(), nullptr /* http_user_agent_settings */,
         SSLClientSocketContext(session_deps_.cert_verifier.get(),
                                session_deps_.channel_id_service.get(),
                                session_deps_.transport_security_state.get(),
diff --git a/net/http/http_stream_factory_job.cc b/net/http/http_stream_factory_job.cc
index 8de407e..aafd478 100644
--- a/net/http/http_stream_factory_job.cc
+++ b/net/http/http_stream_factory_job.cc
@@ -954,10 +954,9 @@
     DCHECK(!is_websocket_);
     DCHECK(request_info_.socket_tag == SocketTag());
     return PreconnectSocketsForHttpRequest(
-        GetSocketGroup(), destination_, request_info_.extra_headers,
-        request_info_.load_flags, priority_, session_, proxy_info_,
-        server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode,
-        net_log_, num_streams_);
+        GetSocketGroup(), destination_, request_info_.load_flags, priority_,
+        session_, proxy_info_, server_ssl_config_, proxy_ssl_config_,
+        request_info_.privacy_mode, net_log_, num_streams_);
   }
 
   // If we can't use a HTTP/2 session, don't bother checking for one after
@@ -977,19 +976,18 @@
     SSLConfig websocket_server_ssl_config = server_ssl_config_;
     websocket_server_ssl_config.alpn_protos.clear();
     return InitSocketHandleForWebSocketRequest(
-        GetSocketGroup(), destination_, request_info_.extra_headers,
-        request_info_.load_flags, priority_, session_, proxy_info_,
-        websocket_server_ssl_config, proxy_ssl_config_,
+        GetSocketGroup(), destination_, request_info_.load_flags, priority_,
+        session_, proxy_info_, websocket_server_ssl_config, proxy_ssl_config_,
         request_info_.privacy_mode, net_log_, connection_.get(),
         resolution_callback, io_callback_, proxy_auth_callback);
   }
 
   return InitSocketHandleForHttpRequest(
-      GetSocketGroup(), destination_, request_info_.extra_headers,
-      request_info_.load_flags, priority_, session_, proxy_info_, quic_version_,
-      server_ssl_config_, proxy_ssl_config_, request_info_.privacy_mode,
-      request_info_.socket_tag, net_log_, connection_.get(),
-      resolution_callback, io_callback_, proxy_auth_callback);
+      GetSocketGroup(), destination_, request_info_.load_flags, priority_,
+      session_, proxy_info_, quic_version_, server_ssl_config_,
+      proxy_ssl_config_, request_info_.privacy_mode, request_info_.socket_tag,
+      net_log_, connection_.get(), resolution_callback, io_callback_,
+      proxy_auth_callback);
 }
 
 void HttpStreamFactory::Job::OnQuicHostResolution(int result) {
diff --git a/net/http/http_stream_factory_unittest.cc b/net/http/http_stream_factory_unittest.cc
index 7161374..19c3ce5 100644
--- a/net/http/http_stream_factory_unittest.cc
+++ b/net/http/http_stream_factory_unittest.cc
@@ -476,6 +476,7 @@
                  nullptr /* socket_factory */,
                  host_resolver,
                  nullptr /* proxy_delegate */,
+                 nullptr /* http_user_agent_settings */,
                  nullptr /* cert_verifier */,
                  nullptr /* channel_id_server */,
                  nullptr /* transport_security_state */,
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index fd626511..5fc84d1 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -78,6 +78,7 @@
 #include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "net/url_request/static_http_user_agent_settings.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_job_factory_impl.h"
 #include "net/url_request/url_request_test_util.h"
@@ -8143,6 +8144,8 @@
 // Checks if a request's specified "user-agent" header shows up correctly in the
 // CONNECT request to a QUIC proxy.
 TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
+  const char kConfiguredUserAgent[] = "Configured User-Agent";
+  const char kRequestUserAgent[] = "Request User-Agent";
   session_params_.enable_quic = true;
   session_params_.enable_quic_proxies_for_https_urls = true;
   proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
@@ -8154,7 +8157,7 @@
       SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
 
   spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
-  headers["user-agent"] = "Chromium Ultra Awesome X Edition";
+  headers["user-agent"] = kConfiguredUserAgent;
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructClientRequestHeadersPacket(
                        2, GetNthClientInitiatedBidirectionalStreamId(0), true,
@@ -8165,11 +8168,14 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
+  StaticHttpUserAgentSettings http_user_agent_settings(
+      std::string() /* accept_language */, kConfiguredUserAgent);
+  session_context_.http_user_agent_settings = &http_user_agent_settings;
   CreateSession();
 
   request_.url = GURL("https://mail.example.org/");
   request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
-                                   "Chromium Ultra Awesome X Edition");
+                                   kRequestUserAgent);
   HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
   HeadersHandler headers_handler;
   trans.SetBeforeHeadersSentCallback(
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index b753e4c..dba6485e 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -529,6 +529,7 @@
             nullptr /* client_socket_factory */,
             nullptr /* host_resolver */,
             nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
             SSLClientSocketContext(),
             SSLClientSocketContext(),
             nullptr /* socket_performance_watcher_factory */,
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc
index b336789..99943a3 100644
--- a/net/socket/client_socket_pool_manager.cc
+++ b/net/socket/client_socket_pool_manager.cc
@@ -11,7 +11,6 @@
 #include "base/strings/stringprintf.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_proxy_connect_job.h"
-#include "net/http/http_request_info.h"
 #include "net/http/http_stream_factory.h"
 #include "net/proxy_resolution/proxy_info.h"
 #include "net/socket/client_socket_handle.h"
@@ -72,7 +71,6 @@
 CreateSocketParamsAndGetGroupName(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
-    const HttpRequestHeaders& request_extra_headers,
     int request_load_flags,
     HttpNetworkSession* session,
     const ProxyInfo& proxy_info,
@@ -132,9 +130,6 @@
         *connection_group = "https_proxy/" + *connection_group;
       }
 
-      std::string user_agent;
-      request_extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
-                                      &user_agent);
       scoped_refptr<SSLSocketParams> ssl_params;
       if (!proxy_info.is_http()) {
         proxy_tcp_params = new TransportSocketParams(
@@ -152,11 +147,10 @@
       }
 
       http_proxy_params = new HttpProxySocketParams(
-          proxy_tcp_params, ssl_params, quic_version, user_agent,
-          origin_host_port, session->http_auth_cache(),
-          session->http_auth_handler_factory(), session->spdy_session_pool(),
-          session->quic_stream_factory(), proxy_server.is_trusted_proxy(),
-          force_tunnel || using_ssl,
+          proxy_tcp_params, ssl_params, quic_version, origin_host_port,
+          session->http_auth_cache(), session->http_auth_handler_factory(),
+          session->spdy_session_pool(), session->quic_stream_factory(),
+          proxy_server.is_trusted_proxy(), force_tunnel || using_ssl,
           NetworkTrafficAnnotationTag(proxy_info.traffic_annotation()));
     } else {
       DCHECK(proxy_info.is_socks());
@@ -213,7 +207,6 @@
 int InitSocketPoolHelper(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
-    const HttpRequestHeaders& request_extra_headers,
     int request_load_flags,
     RequestPriority request_priority,
     HttpNetworkSession* session,
@@ -234,10 +227,9 @@
   std::string connection_group;
   scoped_refptr<TransportClientSocketPool::SocketParams> socket_params =
       CreateSocketParamsAndGetGroupName(
-          group_type, endpoint, request_extra_headers, request_load_flags,
-          session, proxy_info, quic_version, ssl_config_for_origin,
-          ssl_config_for_proxy, force_tunnel, privacy_mode, resolution_callback,
-          &connection_group);
+          group_type, endpoint, request_load_flags, session, proxy_info,
+          quic_version, ssl_config_for_origin, ssl_config_for_proxy,
+          force_tunnel, privacy_mode, resolution_callback, &connection_group);
 
   TransportClientSocketPool* pool =
       session->GetSocketPool(socket_pool_type, proxy_info.proxy_server());
@@ -340,7 +332,6 @@
 int InitSocketHandleForHttpRequest(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
-    const HttpRequestHeaders& request_extra_headers,
     int request_load_flags,
     RequestPriority request_priority,
     HttpNetworkSession* session,
@@ -357,18 +348,16 @@
     const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback) {
   DCHECK(socket_handle);
   return InitSocketPoolHelper(
-      group_type, endpoint, request_extra_headers, request_load_flags,
-      request_priority, session, proxy_info, quic_version,
-      ssl_config_for_origin, ssl_config_for_proxy, /*force_tunnel=*/false,
-      privacy_mode, socket_tag, net_log, 0, socket_handle,
-      HttpNetworkSession::NORMAL_SOCKET_POOL, resolution_callback,
-      std::move(callback), proxy_auth_callback);
+      group_type, endpoint, request_load_flags, request_priority, session,
+      proxy_info, quic_version, ssl_config_for_origin, ssl_config_for_proxy,
+      /*force_tunnel=*/false, privacy_mode, socket_tag, net_log, 0,
+      socket_handle, HttpNetworkSession::NORMAL_SOCKET_POOL,
+      resolution_callback, std::move(callback), proxy_auth_callback);
 }
 
 int InitSocketHandleForWebSocketRequest(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
-    const HttpRequestHeaders& request_extra_headers,
     int request_load_flags,
     RequestPriority request_priority,
     HttpNetworkSession* session,
@@ -383,9 +372,9 @@
     const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback) {
   DCHECK(socket_handle);
   return InitSocketPoolHelper(
-      group_type, endpoint, request_extra_headers, request_load_flags,
-      request_priority, session, proxy_info, quic::QUIC_VERSION_UNSUPPORTED,
-      ssl_config_for_origin, ssl_config_for_proxy,
+      group_type, endpoint, request_load_flags, request_priority, session,
+      proxy_info, quic::QUIC_VERSION_UNSUPPORTED, ssl_config_for_origin,
+      ssl_config_for_proxy,
       /*force_tunnel=*/true, privacy_mode, SocketTag(), net_log, 0,
       socket_handle, HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
       resolution_callback, std::move(callback), proxy_auth_callback);
@@ -405,14 +394,13 @@
     CompletionOnceCallback callback,
     const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback) {
   DCHECK(socket_handle);
-  HttpRequestHeaders request_extra_headers;
   return InitSocketPoolHelper(
-      ClientSocketPoolManager::NORMAL_GROUP, host_port_pair,
-      request_extra_headers, request_load_flags, request_priority, session,
-      proxy_info, quic::QUIC_VERSION_UNSUPPORTED, ssl_config_for_origin,
-      ssl_config_for_proxy, /*force_tunnel=*/true, privacy_mode, SocketTag(),
-      net_log, 0, socket_handle, HttpNetworkSession::NORMAL_SOCKET_POOL,
-      OnHostResolutionCallback(), std::move(callback), proxy_auth_callback);
+      ClientSocketPoolManager::NORMAL_GROUP, host_port_pair, request_load_flags,
+      request_priority, session, proxy_info, quic::QUIC_VERSION_UNSUPPORTED,
+      ssl_config_for_origin, ssl_config_for_proxy, /*force_tunnel=*/true,
+      privacy_mode, SocketTag(), net_log, 0, socket_handle,
+      HttpNetworkSession::NORMAL_SOCKET_POOL, OnHostResolutionCallback(),
+      std::move(callback), proxy_auth_callback);
 }
 
 int InitSocketHandleForTlsConnect(
@@ -429,12 +417,10 @@
     CompletionOnceCallback callback,
     const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback) {
   DCHECK(socket_handle);
-  HttpRequestHeaders request_extra_headers;
   return InitSocketPoolHelper(
-      ClientSocketPoolManager::SSL_GROUP, endpoint, request_extra_headers,
-      request_load_flags, request_priority, session, proxy_info,
-      quic::QUIC_VERSION_UNSUPPORTED, ssl_config_for_origin,
-      ssl_config_for_proxy,
+      ClientSocketPoolManager::SSL_GROUP, endpoint, request_load_flags,
+      request_priority, session, proxy_info, quic::QUIC_VERSION_UNSUPPORTED,
+      ssl_config_for_origin, ssl_config_for_proxy,
       /*force_tunnel=*/true, privacy_mode, SocketTag(), net_log, 0,
       socket_handle, HttpNetworkSession::NORMAL_SOCKET_POOL,
       OnHostResolutionCallback(), std::move(callback), proxy_auth_callback);
@@ -443,7 +429,6 @@
 int PreconnectSocketsForHttpRequest(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
-    const HttpRequestHeaders& request_extra_headers,
     int request_load_flags,
     RequestPriority request_priority,
     HttpNetworkSession* session,
@@ -454,9 +439,9 @@
     const NetLogWithSource& net_log,
     int num_preconnect_streams) {
   return InitSocketPoolHelper(
-      group_type, endpoint, request_extra_headers, request_load_flags,
-      request_priority, session, proxy_info, quic::QUIC_VERSION_UNSUPPORTED,
-      ssl_config_for_origin, ssl_config_for_proxy,
+      group_type, endpoint, request_load_flags, request_priority, session,
+      proxy_info, quic::QUIC_VERSION_UNSUPPORTED, ssl_config_for_origin,
+      ssl_config_for_proxy,
       /*force_tunnel=*/false, privacy_mode, SocketTag(), net_log,
       num_preconnect_streams, NULL, HttpNetworkSession::NORMAL_SOCKET_POOL,
       OnHostResolutionCallback(), CompletionOnceCallback(),
diff --git a/net/socket/client_socket_pool_manager.h b/net/socket/client_socket_pool_manager.h
index cb683d3..71aa9a2 100644
--- a/net/socket/client_socket_pool_manager.h
+++ b/net/socket/client_socket_pool_manager.h
@@ -32,7 +32,6 @@
 class ClientSocketHandle;
 class HostPortPair;
 class HttpNetworkSession;
-class HttpRequestHeaders;
 class NetLogWithSource;
 class ProxyInfo;
 class ProxyServer;
@@ -109,7 +108,6 @@
 int InitSocketHandleForHttpRequest(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
-    const HttpRequestHeaders& request_extra_headers,
     int request_load_flags,
     RequestPriority request_priority,
     HttpNetworkSession* session,
@@ -137,7 +135,6 @@
 int InitSocketHandleForWebSocketRequest(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
-    const HttpRequestHeaders& request_extra_headers,
     int request_load_flags,
     RequestPriority request_priority,
     HttpNetworkSession* session,
@@ -194,7 +191,6 @@
 int PreconnectSocketsForHttpRequest(
     ClientSocketPoolManager::SocketGroupType group_type,
     const HostPortPair& endpoint,
-    const HttpRequestHeaders& request_extra_headers,
     int request_load_flags,
     RequestPriority request_priority,
     HttpNetworkSession* session,
diff --git a/net/socket/client_socket_pool_manager_impl.cc b/net/socket/client_socket_pool_manager_impl.cc
index c0de62a..19d97f4 100644
--- a/net/socket/client_socket_pool_manager_impl.cc
+++ b/net/socket/client_socket_pool_manager_impl.cc
@@ -38,6 +38,7 @@
     SSLConfigService* ssl_config_service,
     WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
     ProxyDelegate* proxy_delegate,
+    const HttpUserAgentSettings* http_user_agent_settings,
     HttpNetworkSession::SocketPoolType pool_type)
     : net_log_(net_log),
       socket_factory_(socket_factory),
@@ -55,6 +56,7 @@
       ssl_config_service_(ssl_config_service),
       websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager),
       proxy_delegate_(proxy_delegate),
+      http_user_agent_settings_(http_user_agent_settings),
       pool_type_(pool_type) {
   CertDatabase::GetInstance()->AddObserver(this);
 }
@@ -101,21 +103,22 @@
     new_pool = std::make_unique<WebSocketTransportClientSocketPool>(
         sockets_per_proxy_server, sockets_per_group,
         unused_idle_socket_timeout(pool_type_), socket_factory_, host_resolver_,
-        proxy_delegate_, cert_verifier_, channel_id_service_,
-        transport_security_state_, cert_transparency_verifier_,
-        ct_policy_enforcer_, ssl_client_session_cache_,
-        ssl_client_session_cache_privacy_mode_, ssl_config_service_,
-        network_quality_estimator_, websocket_endpoint_lock_manager_, net_log_);
+        proxy_delegate_, http_user_agent_settings_, cert_verifier_,
+        channel_id_service_, transport_security_state_,
+        cert_transparency_verifier_, ct_policy_enforcer_,
+        ssl_client_session_cache_, ssl_client_session_cache_privacy_mode_,
+        ssl_config_service_, network_quality_estimator_,
+        websocket_endpoint_lock_manager_, net_log_);
   } else {
     new_pool = std::make_unique<TransportClientSocketPool>(
         sockets_per_proxy_server, sockets_per_group,
         unused_idle_socket_timeout(pool_type_), socket_factory_, host_resolver_,
-        proxy_delegate_, cert_verifier_, channel_id_service_,
-        transport_security_state_, cert_transparency_verifier_,
-        ct_policy_enforcer_, ssl_client_session_cache_,
-        ssl_client_session_cache_privacy_mode_, ssl_config_service_,
-        socket_performance_watcher_factory_, network_quality_estimator_,
-        net_log_);
+        proxy_delegate_, http_user_agent_settings_, cert_verifier_,
+        channel_id_service_, transport_security_state_,
+        cert_transparency_verifier_, ct_policy_enforcer_,
+        ssl_client_session_cache_, ssl_client_session_cache_privacy_mode_,
+        ssl_config_service_, socket_performance_watcher_factory_,
+        network_quality_estimator_, net_log_);
   }
 
   std::pair<TransportSocketPoolMap::iterator, bool> ret =
diff --git a/net/socket/client_socket_pool_manager_impl.h b/net/socket/client_socket_pool_manager_impl.h
index 8568410b..446ce2a 100644
--- a/net/socket/client_socket_pool_manager_impl.h
+++ b/net/socket/client_socket_pool_manager_impl.h
@@ -32,6 +32,7 @@
 class ClientSocketFactory;
 class CTVerifier;
 class HostResolver;
+class HttpUserAgentSettings;
 class NetLog;
 class NetworkQualityEstimator;
 class ProxyDelegate;
@@ -63,6 +64,7 @@
       SSLConfigService* ssl_config_service,
       WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
       ProxyDelegate* proxy_delegate,
+      const HttpUserAgentSettings* http_user_agent_settings,
       HttpNetworkSession::SocketPoolType pool_type);
   ~ClientSocketPoolManagerImpl() override;
 
@@ -102,6 +104,7 @@
   SSLConfigService* const ssl_config_service_;
   WebSocketEndpointLockManager* const websocket_endpoint_lock_manager_;
   ProxyDelegate* const proxy_delegate_;
+  const HttpUserAgentSettings* const http_user_agent_settings_;
   const HttpNetworkSession::SocketPoolType pool_type_;
 
   TransportSocketPoolMap socket_pools_;
diff --git a/net/socket/connect_job.cc b/net/socket/connect_job.cc
index 10ba19b..f35a8656 100644
--- a/net/socket/connect_job.cc
+++ b/net/socket/connect_job.cc
@@ -21,6 +21,7 @@
     ClientSocketFactory* client_socket_factory,
     HostResolver* host_resolver,
     ProxyDelegate* proxy_delegate,
+    const HttpUserAgentSettings* http_user_agent_settings,
     const SSLClientSocketContext& ssl_client_socket_context,
     const SSLClientSocketContext& ssl_client_socket_context_privacy_mode,
     SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
@@ -30,6 +31,7 @@
     : client_socket_factory(client_socket_factory),
       host_resolver(host_resolver),
       proxy_delegate(proxy_delegate),
+      http_user_agent_settings(http_user_agent_settings),
       ssl_client_socket_context(ssl_client_socket_context),
       ssl_client_socket_context_privacy_mode(
           ssl_client_socket_context_privacy_mode),
diff --git a/net/socket/connect_job.h b/net/socket/connect_job.h
index 49dedfbf..65dc78b9 100644
--- a/net/socket/connect_job.h
+++ b/net/socket/connect_job.h
@@ -29,6 +29,7 @@
 class HostResolver;
 class HttpAuthController;
 class HttpResponseInfo;
+class HttpUserAgentSettings;
 class NetLog;
 class NetworkQualityEstimator;
 class ProxyDelegate;
@@ -46,6 +47,7 @@
       ClientSocketFactory* client_socket_factory,
       HostResolver* host_resolver,
       ProxyDelegate* proxy_delegate,
+      const HttpUserAgentSettings* http_user_agent_settings,
       const SSLClientSocketContext& ssl_client_socket_context,
       const SSLClientSocketContext& ssl_client_socket_context_privacy_mode,
       SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
@@ -60,6 +62,7 @@
   ClientSocketFactory* client_socket_factory;
   HostResolver* host_resolver;
   ProxyDelegate* proxy_delegate;
+  const HttpUserAgentSettings* http_user_agent_settings;
   SSLClientSocketContext ssl_client_socket_context;
   SSLClientSocketContext ssl_client_socket_context_privacy_mode;
   SocketPerformanceWatcherFactory* socket_performance_watcher_factory;
diff --git a/net/socket/connect_job_unittest.cc b/net/socket/connect_job_unittest.cc
index 915d02b..cfd1c58 100644
--- a/net/socket/connect_job_unittest.cc
+++ b/net/socket/connect_job_unittest.cc
@@ -95,6 +95,7 @@
             nullptr /* client_socket_factory */,
             nullptr /* host_resolver */,
             nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
             SSLClientSocketContext(),
             SSLClientSocketContext(),
             nullptr /* socket_performance_watcher_factory */,
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 90ede319..7ecb940 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -2078,6 +2078,7 @@
           socket_factory,
           nullptr /* host_resolver */,
           nullptr /* proxy_delegate */,
+          nullptr /* http_user_agent_settings */,
           nullptr /* cert_verifier */,
           nullptr /* channel_id_server */,
           nullptr /* transport_security_state */,
diff --git a/net/socket/socks_connect_job_unittest.cc b/net/socket/socks_connect_job_unittest.cc
index 12d6d3a..a0c86a7 100644
--- a/net/socket/socks_connect_job_unittest.cc
+++ b/net/socket/socks_connect_job_unittest.cc
@@ -54,6 +54,7 @@
             &client_socket_factory_,
             &host_resolver_,
             nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
             SSLClientSocketContext(),
             SSLClientSocketContext(),
             nullptr /* socket_performance_watcher_factory */,
diff --git a/net/socket/ssl_connect_job_unittest.cc b/net/socket/ssl_connect_job_unittest.cc
index 7c31bcd1..bd0b411 100644
--- a/net/socket/ssl_connect_job_unittest.cc
+++ b/net/socket/ssl_connect_job_unittest.cc
@@ -37,7 +37,6 @@
 #include "net/socket/socket_tag.h"
 #include "net/socket/socket_test_util.h"
 #include "net/socket/socks_connect_job.h"
-#include "net/socket/transport_client_socket_pool.h"
 #include "net/socket/transport_connect_job.h"
 #include "net/ssl/ssl_config_service_defaults.h"
 #include "net/test/gtest_util.h"
@@ -49,11 +48,6 @@
 namespace net {
 namespace {
 
-const int kMaxSockets = 32;
-const int kMaxSocketsPerGroup = 6;
-constexpr base::TimeDelta kUnusedIdleSocketTimeout =
-    base::TimeDelta::FromSeconds(10);
-
 // Just check that all connect times are set to base::TimeTicks::Now(), for
 // tests that don't update the mocked out time.
 void CheckConnectTimesSet(const LoadTimingInfo::ConnectTiming& connect_timing) {
@@ -113,7 +107,6 @@
             new HttpProxySocketParams(proxy_transport_socket_params_,
                                       nullptr /* ssl_params */,
                                       quic::QUIC_VERSION_UNSUPPORTED,
-                                      std::string(),
                                       HostPortPair("host", 80),
                                       session_->http_auth_cache(),
                                       session_->http_auth_handler_factory(),
@@ -122,28 +115,11 @@
                                       /*is_trusted_proxy=*/false,
                                       /*tunnel=*/true,
                                       TRAFFIC_ANNOTATION_FOR_TESTS)),
-        http_proxy_socket_pool_(
-            kMaxSockets,
-            kMaxSocketsPerGroup,
-            kUnusedIdleSocketTimeout,
-            &socket_factory_,
-            &host_resolver_,
-            nullptr /* proxy_delegate */,
-            nullptr /* cert_verifier */,
-            nullptr /* channel_id_server */,
-            nullptr /* transport_security_state */,
-            nullptr /* cert_transparency_verifier */,
-            nullptr /* ct_policy_enforcer */,
-            nullptr /* ssl_client_session_cache */,
-            nullptr /* ssl_client_session_cache_privacy_mode */,
-            nullptr /* ssl_config_service */,
-            nullptr /* socket_performance_watcher_factory */,
-            nullptr /* network_quality_estimator */,
-            nullptr /* net_log */),
         common_connect_job_params_(
             &socket_factory_,
             &host_resolver_,
             nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
             ssl_client_socket_context_,
             ssl_client_socket_context_,
             nullptr /* socket_performance_watcher */,
@@ -222,8 +198,6 @@
   scoped_refptr<SOCKSSocketParams> socks_socket_params_;
   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
 
-  TransportClientSocketPool http_proxy_socket_pool_;
-
   SSLConfig ssl_config_;
   const CommonConnectJobParams common_connect_job_params_;
 };
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index 2c00e22c..69b9224f 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -122,6 +122,7 @@
         ClientSocketFactory* client_socket_factory,
         HostResolver* host_resolver,
         ProxyDelegate* proxy_delegate,
+        const HttpUserAgentSettings* http_user_agent_settings,
         const SSLClientSocketContext& ssl_client_socket_context,
         const SSLClientSocketContext& ssl_client_socket_context_privacy_mode,
         SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
@@ -131,6 +132,7 @@
           client_socket_factory,
           host_resolver,
           proxy_delegate,
+          http_user_agent_settings,
           ssl_client_socket_context,
           ssl_client_socket_context_privacy_mode,
           socket_performance_watcher_factory,
@@ -157,6 +159,7 @@
     ClientSocketFactory* client_socket_factory,
     HostResolver* host_resolver,
     ProxyDelegate* proxy_delegate,
+    const HttpUserAgentSettings* http_user_agent_settings,
     CertVerifier* cert_verifier,
     ChannelIDService* channel_id_service,
     TransportSecurityState* transport_security_state,
@@ -176,6 +179,7 @@
                 client_socket_factory,
                 host_resolver,
                 proxy_delegate,
+                http_user_agent_settings,
                 SSLClientSocketContext(cert_verifier,
                                        channel_id_service,
                                        transport_security_state,
diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h
index e8aa4873..eda35d4 100644
--- a/net/socket/transport_client_socket_pool.h
+++ b/net/socket/transport_client_socket_pool.h
@@ -29,6 +29,7 @@
 class CTPolicyEnforcer;
 class HostResolver;
 class HttpProxySocketParams;
+class HttpUserAgentSettings;
 class NetLog;
 class NetLogWithSource;
 class NetworkQualityEstimator;
@@ -98,6 +99,7 @@
       ClientSocketFactory* client_socket_factory,
       HostResolver* host_resolver,
       ProxyDelegate* proxy_delegate,
+      const HttpUserAgentSettings* http_user_agent_settings,
       CertVerifier* cert_verifier,
       ChannelIDService* channel_id_service,
       TransportSecurityState* transport_security_state,
@@ -173,6 +175,7 @@
         ClientSocketFactory* client_socket_factory,
         HostResolver* host_resolver,
         ProxyDelegate* proxy_delegate,
+        const HttpUserAgentSettings* http_user_agent_settings,
         const SSLClientSocketContext& ssl_client_socket_context,
         const SSLClientSocketContext& ssl_client_socket_context_privacy_mode,
         SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc
index 2e8aa5e..64255af 100644
--- a/net/socket/transport_client_socket_pool_unittest.cc
+++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -104,8 +104,8 @@
     pool_ = std::make_unique<TransportClientSocketPool>(
         kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
         &client_socket_factory_, session_deps_.host_resolver.get(),
-        nullptr /* proxy_delegate */, session_deps_.cert_verifier.get(),
-        nullptr /* channel_id_server */,
+        nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+        session_deps_.cert_verifier.get(), nullptr /* channel_id_server */,
         session_deps_.transport_security_state.get(),
         session_deps_.cert_transparency_verifier.get(),
         session_deps_.ct_policy_enforcer.get(),
@@ -118,8 +118,8 @@
     tagging_pool_ = std::make_unique<TransportClientSocketPool>(
         kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
         &tagging_client_socket_factory_, session_deps_.host_resolver.get(),
-        nullptr /* proxy_delegate */, session_deps_.cert_verifier.get(),
-        nullptr /* channel_id_server */,
+        nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+        session_deps_.cert_verifier.get(), nullptr /* channel_id_server */,
         session_deps_.transport_security_state.get(),
         session_deps_.cert_transparency_verifier.get(),
         session_deps_.ct_policy_enforcer.get(),
@@ -133,6 +133,7 @@
         kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
         ClientSocketFactory::GetDefaultFactory(),
         session_deps_.host_resolver.get(), nullptr /* proxy_delegate */,
+        nullptr /* http_user_agent_settings */,
         session_deps_.cert_verifier.get(), nullptr /* channel_id_server */,
         session_deps_.transport_security_state.get(),
         session_deps_.cert_transparency_verifier.get(),
@@ -490,8 +491,8 @@
   TransportClientSocketPool pool(
       kMaxSockets, 1, kUnusedIdleSocketTimeout, &client_socket_factory_,
       session_deps_.host_resolver.get(), nullptr /* proxy_delegate */,
-      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
-      nullptr /* transport_security_state */,
+      nullptr /* http_user_agent_settings */, nullptr /* cert_verifier */,
+      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -1755,7 +1756,7 @@
                   HostPortPair("http.proxy.host", 80), false,
                   OnHostResolutionCallback()),
               nullptr /* ssl_params */, quic::QUIC_VERSION_UNSUPPORTED,
-              std::string(), HostPortPair("www.google.com", 80),
+              HostPortPair("www.google.com", 80),
               http_network_session_->http_auth_cache(),
               http_network_session_->http_auth_handler_factory(),
               http_network_session_->spdy_session_pool(),
@@ -1824,7 +1825,7 @@
                   HostPortPair("http.proxy.host", 80), false,
                   OnHostResolutionCallback()),
               nullptr /* ssl_params */, quic::QUIC_VERSION_UNSUPPORTED,
-              std::string(), HostPortPair("www.google.com", 443),
+              HostPortPair("www.google.com", 443),
               http_network_session_->http_auth_cache(),
               http_network_session_->http_auth_handler_factory(),
               http_network_session_->spdy_session_pool(),
diff --git a/net/socket/transport_connect_job_unittest.cc b/net/socket/transport_connect_job_unittest.cc
index 0fbc0a6..decfde5 100644
--- a/net/socket/transport_connect_job_unittest.cc
+++ b/net/socket/transport_connect_job_unittest.cc
@@ -37,6 +37,7 @@
             &client_socket_factory_,
             &host_resolver_,
             nullptr /* proxy_delegate */,
+            nullptr /* http_user_agent_settings */,
             SSLClientSocketContext(),
             SSLClientSocketContext(),
             nullptr /* socket_performance_watcher_factory */,
diff --git a/net/socket/websocket_transport_client_socket_pool.cc b/net/socket/websocket_transport_client_socket_pool.cc
index 4a5c6d0f..87914b78 100644
--- a/net/socket/websocket_transport_client_socket_pool.cc
+++ b/net/socket/websocket_transport_client_socket_pool.cc
@@ -33,6 +33,7 @@
     ClientSocketFactory* client_socket_factory,
     HostResolver* host_resolver,
     ProxyDelegate* proxy_delegate,
+    const HttpUserAgentSettings* http_user_agent_settings,
     CertVerifier* cert_verifier,
     ChannelIDService* channel_id_service,
     TransportSecurityState* transport_security_state,
@@ -51,6 +52,7 @@
           client_socket_factory,
           host_resolver,
           proxy_delegate,
+          http_user_agent_settings,
           cert_verifier,
           channel_id_service,
           transport_security_state,
@@ -66,6 +68,7 @@
           client_socket_factory,
           host_resolver,
           proxy_delegate,
+          http_user_agent_settings,
           SSLClientSocketContext(cert_verifier,
                                  channel_id_service,
                                  transport_security_state,
diff --git a/net/socket/websocket_transport_client_socket_pool.h b/net/socket/websocket_transport_client_socket_pool.h
index 4fe0252..9a4b401 100644
--- a/net/socket/websocket_transport_client_socket_pool.h
+++ b/net/socket/websocket_transport_client_socket_pool.h
@@ -33,6 +33,7 @@
 
 class ClientSocketFactory;
 class HostResolver;
+class HttpUserAgentSettings;
 class NetLog;
 class NetworkQualityEstimator;
 class ProxyDelegate;
@@ -50,6 +51,7 @@
       ClientSocketFactory* client_socket_factory,
       HostResolver* host_resolver,
       ProxyDelegate* proxy_delegate,
+      const HttpUserAgentSettings* http_user_agent_settings,
       CertVerifier* cert_verifier,
       ChannelIDService* channel_id_service,
       TransportSecurityState* transport_security_state,
diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc
index 13d6678..bc01f68 100644
--- a/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -75,6 +75,7 @@
               &client_socket_factory_,
               host_resolver_.get(),
               nullptr /* proxy_delegate */,
+              nullptr /* http_user_agent_settings */,
               nullptr /* cert_verifier */,
               nullptr /* channel_id_server */,
               nullptr /* transport_security_state */,
@@ -565,8 +566,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -612,8 +614,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -658,8 +661,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -696,8 +700,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -735,8 +740,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -778,8 +784,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -829,8 +836,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -874,8 +882,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
@@ -923,8 +932,9 @@
   WebSocketTransportClientSocketPool pool(
       kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
       &client_socket_factory_, host_resolver_.get(),
-      nullptr /* proxy_delegate */, nullptr /* cert_verifier */,
-      nullptr /* channel_id_server */, nullptr /* transport_security_state */,
+      nullptr /* proxy_delegate */, nullptr /* http_user_agent_settings */,
+      nullptr /* cert_verifier */, nullptr /* channel_id_server */,
+      nullptr /* transport_security_state */,
       nullptr /* cert_transparency_verifier */,
       nullptr /* ct_policy_enforcer */, nullptr /* ssl_client_session_cache */,
       nullptr /* ssl_client_session_cache_privacy_mode */,
diff --git a/net/spdy/platform/impl/spdy_logging_impl.h b/net/spdy/platform/impl/spdy_logging_impl.h
new file mode 100644
index 0000000..cc79854
--- /dev/null
+++ b/net/spdy/platform/impl/spdy_logging_impl.h
@@ -0,0 +1,86 @@
+// Copyright (c) 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 NET_SPDY_PLATFORM_IMPL_SPDY_LOGGING_IMPL_H_
+#define NET_SPDY_PLATFORM_IMPL_SPDY_LOGGING_IMPL_H_
+
+#include "base/logging.h"
+#include "build/build_config.h"
+#include "net/base/net_export.h"
+
+#define SPDY_LOG_IMPL(severity) SPDY_CHROMIUM_LOG_##severity
+#define SPDY_VLOG_IMPL(verbose_level) VLOG(verbose_level)
+#define SPDY_DLOG_IMPL(severity) SPDY_CHROMIUM_DLOG_##severity
+#define SPDY_DLOG_IF_IMPL(severity, condition) \
+  SPDY_CHROMIUM_DLOG_IF_##severity(condition)
+#define SPDY_DVLOG_IMPL(verbose_level) DVLOG(verbose_level)
+#define SPDY_DVLOG_IF_IMPL(verbose_level, condition) \
+  DVLOG_IF(verbose_level, condition)
+
+#define SPDY_CHROMIUM_LOG_INFO VLOG(1)
+#define SPDY_CHROMIUM_LOG_WARNING DLOG(WARNING)
+#define SPDY_CHROMIUM_LOG_ERROR DLOG(ERROR)
+#define SPDY_CHROMIUM_LOG_FATAL LOG(FATAL)
+#define SPDY_CHROMIUM_LOG_DFATAL LOG(DFATAL)
+
+#define SPDY_CHROMIUM_DLOG_INFO DVLOG(1)
+#define SPDY_CHROMIUM_DLOG_WARNING DLOG(WARNING)
+#define SPDY_CHROMIUM_DLOG_ERROR DLOG(ERROR)
+#define SPDY_CHROMIUM_DLOG_FATAL DLOG(FATAL)
+#define SPDY_CHROMIUM_DLOG_DFATAL DLOG(DFATAL)
+
+#define SPDY_CHROMIUM_LOG_IF_INFO(condition) VLOG_IF(1, condition)
+#define SPDY_CHROMIUM_LOG_IF_WARNING(condition) DLOG_IF(WARNING, condition)
+#define SPDY_CHROMIUM_LOG_IF_ERROR(condition) DLOG_IF(ERROR, condition)
+#define SPDY_CHROMIUM_LOG_IF_FATAL(condition) LOG_IF(FATAL, condition)
+#define SPDY_CHROMIUM_LOG_IF_DFATAL(condition) LOG_IF(DFATAL, condition)
+
+#define SPDY_CHROMIUM_DLOG_IF_INFO(condition) DVLOG_IF(1, condition)
+#define SPDY_CHROMIUM_DLOG_IF_WARNING(condition) DLOG_IF(WARNING, condition)
+#define SPDY_CHROMIUM_DLOG_IF_ERROR(condition) DLOG_IF(ERROR, condition)
+#define SPDY_CHROMIUM_DLOG_IF_FATAL(condition) DLOG_IF(FATAL, condition)
+#define SPDY_CHROMIUM_DLOG_IF_DFATAL(condition) DLOG_IF(DFATAL, condition)
+
+#define SPDY_LOG_INFO_IS_ON_IMPL() 0
+#ifdef NDEBUG
+#define SPDY_LOG_WARNING_IS_ON_IMPL() 0
+#define SPDY_LOG_ERROR_IS_ON_IMPL() 0
+#else
+#define SPDY_LOG_WARNING_IS_ON_IMPL() 1
+#define SPDY_LOG_ERROR_IS_ON_IMPL() 1
+#endif
+#define SPDY_DLOG_INFO_IS_ON_IMPL() 0
+
+#if defined(OS_WIN)
+// wingdi.h defines ERROR to be 0. When we call SPDY_DLOG(ERROR), it gets
+// substituted with 0, and it expands to SPDY_CHROMIUM_DLOG_0. To allow us to
+// keep using this syntax, we define this macro to do the same thing as
+// SPDY_CHROMIUM_DLOG_ERROR.
+#define SPDY_CHROMIUM_LOG_0 SPDY_CHROMIUM_LOG_ERROR
+#define SPDY_CHROMIUM_DLOG_0 SPDY_CHROMIUM_DLOG_ERROR
+#define SPDY_CHROMIUM_LOG_IF_0 SPDY_CHROMIUM_LOG_IF_ERROR
+#define SPDY_CHROMIUM_DLOG_IF_0 SPDY_CHROMIUM_DLOG_IF_ERROR
+#endif
+
+#define SPDY_PREDICT_FALSE_IMPL(x) x
+
+#define SPDY_NOTREACHED_IMPL() NOTREACHED()
+
+#define SPDY_PLOG_IMPL(severity) DVLOG(1)
+
+namespace spdy {
+template <typename T>
+NET_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& out,
+                                                   const std::vector<T>& v) {
+  out << "[";
+  const char* sep = "";
+  for (size_t i = 0; i < v.size(); ++i) {
+    out << sep << v[i];
+    sep = ", ";
+  }
+  return out << "]";
+}
+}  // namespace spdy
+
+#endif  // NET_SPDY_PLATFORM_IMPL_SPDY_LOGGING_IMPL_H_
diff --git a/net/spdy/platform/impl/spdy_macros_impl.h b/net/spdy/platform/impl/spdy_macros_impl.h
index e562f11..fb286bc 100644
--- a/net/spdy/platform/impl/spdy_macros_impl.h
+++ b/net/spdy/platform/impl/spdy_macros_impl.h
@@ -11,6 +11,4 @@
 #define SPDY_MUST_USE_RESULT_IMPL WARN_UNUSED_RESULT
 #define SPDY_UNUSED_IMPL ALLOW_UNUSED_TYPE
 
-#define SPDY_DVLOG_IF_IMPL DVLOG_IF
-
 #endif  // NET_SPDY_PLATFORM_IMPL_SPDY_MACROS_IMPL_H_
diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc
index 7115c81..f4103f1 100644
--- a/net/spdy/spdy_proxy_client_socket_unittest.cc
+++ b/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -221,6 +221,7 @@
           session_deps_.socket_factory.get(),
           session_deps_.host_resolver.get(),
           nullptr /* proxy_delegate */,
+          nullptr /* http_user_agent_settings */,
           SSLClientSocketContext(session_deps_.cert_verifier.get(),
                                  session_deps_.channel_id_service.get(),
                                  session_deps_.transport_security_state.get(),
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 570805fa..c3dec2e 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "net/base/host_port_pair.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/cert/ct_policy_enforcer.h"
 #include "net/cert/ct_policy_status.h"
 #include "net/cert/do_nothing_ct_verifier.h"
@@ -412,6 +413,8 @@
   context.ct_policy_enforcer = session_deps->ct_policy_enforcer.get();
   context.proxy_resolution_service =
       session_deps->proxy_resolution_service.get();
+  context.http_user_agent_settings =
+      session_deps->http_user_agent_settings.get();
   context.ssl_config_service = session_deps->ssl_config_service.get();
   context.http_auth_handler_factory =
       session_deps->http_auth_handler_factory.get();
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index a15d79e..25797eb6 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -53,6 +53,7 @@
 class HashValue;
 class HostPortPair;
 class HostResolver;
+class HttpUserAgentSettings;
 class NetLogWithSource;
 class SpdySessionKey;
 class SpdyStream;
@@ -212,6 +213,7 @@
   std::unique_ptr<CTVerifier> cert_transparency_verifier;
   std::unique_ptr<CTPolicyEnforcer> ct_policy_enforcer;
   std::unique_ptr<ProxyResolutionService> proxy_resolution_service;
+  std::unique_ptr<HttpUserAgentSettings> http_user_agent_settings;
   std::unique_ptr<SSLConfigService> ssl_config_service;
   std::unique_ptr<MockClientSocketFactory> socket_factory;
   std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
diff --git a/net/ssl/ssl_platform_key_mac.cc b/net/ssl/ssl_platform_key_mac.cc
index 4be200c..4a2fc356 100644
--- a/net/ssl/ssl_platform_key_mac.cc
+++ b/net/ssl/ssl_platform_key_mac.cc
@@ -12,7 +12,10 @@
 #include <Security/cssm.h>
 
 #include <memory>
+#include <utility>
+#include <vector>
 
+#include "base/containers/span.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/mac/availability.h"
@@ -23,6 +26,7 @@
 #include "base/macros.h"
 #include "base/memory/scoped_policy.h"
 #include "base/numerics/safe_conversions.h"
+#include "base/optional.h"
 #include "base/synchronization/lock.h"
 #include "crypto/mac_security_services_lock.h"
 #include "crypto/openssl_util.h"
@@ -63,6 +67,23 @@
     CFSTR("algid:sign:RSA:digest-PSS:SHA512:SHA512:64");
 #endif
 
+base::Optional<std::vector<uint8_t>> AddPSSPadding(
+    EVP_PKEY* pubkey,
+    const EVP_MD* md,
+    base::span<const uint8_t> digest) {
+  RSA* rsa = EVP_PKEY_get0_RSA(pubkey);
+  if (!rsa) {
+    return base::nullopt;
+  }
+  std::vector<uint8_t> ret(RSA_size(rsa));
+  if (digest.size() != EVP_MD_size(md) ||
+      !RSA_padding_add_PKCS1_PSS_mgf1(rsa, ret.data(), digest.data(), md, md,
+                                      -1 /* salt length is digest length */)) {
+    return base::nullopt;
+  }
+  return ret;
+}
+
 class ScopedCSSM_CC_HANDLE {
  public:
   ScopedCSSM_CC_HANDLE() : handle_(0) {}
@@ -86,12 +107,10 @@
 
 class SSLPlatformKeyCSSM : public ThreadedSSLPrivateKey::Delegate {
  public:
-  SSLPlatformKeyCSSM(int type,
-                     size_t max_length,
+  SSLPlatformKeyCSSM(bssl::UniquePtr<EVP_PKEY> pubkey,
                      SecKeyRef key,
                      const CSSM_KEY* cssm_key)
-      : type_(type),
-        max_length_(max_length),
+      : pubkey_(std::move(pubkey)),
         key_(key, base::scoped_policy::RETAIN),
         cssm_key_(cssm_key) {}
 
@@ -104,8 +123,8 @@
   }
 
   std::vector<uint16_t> GetAlgorithmPreferences() override {
-    return SSLPrivateKey::DefaultAlgorithmPreferences(type_,
-                                                      false /* no PSS */);
+    return SSLPrivateKey::DefaultAlgorithmPreferences(
+        EVP_PKEY_id(pubkey_.get()), true /* include PSS */);
   }
 
   Error Sign(uint16_t algorithm,
@@ -148,17 +167,38 @@
     hash_data.Length = digest_len;
     hash_data.Data = digest;
 
+    base::Optional<std::vector<uint8_t>> pss_storage;
     bssl::UniquePtr<uint8_t> free_digest_info;
     if (cssm_key_->KeyHeader.AlgorithmId == CSSM_ALGID_RSA) {
-      // CSSM expects the caller to prepend the DigestInfo.
-      int hash_nid = EVP_MD_type(md);
-      int is_alloced;
-      if (!RSA_add_pkcs1_prefix(&hash_data.Data, &hash_data.Length, &is_alloced,
-                                hash_nid, hash_data.Data, hash_data.Length)) {
-        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+      if (SSL_is_signature_algorithm_rsa_pss(algorithm)) {
+        pss_storage = AddPSSPadding(pubkey_.get(), md,
+                                    base::make_span(digest, digest_len));
+        if (!pss_storage) {
+          return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+        }
+        hash_data.Length = pss_storage->size();
+        hash_data.Data = pss_storage->data();
+
+        CSSM_CONTEXT_ATTRIBUTE padding_attr;
+        padding_attr.AttributeType = CSSM_ATTRIBUTE_PADDING;
+        padding_attr.AttributeLength = sizeof(uint32_t);
+        padding_attr.Attribute.Uint32 = CSSM_PADDING_NONE;
+        if (CSSM_UpdateContextAttributes(cssm_signature.get(), 1,
+                                         &padding_attr) != CSSM_OK) {
+          return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+        }
+      } else {
+        // CSSM expects the caller to prepend the DigestInfo.
+        int hash_nid = EVP_MD_type(md);
+        int is_alloced;
+        if (!RSA_add_pkcs1_prefix(&hash_data.Data, &hash_data.Length,
+                                  &is_alloced, hash_nid, hash_data.Data,
+                                  hash_data.Length)) {
+          return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+        }
+        if (is_alloced)
+          free_digest_info.reset(hash_data.Data);
       }
-      if (is_alloced)
-        free_digest_info.reset(hash_data.Data);
 
       // Set RSA blinding.
       CSSM_CONTEXT_ATTRIBUTE blinding_attr;
@@ -171,7 +211,7 @@
       }
     }
 
-    signature->resize(max_length_);
+    signature->resize(EVP_PKEY_size(pubkey_.get()));
     CSSM_DATA signature_data;
     signature_data.Length = signature->size();
     signature_data.Data = signature->data();
@@ -185,8 +225,7 @@
   }
 
  private:
-  int type_;
-  size_t max_length_;
+  bssl::UniquePtr<EVP_PKEY> pubkey_;
   base::ScopedCFTypeRef<SecKeyRef> key_;
   const CSSM_KEY* cssm_key_;
 
@@ -217,6 +256,8 @@
       return kSecKeyAlgorithmECDSASignatureDigestX962SHA1;
   }
 
+  // RSA-PSS is only available in macOS 10.13 and up. In earlier versions, we
+  // use a fallback path (see GetSecKeyAlgorithmWithFallback).
   if (__builtin_available(macOS 10.13, *)) {
     switch (algorithm) {
       case SSL_SIGN_RSA_PSS_SHA512:
@@ -234,15 +275,13 @@
 class API_AVAILABLE(macosx(10.12)) SSLPlatformKeySecKey
     : public ThreadedSSLPrivateKey::Delegate {
  public:
-  SSLPlatformKeySecKey(int type, size_t max_length, SecKeyRef key)
-      : key_(key, base::scoped_policy::RETAIN) {
+  SSLPlatformKeySecKey(bssl::UniquePtr<EVP_PKEY> pubkey, SecKeyRef key)
+      : pubkey_(std::move(pubkey)), key_(key, base::scoped_policy::RETAIN) {
     // Determine the algorithms supported by the key.
     for (uint16_t algorithm : SSLPrivateKey::DefaultAlgorithmPreferences(
-             type, true /* include PSS */)) {
-      SecKeyAlgorithm sec_algorithm = GetSecKeyAlgorithm(algorithm);
-      if (sec_algorithm &&
-          SecKeyIsAlgorithmSupported(key_.get(), kSecKeyOperationTypeSign,
-                                     sec_algorithm)) {
+             EVP_PKEY_id(pubkey_.get()), true /* include PSS */)) {
+      bool unused;
+      if (GetSecKeyAlgorithmWithFallback(algorithm, &unused)) {
         preferences_.push_back(algorithm);
       }
     }
@@ -263,23 +302,39 @@
   Error Sign(uint16_t algorithm,
              base::span<const uint8_t> input,
              std::vector<uint8_t>* signature) override {
-    SecKeyAlgorithm sec_algorithm = GetSecKeyAlgorithm(algorithm);
+    bool pss_fallback = false;
+    SecKeyAlgorithm sec_algorithm =
+        GetSecKeyAlgorithmWithFallback(algorithm, &pss_fallback);
     if (!sec_algorithm) {
       NOTREACHED();
       return ERR_FAILED;
     }
 
     const EVP_MD* md = SSL_get_signature_algorithm_digest(algorithm);
-    uint8_t digest[EVP_MAX_MD_SIZE];
+    uint8_t digest_buf[EVP_MAX_MD_SIZE];
     unsigned digest_len;
-    if (!md || !EVP_Digest(input.data(), input.size(), digest, &digest_len, md,
-                           nullptr)) {
+    if (!md || !EVP_Digest(input.data(), input.size(), digest_buf, &digest_len,
+                           md, nullptr)) {
       return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
     }
+    base::span<const uint8_t> digest = base::make_span(digest_buf, digest_len);
+
+    base::Optional<std::vector<uint8_t>> pss_storage;
+    if (pss_fallback) {
+      // Implement RSA-PSS by adding the padding manually and then using
+      // kSecKeyAlgorithmRSASignatureRaw.
+      DCHECK(SSL_is_signature_algorithm_rsa_pss(algorithm));
+      DCHECK_EQ(sec_algorithm, kSecKeyAlgorithmRSASignatureRaw);
+      pss_storage = AddPSSPadding(pubkey_.get(), md, digest);
+      if (!pss_storage) {
+        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+      }
+      digest = *pss_storage;
+    }
 
     base::ScopedCFTypeRef<CFDataRef> digest_ref(CFDataCreateWithBytesNoCopy(
-        kCFAllocatorDefault, digest, base::checked_cast<CFIndex>(digest_len),
-        kCFAllocatorNull));
+        kCFAllocatorDefault, digest.data(),
+        base::checked_cast<CFIndex>(digest.size()), kCFAllocatorNull));
 
     base::ScopedCFTypeRef<CFErrorRef> error;
     base::ScopedCFTypeRef<CFDataRef> signature_ref(SecKeyCreateSignature(
@@ -296,7 +351,31 @@
   }
 
  private:
+  // Returns the algorithm to use with |algorithm| and this key, or nullptr if
+  // not supported. If the resulting algorithm should be manually padded for
+  // RSA-PSS, |*out_pss_fallback| is set to true.
+  SecKeyAlgorithm GetSecKeyAlgorithmWithFallback(uint16_t algorithm,
+                                                 bool* out_pss_fallback) {
+    SecKeyAlgorithm sec_algorithm = GetSecKeyAlgorithm(algorithm);
+    if (sec_algorithm &&
+        SecKeyIsAlgorithmSupported(key_.get(), kSecKeyOperationTypeSign,
+                                   sec_algorithm)) {
+      *out_pss_fallback = false;
+      return sec_algorithm;
+    }
+
+    if (SSL_is_signature_algorithm_rsa_pss(algorithm) &&
+        SecKeyIsAlgorithmSupported(key_.get(), kSecKeyOperationTypeSign,
+                                   kSecKeyAlgorithmRSASignatureRaw)) {
+      *out_pss_fallback = true;
+      return kSecKeyAlgorithmRSASignatureRaw;
+    }
+
+    return nullptr;
+  }
+
   std::vector<uint16_t> preferences_;
+  bssl::UniquePtr<EVP_PKEY> pubkey_;
   base::ScopedCFTypeRef<SecKeyRef> key_;
 
   DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeySecKey);
@@ -305,15 +384,13 @@
 scoped_refptr<SSLPrivateKey> CreateSSLPrivateKeyForSecKey(
     const X509Certificate* certificate,
     SecKeyRef private_key) {
-  int key_type;
-  size_t max_length;
-  if (!GetClientCertInfo(certificate, &key_type, &max_length))
+  bssl::UniquePtr<EVP_PKEY> pubkey = GetClientCertPublicKey(certificate);
+  if (!pubkey)
     return nullptr;
 
   if (__builtin_available(macOS 10.12, *)) {
     return base::MakeRefCounted<ThreadedSSLPrivateKey>(
-        std::make_unique<SSLPlatformKeySecKey>(key_type, max_length,
-                                               private_key),
+        std::make_unique<SSLPlatformKeySecKey>(std::move(pubkey), private_key),
         GetSSLPlatformKeyTaskRunner());
   }
 
@@ -325,7 +402,7 @@
   }
 
   return base::MakeRefCounted<ThreadedSSLPrivateKey>(
-      std::make_unique<SSLPlatformKeyCSSM>(key_type, max_length, private_key,
+      std::make_unique<SSLPlatformKeyCSSM>(std::move(pubkey), private_key,
                                            cssm_key),
       GetSSLPlatformKeyTaskRunner());
 }
diff --git a/net/ssl/ssl_platform_key_mac_unittest.cc b/net/ssl/ssl_platform_key_mac_unittest.cc
index 87dabcb92..dadc146 100644
--- a/net/ssl/ssl_platform_key_mac_unittest.cc
+++ b/net/ssl/ssl_platform_key_mac_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
-#include "base/mac/mac_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/memory/ref_counted.h"
 #include "base/test/scoped_task_environment.h"
@@ -78,10 +77,8 @@
       CreateSSLPrivateKeyForSecIdentity(cert.get(), sec_identity.get());
   ASSERT_TRUE(key);
 
-  // Mac keys from the default provider are expected to support all algorithms,
-  // except RSA-PSS which is new in 10.13.
-  EXPECT_EQ(SSLPrivateKey::DefaultAlgorithmPreferences(
-                test_key.type, base::mac::IsAtLeastOS10_13()),
+  // Mac keys from the default provider are expected to support all algorithms.
+  EXPECT_EQ(SSLPrivateKey::DefaultAlgorithmPreferences(test_key.type, true),
             key->GetAlgorithmPreferences());
 
   TestSSLPrivateKeyMatches(key.get(), pkcs8);
diff --git a/net/ssl/ssl_platform_key_util.cc b/net/ssl/ssl_platform_key_util.cc
index 70df11b4..6a4dab0 100644
--- a/net/ssl/ssl_platform_key_util.cc
+++ b/net/ssl/ssl_platform_key_util.cc
@@ -50,9 +50,8 @@
   return g_platform_key_task_runner.Get().task_runner();
 }
 
-bool GetClientCertInfo(const X509Certificate* certificate,
-                       int* out_type,
-                       size_t* out_max_length) {
+bssl::UniquePtr<EVP_PKEY> GetClientCertPublicKey(
+    const X509Certificate* certificate) {
   crypto::OpenSSLErrStackTracer tracker(FROM_HERE);
 
   base::StringPiece spki;
@@ -60,7 +59,7 @@
           x509_util::CryptoBufferAsStringPiece(certificate->cert_buffer()),
           &spki)) {
     LOG(ERROR) << "Could not extract SPKI from certificate.";
-    return false;
+    return nullptr;
   }
 
   CBS cbs;
@@ -68,6 +67,17 @@
   bssl::UniquePtr<EVP_PKEY> key(EVP_parse_public_key(&cbs));
   if (!key || CBS_len(&cbs) != 0) {
     LOG(ERROR) << "Could not parse public key.";
+    return nullptr;
+  }
+
+  return key;
+}
+
+bool GetClientCertInfo(const X509Certificate* certificate,
+                       int* out_type,
+                       size_t* out_max_length) {
+  bssl::UniquePtr<EVP_PKEY> key = GetClientCertPublicKey(certificate);
+  if (!key) {
     return false;
   }
 
diff --git a/net/ssl/ssl_platform_key_util.h b/net/ssl/ssl_platform_key_util.h
index 2154fc5..5b2fe55 100644
--- a/net/ssl/ssl_platform_key_util.h
+++ b/net/ssl/ssl_platform_key_util.h
@@ -10,6 +10,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "net/base/net_export.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
 
 namespace net {
 
@@ -21,6 +22,10 @@
 // TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN semantics.
 scoped_refptr<base::SingleThreadTaskRunner> GetSSLPlatformKeyTaskRunner();
 
+// Returns the public key of |certificate| as an |EVP_PKEY| or nullptr on error.
+bssl::UniquePtr<EVP_PKEY> GetClientCertPublicKey(
+    const X509Certificate* certificate);
+
 // Determines the key type and maximum signature length of |certificate|'s
 // public key. |*out_type| will be set to one of the |EVP_PKEY_*| values from
 // BoringSSL.
diff --git a/net/third_party/quic/core/quic_epoll_connection_helper.h b/net/third_party/quic/core/quic_epoll_connection_helper.h
index 739b570..9abfb1a5 100644
--- a/net/third_party/quic/core/quic_epoll_connection_helper.h
+++ b/net/third_party/quic/core/quic_epoll_connection_helper.h
@@ -17,8 +17,8 @@
 #include "net/third_party/quic/core/quic_packets.h"
 #include "net/third_party/quic/core/quic_simple_buffer_allocator.h"
 #include "net/third_party/quic/core/quic_time.h"
-#include "net/third_party/quic/platform/api/quic_default_buffer_allocator.h"
 #include "net/third_party/quic/platform/api/quic_epoll.h"
+#include "net/third_party/quic/platform/api/quic_stream_buffer_allocator.h"
 #include "net/third_party/quic/platform/impl/quic_epoll_clock.h"
 
 namespace quic {
@@ -45,7 +45,7 @@
   QuicRandom* random_generator_;
   // Set up allocators.  They take up minimal memory before use.
   // Allocator for stream send buffers.
-  QuicDefaultBufferAllocator stream_buffer_allocator_;
+  QuicStreamBufferAllocator stream_buffer_allocator_;
   SimpleBufferAllocator simple_buffer_allocator_;
   QuicAllocator allocator_type_;
 };
diff --git a/net/third_party/quic/platform/api/quic_default_buffer_allocator.h b/net/third_party/quic/platform/api/quic_default_buffer_allocator.h
deleted file mode 100644
index abd37de..0000000
--- a/net/third_party/quic/platform/api/quic_default_buffer_allocator.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_DEFAULT_BUFFER_ALLOCATOR_H_
-#define NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_DEFAULT_BUFFER_ALLOCATOR_H_
-
-#include "net/third_party/quic/platform/impl/quic_default_buffer_allocator_impl.h"
-
-namespace quic {
-
-using QuicDefaultBufferAllocator = QuicStreamBufferAllocatorImpl;
-
-}
-
-#endif  // NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_DEFAULT_BUFFER_ALLOCATOR_H_
diff --git a/net/third_party/quic/platform/api/quic_default_proof_providers.h b/net/third_party/quic/platform/api/quic_default_proof_providers.h
index c5cbaff..a807a63 100644
--- a/net/third_party/quic/platform/api/quic_default_proof_providers.h
+++ b/net/third_party/quic/platform/api/quic_default_proof_providers.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "net/third_party/quic/core/crypto/proof_source.h"
 #include "net/third_party/quic/core/crypto/proof_verifier.h"
 #include "net/third_party/quic/platform/impl/quic_default_proof_providers_impl.h"
 
@@ -15,10 +16,16 @@
 // Provides a default proof verifier.  The verifier has to do a good faith
 // attempt at verifying the certificate against a reasonable root store, and not
 // just always return success.
-std::unique_ptr<ProofVerifier> CreateDefaultProofVerifier() {
+inline std::unique_ptr<ProofVerifier> CreateDefaultProofVerifier() {
   return CreateDefaultProofVerifierImpl();
 }
 
+// Provides a default proof source for CLI-based tools.  The actual certificates
+// used in the proof source should be confifgurable via command-line flags.
+inline std::unique_ptr<ProofSource> CreateDefaultProofSource() {
+  return CreateDefaultProofSourceImpl();
+}
+
 }  // namespace quic
 
 #endif  // NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_DEFAULT_PROOF_PROVIDERS_H_
diff --git a/net/third_party/quic/platform/api/quic_stream_buffer_allocator.h b/net/third_party/quic/platform/api/quic_stream_buffer_allocator.h
new file mode 100644
index 0000000..907b0ed
--- /dev/null
+++ b/net/third_party/quic/platform/api/quic_stream_buffer_allocator.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
+#define NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
+
+#include "net/third_party/quic/platform/impl/quic_stream_buffer_allocator_impl.h"
+
+namespace quic {
+
+using QuicStreamBufferAllocator = QuicStreamBufferAllocatorImpl;
+
+}
+
+#endif  // NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_STREAM_BUFFER_ALLOCATOR_H_
diff --git a/net/third_party/quic/platform/impl/quic_default_buffer_allocator_impl.h b/net/third_party/quic/platform/impl/quic_default_buffer_allocator_impl.h
deleted file mode 100644
index aa9170af..0000000
--- a/net/third_party/quic/platform/impl/quic_default_buffer_allocator_impl.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_DEFAULT_BUFFER_ALLOCATOR_IMPL_H_
-#define NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_DEFAULT_BUFFER_ALLOCATOR_IMPL_H_
-
-#include "net/third_party/quic/core/quic_simple_buffer_allocator.h"
-
-namespace quic {
-
-using QuicStreamBufferAllocatorImpl = SimpleBufferAllocator;
-
-}  // namespace quic
-
-#endif /* NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_DEFAULT_BUFFER_ALLOCATOR_IMPL_H_ \
-        */
diff --git a/net/third_party/quic/platform/impl/quic_default_proof_providers_impl.cc b/net/third_party/quic/platform/impl/quic_default_proof_providers_impl.cc
index 8f261bac7..7000e55 100644
--- a/net/third_party/quic/platform/impl/quic_default_proof_providers_impl.cc
+++ b/net/third_party/quic/platform/impl/quic_default_proof_providers_impl.cc
@@ -6,14 +6,27 @@
 
 #include <utility>
 
+#include "base/files/file_path.h"
 #include "net/cert/cert_verifier.h"
 #include "net/cert/ct_log_verifier.h"
 #include "net/cert/ct_policy_enforcer.h"
 #include "net/cert/multi_log_ct_verifier.h"
 #include "net/http/transport_security_state.h"
+#include "net/quic/crypto/proof_source_chromium.h"
 #include "net/quic/crypto/proof_verifier_chromium.h"
+#include "net/third_party/quic/platform/api/quic_flags.h"
 #include "net/third_party/quic/platform/api/quic_ptr_util.h"
 
+DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
+                              certificate_file,
+                              "",
+                              "Path to the certificate chain.");
+
+DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
+                              key_file,
+                              "",
+                              "Path to the pkcs8 private key.");
+
 using net::CertVerifier;
 using net::CTVerifier;
 using net::MultiLogCTVerifier;
@@ -45,4 +58,12 @@
       std::move(cert_verifier));
 }
 
+std::unique_ptr<ProofSource> CreateDefaultProofSourceImpl() {
+  auto proof_source = std::make_unique<net::ProofSourceChromium>();
+  CHECK(proof_source->Initialize(
+      base::FilePath(GetQuicFlag(FLAGS_certificate_file)),
+      base::FilePath(GetQuicFlag(FLAGS_key_file)), base::FilePath()));
+  return std::move(proof_source);
+}
+
 }  // namespace quic
diff --git a/net/third_party/quic/platform/impl/quic_default_proof_providers_impl.h b/net/third_party/quic/platform/impl/quic_default_proof_providers_impl.h
index 6bb4e0c..c1c34c39 100644
--- a/net/third_party/quic/platform/impl/quic_default_proof_providers_impl.h
+++ b/net/third_party/quic/platform/impl/quic_default_proof_providers_impl.h
@@ -7,11 +7,12 @@
 
 #include <memory>
 
+#include "net/third_party/quic/core/crypto/proof_source.h"
 #include "net/third_party/quic/core/crypto/proof_verifier.h"
 
 namespace quic {
 
 std::unique_ptr<ProofVerifier> CreateDefaultProofVerifierImpl();
-
+std::unique_ptr<ProofSource> CreateDefaultProofSourceImpl();
 }
 #endif  // NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_DEFAULT_PROOF_PROVIDERS_IMPL_H_
diff --git a/net/third_party/quic/platform/impl/quic_stream_buffer_allocator_impl.h b/net/third_party/quic/platform/impl/quic_stream_buffer_allocator_impl.h
new file mode 100644
index 0000000..40ca6d8
--- /dev/null
+++ b/net/third_party/quic/platform/impl/quic_stream_buffer_allocator_impl.h
@@ -0,0 +1,13 @@
+#ifndef NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_STREAM_BUFFER_ALLOCATOR_IMPL_H_
+#define NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_STREAM_BUFFER_ALLOCATOR_IMPL_H_
+
+#include "net/third_party/quic/core/quic_simple_buffer_allocator.h"
+
+namespace quic {
+
+using QuicStreamBufferAllocatorImpl = SimpleBufferAllocator;
+
+}  // namespace quic
+
+#endif /* NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_STREAM_BUFFER_ALLOCATOR_IMPL_H_ \
+        */
diff --git a/net/third_party/quic/quartc/quartc_endpoint_test.cc b/net/third_party/quic/quartc/quartc_endpoint_test.cc
index b557712..126f2af 100644
--- a/net/third_party/quic/quartc/quartc_endpoint_test.cc
+++ b/net/third_party/quic/quartc/quartc_endpoint_test.cc
@@ -170,7 +170,8 @@
 
 // Tests that version negotiation fails when the client and server support
 // completely disjoint sets of versions.
-TEST_F(QuartcEndpointTest, DISABLED_VersionNegotiationWithDisjointVersions) {
+TEST_F(QuartcEndpointTest,
+       QUIC_TEST_DISABLED_IN_CHROME(VersionNegotiationWithDisjointVersions)) {
   // Note: for this test, we need support for two versions.  Which two shouldn't
   // matter, but they must be enabled so that the version manager doesn't filter
   // them out.
diff --git a/net/third_party/quic/test_tools/quic_test_client.cc b/net/third_party/quic/test_tools/quic_test_client.cc
index 514ef041..966a7b4b 100644
--- a/net/third_party/quic/test_tools/quic_test_client.cc
+++ b/net/third_party/quic/test_tools/quic_test_client.cc
@@ -100,7 +100,7 @@
   }
 
   std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
-    return verifier_->CreateDefaultContext();
+    return verifier_ != nullptr ? verifier_->CreateDefaultContext() : nullptr;
   }
 
   const QuicString& common_name() const { return common_name_; }
diff --git a/net/third_party/quic/tools/quic_server_bin.cc b/net/third_party/quic/tools/quic_server_bin.cc
index 7117e94b..48b9d421 100644
--- a/net/third_party/quic/tools/quic_server_bin.cc
+++ b/net/third_party/quic/tools/quic_server_bin.cc
@@ -5,21 +5,11 @@
 // A binary wrapper for QuicServer.  It listens forever on --port
 // (default 6121) until it's killed or ctrl-cd to death.
 
-#include <iostream>
+#include <vector>
 
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/task/task_scheduler/task_scheduler.h"
-#include "net/quic/crypto/proof_source_chromium.h"
-#include "net/third_party/quic/core/quic_packets.h"
+#include "net/third_party/quic/platform/api/quic_default_proof_providers.h"
 #include "net/third_party/quic/platform/api/quic_flags.h"
 #include "net/third_party/quic/platform/api/quic_socket_address.h"
-#include "net/third_party/quic/platform/api/quic_string.h"
 #include "net/third_party/quic/tools/quic_memory_cache_backend.h"
 #include "net/third_party/quic/tools/quic_server.h"
 
@@ -29,81 +19,33 @@
                               "The port the quic server will listen on.");
 
 DEFINE_QUIC_COMMAND_LINE_FLAG(
-    quic::QuicString,
-    mode,
-    "cache",
-    "Mode of operations: currently only support in-memory cache.");
-
-DEFINE_QUIC_COMMAND_LINE_FLAG(
-    quic::QuicString,
+    std::string,
     quic_response_cache_dir,
     "",
-    "Specifies the directory used during QuicHttpResponseCache construction to "
-    "seed the cache. Cache directory can be generated using `wget -p "
-    "--save-headers <url>`");
-
-DEFINE_QUIC_COMMAND_LINE_FLAG(quic::QuicString,
-                              certificate_file,
-                              "",
-                              "Path to the certificate chain.");
-
-DEFINE_QUIC_COMMAND_LINE_FLAG(quic::QuicString,
-                              key_file,
-                              "",
-                              "Path to the pkcs8 private key.");
-
-std::unique_ptr<quic::ProofSource> CreateProofSource(
-    const base::FilePath& cert_path,
-    const base::FilePath& key_path) {
-  std::unique_ptr<net::ProofSourceChromium> proof_source(
-      new net::ProofSourceChromium());
-  CHECK(proof_source->Initialize(cert_path, key_path, base::FilePath()));
-  return std::move(proof_source);
-}
+    "Specifies the directory used during QuicHttpResponseCache "
+    "construction to seed the cache. Cache directory can be "
+    "generated using `wget -p --save-headers <url>`");
 
 int main(int argc, char* argv[]) {
-  base::AtExitManager exit_manager;
-  const char* usage = "Usage: epoll_quic_server [options]\n";
-  quic::QuicParseCommandLineFlags(usage, argc, argv);
-
-  logging::LoggingSettings settings;
-  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
-  CHECK(logging::InitLogging(settings));
+  const char* usage = "Usage: quic_server [options]";
+  std::vector<quic::QuicString> non_option_args =
+      quic::QuicParseCommandLineFlags(usage, argc, argv);
+  if (!non_option_args.empty()) {
+    quic::QuicPrintCommandLineFlagHelp(usage);
+    exit(0);
+  }
 
   quic::QuicMemoryCacheBackend memory_cache_backend;
-  if (GetQuicFlag(FLAGS_mode) == "cache") {
-    if (GetQuicFlag(FLAGS_quic_response_cache_dir).empty() ||
-        !memory_cache_backend.InitializeBackend(
-            GetQuicFlag(FLAGS_quic_response_cache_dir))) {
-      LOG(ERROR) << "--quic_response_cache_dir is not valid !";
-      return 1;
-    }
-  } else {
-    LOG(ERROR) << "unknown --mode. cache is a valid mode of operation";
-    return 1;
+  if (!GetQuicFlag(FLAGS_quic_response_cache_dir).empty()) {
+    memory_cache_backend.InitializeBackend(
+        GetQuicFlag(FLAGS_quic_response_cache_dir));
   }
 
-  if (GetQuicFlag(FLAGS_certificate_file).empty()) {
-    LOG(ERROR) << "missing --certificate_file";
-    return 1;
-  }
+  quic::QuicServer server(quic::CreateDefaultProofSource(),
+                          &memory_cache_backend);
 
-  if (GetQuicFlag(FLAGS_key_file).empty()) {
-    LOG(ERROR) << "missing --key_file";
-    return 1;
-  }
-
-  quic::QuicConfig config;
-  quic::QuicServer server(
-      CreateProofSource(base::FilePath(GetQuicFlag(FLAGS_certificate_file)),
-                        base::FilePath(GetQuicFlag(FLAGS_key_file))),
-      config, quic::QuicCryptoServerConfig::ConfigOptions(),
-      quic::AllSupportedVersions(), &memory_cache_backend,
-      quic::kQuicDefaultConnectionIdLength);
-
-  int rc = server.CreateUDPSocketAndListen(quic::QuicSocketAddress(
-      quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)));
-  if (rc < 0) {
+  if (!server.CreateUDPSocketAndListen(quic::QuicSocketAddress(
+          quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
     return 1;
   }
 
diff --git a/net/tools/quic/synchronous_host_resolver.cc b/net/tools/quic/synchronous_host_resolver.cc
index 32f670e3..8bd0b9f 100644
--- a/net/tools/quic/synchronous_host_resolver.cc
+++ b/net/tools/quic/synchronous_host_resolver.cc
@@ -20,7 +20,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/net_errors.h"
-#include "net/dns/host_resolver_impl.h"
+#include "net/dns/host_resolver.h"
 #include "net/log/net_log.h"
 #include "net/log/net_log_with_source.h"
 
@@ -63,8 +63,8 @@
   net::HostResolver::Options options;
   options.max_concurrent_resolves = 6;
   options.max_retry_attempts = 3u;
-  std::unique_ptr<net::HostResolverImpl> resolver(
-      new net::HostResolverImpl(options, &net_log));
+  std::unique_ptr<net::HostResolver> resolver =
+      net::HostResolver::CreateSystemResolver(options, &net_log);
 
   HostPortPair host_port_pair(host_, 80);
   std::unique_ptr<net::HostResolver::ResolveHostRequest> request =
diff --git a/net/url_request/static_http_user_agent_settings.h b/net/url_request/static_http_user_agent_settings.h
index eda4240..0ccfe13 100644
--- a/net/url_request/static_http_user_agent_settings.h
+++ b/net/url_request/static_http_user_agent_settings.h
@@ -9,8 +9,8 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/net_export.h"
-#include "net/url_request/http_user_agent_settings.h"
 
 namespace net {
 
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc
index f4fe7c4..70a2138 100644
--- a/net/url_request/url_request_context.cc
+++ b/net/url_request/url_request_context.cc
@@ -18,12 +18,12 @@
 #include "base/trace_event/memory_dump_manager.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "base/trace_event/process_memory_dump.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/cookies/cookie_store.h"
 #include "net/dns/host_resolver.h"
 #include "net/http/http_cache.h"
 #include "net/http/http_transaction_factory.h"
 #include "net/socket/ssl_client_socket_impl.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request.h"
 
 namespace net {
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index 28d0e68..0207f8c 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -213,6 +213,8 @@
   session_context->proxy_resolution_service =
       request_context->proxy_resolution_service();
   session_context->proxy_delegate = request_context->proxy_delegate();
+  session_context->http_user_agent_settings =
+      request_context->http_user_agent_settings();
   session_context->ssl_config_service = request_context->ssl_config_service();
   session_context->http_auth_handler_factory =
       request_context->http_auth_handler_factory();
diff --git a/net/url_request/url_request_context_storage.cc b/net/url_request/url_request_context_storage.cc
index ab7bb7c..74fb1a4 100644
--- a/net/url_request/url_request_context_storage.cc
+++ b/net/url_request/url_request_context_storage.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/logging.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/network_delegate.h"
 #include "net/base/proxy_delegate.h"
 #include "net/cert/cert_verifier.h"
@@ -20,7 +21,6 @@
 #include "net/log/net_log.h"
 #include "net/proxy_resolution/proxy_resolution_service.h"
 #include "net/ssl/channel_id_service.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_job_factory.h"
 #include "net/url_request/url_request_throttler_manager.h"
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index d853324e..5d55790 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -26,6 +26,7 @@
 #include "base/trace_event/trace_event.h"
 #include "base/values.h"
 #include "net/base/host_port_pair.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
 #include "net/base/network_delegate.h"
@@ -61,7 +62,6 @@
 #include "net/ssl/channel_id_service.h"
 #include "net/ssl/ssl_cert_request_info.h"
 #include "net/ssl/ssl_config_service.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_error_job.h"
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 2c5d63e..5a016a7a 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -113,6 +113,11 @@
     context_storage_.set_channel_id_service(
         std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr)));
   }
+  if (!http_user_agent_settings() && create_default_http_user_agent_settings_) {
+    context_storage_.set_http_user_agent_settings(
+        std::make_unique<StaticHttpUserAgentSettings>("en-us,fr",
+                                                      std::string()));
+  }
   if (http_transaction_factory()) {
     // Make sure we haven't been passed an object we're not going to use.
     EXPECT_FALSE(client_socket_factory_);
@@ -132,6 +137,7 @@
     session_context.transport_security_state = transport_security_state();
     session_context.proxy_resolution_service = proxy_resolution_service();
     session_context.proxy_delegate = proxy_delegate();
+    session_context.http_user_agent_settings = http_user_agent_settings();
     session_context.ssl_config_service = ssl_config_service();
     session_context.http_auth_handler_factory = http_auth_handler_factory();
     session_context.http_server_properties = http_server_properties();
@@ -147,11 +153,6 @@
         context_storage_.http_network_session(),
         HttpCache::DefaultBackend::InMemory(0), true /* is_main_cache */));
   }
-  if (!http_user_agent_settings() && create_default_http_user_agent_settings_) {
-    context_storage_.set_http_user_agent_settings(
-        std::make_unique<StaticHttpUserAgentSettings>("en-us,fr",
-                                                      std::string()));
-  }
   if (!job_factory()) {
     context_storage_.set_job_factory(
         std::make_unique<URLRequestJobFactoryImpl>());
diff --git a/net/websockets/websocket_basic_stream_adapters_test.cc b/net/websockets/websocket_basic_stream_adapters_test.cc
index 5a2d5c2..c1144c9 100644
--- a/net/websockets/websocket_basic_stream_adapters_test.cc
+++ b/net/websockets/websocket_basic_stream_adapters_test.cc
@@ -75,6 +75,7 @@
             nullptr,
             &websocket_endpoint_lock_manager_,
             nullptr,
+            nullptr,
             HttpNetworkSession::NORMAL_SOCKET_POOL)),
         transport_params_(base::MakeRefCounted<TransportSocketParams>(
             host_port_pair_,
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc
index f6a76448c..b7b6409 100644
--- a/services/identity/public/cpp/identity_manager.cc
+++ b/services/identity/public/cpp/identity_manager.cc
@@ -304,10 +304,12 @@
   account_fetcher_service_->OnNetworkInitialized();
 }
 
-void IdentityManager::LegacyLoadCredentialsForSupervisedUser(
+#if !defined(OS_IOS) && !defined(OS_ANDROID)
+void IdentityManager::DeprecatedLoadCredentialsForSupervisedUser(
     const std::string& primary_account_id) {
   token_service_->LoadCredentials(primary_account_id);
 }
+#endif
 
 DiagnosticsProvider* IdentityManager::GetDiagnosticsProvider() {
   return diagnostics_provider_.get();
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h
index 4e905ed..14cbd003 100644
--- a/services/identity/public/cpp/identity_manager.h
+++ b/services/identity/public/cpp/identity_manager.h
@@ -31,11 +31,6 @@
 #include "base/android/jni_android.h"
 #endif
 
-// Necessary to declare this class as a friend.
-namespace arc {
-class ArcTermsOfServiceDefaultNegotiatorTest;
-}
-
 // Necessary to declare these classes as friends.
 namespace chromeos {
 class ChromeSessionManager;
@@ -48,9 +43,9 @@
 }  // namespace network
 
 // Necessary to declare these classes as friends.
-class ArcSupportHostTest;
 class IdentityManagerFactory;
 class PrefRegistrySimple;
+class SigninManagerAndroid;
 
 namespace identity {
 
@@ -385,11 +380,14 @@
   // Performs initalization that is dependent on the network being initialized.
   void OnNetworkInitialized();
 
+#if !defined(OS_IOS) && !defined(OS_ANDROID)
   // Explicitly triggers the loading of accounts in the context of supervised
   // users.
-  // TODO(https://crbug.com/860492): Eliminate the need to expose this.
-  void LegacyLoadCredentialsForSupervisedUser(
+  // TODO(https://crbug.com/860492): Remove this method when supervised users
+  // support is eliminated.
+  void DeprecatedLoadCredentialsForSupervisedUser(
       const std::string& primary_account_id);
+#endif
 
   // Returns pointer to the object used to obtain diagnostics about the internal
   // state of IdentityManager.
@@ -511,13 +509,26 @@
       network::TestURLLoaderFactory* test_url_loader_factory,
       const std::vector<identity::CookieParams>& cookie_accounts);
 
+  friend void SimulateSuccessfulFetchOfAccountInfo(
+      IdentityManager* identity_manager,
+      const std::string& account_id,
+      const std::string& email,
+      const std::string& gaia,
+      const std::string& hosted_domain,
+      const std::string& full_name,
+      const std::string& given_name,
+      const std::string& locale,
+      const std::string& picture_url);
+
   // These clients needs to call SetPrimaryAccountSynchronously().
-  friend ArcSupportHostTest;
-  friend arc::ArcTermsOfServiceDefaultNegotiatorTest;
   friend chromeos::ChromeSessionManager;
   friend chromeos::UserSessionManager;
   friend IdentityManagerFactory;
 
+  // This friend is temporary during the conversion process.
+  // TODO(crbug.com/889902): Delete this friendship when conversion is done.
+  friend SigninManagerAndroid;
+
   // Private getters used for testing only (i.e. see identity_test_utils.h).
   SigninManagerBase* GetSigninManager();
   ProfileOAuth2TokenService* GetTokenService();
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc
index 84dc5f0..e293205 100644
--- a/services/identity/public/cpp/identity_manager_unittest.cc
+++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -56,13 +56,11 @@
 const char kTestEmail2[] = "me2@gmail.com";
 const char kTestEmail3[] = "me3@gmail.com";
 
-#if defined(OS_ANDROID)
 const char kTestHostedDomain[] = "example.com";
 const char kTestFullName[] = "full_name";
 const char kTestGivenName[] = "given_name";
 const char kTestLocale[] = "locale";
 const char kTestPictureUrl[] = "http://picture.example.com/picture.jpg";
-#endif
 
 #if defined(OS_CHROMEOS)
 const char kTestEmailWithPeriod[] = "m.e@gmail.com";
@@ -112,14 +110,6 @@
   base::OnceClosure on_access_token_invalidated_callback_;
 };
 
-class AccountTrackerServiceForTest : public AccountTrackerService {
- public:
-  void SetAccountInfoFromUserInfo(const std::string& account_id,
-                                  const base::DictionaryValue* user_info) {
-    AccountTrackerService::SetAccountInfoFromUserInfo(account_id, user_info);
-  }
-};
-
 class TestSigninManagerObserver : public SigninManagerBase::Observer {
  public:
   explicit TestSigninManagerObserver(SigninManagerBase* signin_manager)
@@ -366,7 +356,7 @@
   identity_manager_diagnostics_observer() {
     return identity_manager_diagnostics_observer_.get();
   }
-  AccountTrackerServiceForTest* account_tracker() { return &account_tracker_; }
+  AccountTrackerService* account_tracker() { return &account_tracker_; }
   AccountFetcherService* account_fetcher() { return &account_fetcher_; }
   SigninManagerBase* signin_manager() { return signin_manager_.get(); }
   CustomFakeProfileOAuth2TokenService* token_service() {
@@ -485,7 +475,7 @@
  private:
   base::MessageLoop message_loop_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
-  AccountTrackerServiceForTest account_tracker_;
+  AccountTrackerService account_tracker_;
   AccountFetcherService account_fetcher_;
   TestSigninClient signin_client_;
   CustomFakeProfileOAuth2TokenService token_service_;
@@ -1398,18 +1388,20 @@
   EXPECT_TRUE(mutator);
 }
 
+#if !defined(OS_IOS) && !defined(OS_ANDROID)
 // Tests that requesting a load of accounts results in the notification
 // firing that tokens were loaded.
-TEST_F(IdentityManagerTest, LegacyLoadCredentials) {
+TEST_F(IdentityManagerTest, DeprecatedLoadCredentialsForSupervisedUser) {
   base::RunLoop run_loop;
   identity_manager_observer()->SetOnRefreshTokensLoadedCallback(
       run_loop.QuitClosure());
 
   // Load the accounts and ensure that we see the resulting notification that
   // they were loaded.
-  identity_manager()->LegacyLoadCredentialsForSupervisedUser("");
+  identity_manager()->DeprecatedLoadCredentialsForSupervisedUser("");
   run_loop.Run();
 }
+#endif
 
 TEST_F(IdentityManagerTest, LegacySeedAccountInfo) {
   ASSERT_FALSE(
@@ -1521,12 +1513,10 @@
 
   // Simulate the flow wherein the user's email address was updated
   // to the originally-created non-normalized version.
-  base::DictionaryValue user_info;
-  user_info.SetString("id", kTestGaiaId);
-  user_info.SetString("email", kTestEmailWithPeriod);
-  account_tracker()->SetAccountInfoFromUserInfo(primary_account_info.account_id,
-                                                &user_info);
-
+  SimulateSuccessfulFetchOfAccountInfo(
+      identity_manager(), primary_account_info.account_id, kTestEmailWithPeriod,
+      kTestGaiaId, kTestHostedDomain, kTestFullName, kTestGivenName,
+      kTestLocale, kTestPictureUrl);
   // Verify that IdentityManager reflects the update.
   primary_account_info = identity_manager()->GetPrimaryAccountInfo();
   EXPECT_EQ(kTestGaiaId, primary_account_info.gaia);
@@ -2385,11 +2375,10 @@
   const AccountInfo account_info =
       MakeAccountAvailable(identity_manager(), kTestEmail3);
 
-  base::DictionaryValue user_info;
-  user_info.SetString("id", account_info.account_id);
-  user_info.SetString("email", account_info.email);
-  account_tracker()->SetAccountInfoFromUserInfo(account_info.account_id,
-                                                &user_info);
+  SimulateSuccessfulFetchOfAccountInfo(
+      identity_manager(), account_info.account_id, account_info.email,
+      account_info.account_id, kTestHostedDomain, kTestFullName, kTestGivenName,
+      kTestLocale, kTestPictureUrl);
 
   EXPECT_EQ(account_info.account_id, identity_manager_observer()
                                          ->AccountFromAccountUpdatedCallback()
@@ -2498,16 +2487,10 @@
   identity_manager()->ForceRefreshOfExtendedAccountInfo(
       account_info.account_id);
 
-  base::DictionaryValue user_info;
-  user_info.SetString("id", account_info.account_id);
-  user_info.SetString("email", account_info.email);
-  user_info.SetString("hd", kTestHostedDomain);
-  user_info.SetString("name", kTestFullName);
-  user_info.SetString("given_name", kTestGivenName);
-  user_info.SetString("locale", kTestLocale);
-  user_info.SetString("picture", kTestPictureUrl);
-  account_tracker()->SetAccountInfoFromUserInfo(account_info.account_id,
-                                                &user_info);
+  SimulateSuccessfulFetchOfAccountInfo(
+      identity_manager(), account_info.account_id, account_info.email,
+      account_info.account_id, kTestHostedDomain, kTestFullName, kTestGivenName,
+      kTestLocale, kTestPictureUrl);
 
   const AccountInfo& refreshed_account_info =
       identity_manager_observer()->AccountFromAccountUpdatedCallback();
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc
index 2d7dcc4..8b91289b 100644
--- a/services/identity/public/cpp/identity_test_environment.cc
+++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -584,15 +584,9 @@
     const std::string& given_name,
     const std::string& locale,
     const std::string& picture_url) {
-  base::DictionaryValue user_info;
-  user_info.SetString("id", gaia);
-  user_info.SetString("email", email);
-  user_info.SetString("hd", hosted_domain);
-  user_info.SetString("name", full_name);
-  user_info.SetString("given_name", given_name);
-  user_info.SetString("locale", locale);
-  user_info.SetString("picture", picture_url);
-  account_tracker_service_->SetAccountInfoFromUserInfo(account_id, &user_info);
+  identity::SimulateSuccessfulFetchOfAccountInfo(
+      identity_manager(), account_id, email, gaia, hosted_domain, full_name,
+      given_name, locale, picture_url);
 }
 
 void IdentityTestEnvironment::SimulateMergeSessionFailure(
diff --git a/services/identity/public/cpp/identity_test_utils.cc b/services/identity/public/cpp/identity_test_utils.cc
index 74e493f2..afb7d3c 100644
--- a/services/identity/public/cpp/identity_test_utils.cc
+++ b/services/identity/public/cpp/identity_test_utils.cc
@@ -326,4 +326,27 @@
   identity_manager->GetGaiaCookieManagerService()->CancelAll();
 }
 
+void SimulateSuccessfulFetchOfAccountInfo(IdentityManager* identity_manager,
+                                          const std::string& account_id,
+                                          const std::string& email,
+                                          const std::string& gaia,
+                                          const std::string& hosted_domain,
+                                          const std::string& full_name,
+                                          const std::string& given_name,
+                                          const std::string& locale,
+                                          const std::string& picture_url) {
+  base::DictionaryValue user_info;
+  user_info.SetString("id", gaia);
+  user_info.SetString("email", email);
+  user_info.SetString("hd", hosted_domain);
+  user_info.SetString("name", full_name);
+  user_info.SetString("given_name", given_name);
+  user_info.SetString("locale", locale);
+  user_info.SetString("picture", picture_url);
+
+  AccountTrackerService* account_tracker_service =
+      identity_manager->GetAccountTrackerService();
+  account_tracker_service->SetAccountInfoFromUserInfo(account_id, &user_info);
+}
+
 }  // namespace identity
diff --git a/services/identity/public/cpp/identity_test_utils.h b/services/identity/public/cpp/identity_test_utils.h
index 7997a94..ef47d569 100644
--- a/services/identity/public/cpp/identity_test_utils.h
+++ b/services/identity/public/cpp/identity_test_utils.h
@@ -159,6 +159,17 @@
 // Cancels all ongoing operations related to the accounts in the Gaia cookie.
 void CancelAllOngoingGaiaCookieOperations(IdentityManager* identity_manager);
 
+// Simulate account fetching using AccountTrackerService without sending
+// network requests.
+void SimulateSuccessfulFetchOfAccountInfo(IdentityManager* identity_manager,
+                                          const std::string& account_id,
+                                          const std::string& email,
+                                          const std::string& gaia,
+                                          const std::string& hosted_domain,
+                                          const std::string& full_name,
+                                          const std::string& given_name,
+                                          const std::string& locale,
+                                          const std::string& picture_url);
 }  // namespace identity
 
 #endif  // SERVICES_IDENTITY_PUBLIC_CPP_IDENTITY_TEST_UTILS_H_
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index c02b285..8d0a390 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -104,8 +104,7 @@
     return;
   }
 
-  if (base::FeatureList::IsEnabled(features::kOutOfBlinkCors) &&
-      !disable_web_security_) {
+  if (features::ShouldEnableOutOfBlinkCors() && !disable_web_security_) {
     auto loader = std::make_unique<CorsURLLoader>(
         std::move(request), routing_id, request_id, options,
         base::BindOnce(&CorsURLLoaderFactory::DestroyURLLoader,
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc
index 92903bb..e1b60cf 100644
--- a/services/network/cors/cors_url_loader_unittest.cc
+++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -143,7 +143,8 @@
  protected:
   // testing::Test implementation.
   void SetUp() override {
-    feature_list_.InitAndEnableFeature(features::kOutOfBlinkCors);
+    feature_list_.InitWithFeatures(
+        {features::kOutOfBlinkCors, features::kNetworkService}, {});
 
     network_service_ = NetworkService::CreateForTesting();
 
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index f00b2da..c9cd180 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -116,12 +116,12 @@
 #endif  // !defined(OS_IOS)
 
 #if BUILDFLAG(ENABLE_REPORTING)
+#include "net/base/http_user_agent_settings.h"
 #include "net/network_error_logging/network_error_logging_service.h"
 #include "net/reporting/reporting_browsing_data_remover.h"
 #include "net/reporting/reporting_policy.h"
 #include "net/reporting/reporting_report.h"
 #include "net/reporting/reporting_service.h"
-#include "net/url_request/http_user_agent_settings.h"
 #endif  // BUILDFLAG(ENABLE_REPORTING)
 
 #if BUILDFLAG(ENABLE_MDNS)
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
index 79425af07..d6f22f6 100644
--- a/services/network/network_context_unittest.cc
+++ b/services/network/network_context_unittest.cc
@@ -47,6 +47,7 @@
 #include "net/base/features.h"
 #include "net/base/hash_value.h"
 #include "net/base/host_port_pair.h"
+#include "net/base/http_user_agent_settings.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/base/network_change_notifier.h"
@@ -86,7 +87,6 @@
 #include "net/test/gtest_util.h"
 #include "net/test/test_data_directory.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "net/url_request/http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_builder.h"
 #include "net/url_request/url_request_job_factory.h"
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 72e96fb..5276ed9 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -59,5 +59,13 @@
 const base::Feature kEnforceRequestInitiatorLockForCorb{
     "EnforceRequestInitiatorLockForCorb", base::FEATURE_ENABLED_BY_DEFAULT};
 
+bool ShouldEnableOutOfBlinkCors() {
+  // OOR-CORS requires NetworkService.
+  if (!base::FeatureList::IsEnabled(features::kNetworkService))
+    return false;
+
+  return base::FeatureList::IsEnabled(features::kOutOfBlinkCors);
+}
+
 }  // namespace features
 }  // namespace network
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 72618b3..cbf53f1f 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -28,6 +28,8 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kEnforceRequestInitiatorLockForCorb;
 
+COMPONENT_EXPORT(NETWORK_CPP) bool ShouldEnableOutOfBlinkCors();
+
 }  // namespace features
 }  // namespace network
 
diff --git a/services/service_manager/service_process_launcher.cc b/services/service_manager/service_process_launcher.cc
index 916a11f..1a095f9 100644
--- a/services/service_manager/service_process_launcher.cc
+++ b/services/service_manager/service_process_launcher.cc
@@ -25,6 +25,7 @@
 #include "base/threading/thread.h"
 #include "build/build_config.h"
 #include "mojo/public/cpp/bindings/interface_ptr_info.h"
+#include "mojo/public/cpp/platform/features.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/system/core.h"
 #include "mojo/public/cpp/system/invitation.h"
@@ -194,10 +195,25 @@
     NOTIMPLEMENTED();
   options.handles_to_transfer = std::move(handle_passing_info);
 #elif defined(OS_POSIX)
-  handle_passing_info.push_back(std::make_pair(STDIN_FILENO, STDIN_FILENO));
-  handle_passing_info.push_back(std::make_pair(STDOUT_FILENO, STDOUT_FILENO));
-  handle_passing_info.push_back(std::make_pair(STDERR_FILENO, STDERR_FILENO));
+  const base::FileHandleMappingVector fd_mapping{
+      {STDIN_FILENO, STDIN_FILENO},
+      {STDOUT_FILENO, STDOUT_FILENO},
+      {STDERR_FILENO, STDERR_FILENO},
+  };
+#if defined(OS_MACOSX)
+  if (base::FeatureList::IsEnabled(mojo::features::kMojoChannelMac)) {
+    options.fds_to_remap = fd_mapping;
+    options.mach_ports_for_rendezvous = handle_passing_info;
+  } else {
+    options.fds_to_remap = handle_passing_info;
+    options.fds_to_remap.insert(options.fds_to_remap.end(), fd_mapping.begin(),
+                                fd_mapping.end());
+  }
+#else
+  handle_passing_info.insert(handle_passing_info.end(), fd_mapping.begin(),
+                             fd_mapping.end());
   options.fds_to_remap = handle_passing_info;
+#endif  // defined(OS_MACOSX)
 #endif
   DVLOG(2) << "Launching child with command line: "
            << child_command_line->GetCommandLineString();
diff --git a/services/service_manager/tests/util.cc b/services/service_manager/tests/util.cc
index 072efd5..de1443b 100644
--- a/services/service_manager/tests/util.cc
+++ b/services/service_manager/tests/util.cc
@@ -17,6 +17,7 @@
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "build/build_config.h"
+#include "mojo/public/cpp/platform/features.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/system/invitation.h"
 #include "services/service_manager/public/cpp/connector.h"
@@ -85,8 +86,13 @@
 #if defined(OS_WIN)
   options.handles_to_inherit = handle_passing_info;
 #elif defined(OS_FUCHSIA)
-
   options.handles_to_transfer = handle_passing_info;
+#elif defined(OS_MACOSX)
+  if (base::FeatureList::IsEnabled(mojo::features::kMojoChannelMac)) {
+    options.mach_ports_for_rendezvous = handle_passing_info;
+  } else {
+    options.fds_to_remap = handle_passing_info;
+  }
 #elif defined(OS_POSIX)
   options.fds_to_remap = handle_passing_info;
 #endif
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 7b7bcf7d..d392936b2 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
@@ -10,8 +10,6 @@
 
 # https://crbug.com/893566
 -org.chromium.android_webview.test.AwContentsClientShouldInterceptRequestTest.testBaseUrlOfLoadDataSentInRefererHeader
--org.chromium.android_webview.test.AwContentsClientShouldInterceptRequestTest.testCalledForUnsupportedSchemes
--org.chromium.android_webview.test.AwContentsClientShouldInterceptRequestTest.testContentIdIframe
 -org.chromium.android_webview.test.AwContentsClientShouldInterceptRequestTest.testLoadDataShouldTriggerShouldInterceptRequest
 -org.chromium.android_webview.test.AwContentsClientShouldInterceptRequestTest.testLoadDataUrlShouldTriggerShouldInterceptRequest
 -org.chromium.android_webview.test.AwContentsClientShouldInterceptRequestTest.testLoadDataWithBaseUrlTriggersShouldInterceptRequest
@@ -43,8 +41,8 @@
 
 # Flaky tests on android_mojo and android_mojo_rel bots
 # https://crbug.com/936757, https://crbug.com/939355
--org.chromium.android_webview.test.AwContentsClientFullScreenTest#testOnShowCustomViewAndPlayWithHtmlControl_videoInsideDiv
--org.chromium.android_webview.test.AwContentsClientFullScreenTest#testPowerSaveBlockerIsEnabledDuringEmbeddedPlayback
--org.chromium.android_webview.test.AwContentsClientFullScreenTest#testPowerSaveBlockerIsTransferredToEmbedded
--org.chromium.android_webview.test.AwContentsClientFullScreenTest#testPowerSaveBlockerIsTransferredToFullscreen
--org.chromium.android_webview.test.AwContentsClientFullScreenTest#testPowerSaveBlockerIsEnabledDuringFullscreenPlayback_videoInsideDiv
+-org.chromium.android_webview.test.AwContentsClientFullScreenTest.testOnShowCustomViewAndPlayWithHtmlControl_videoInsideDiv
+-org.chromium.android_webview.test.AwContentsClientFullScreenTest.testPowerSaveBlockerIsEnabledDuringEmbeddedPlayback
+-org.chromium.android_webview.test.AwContentsClientFullScreenTest.testPowerSaveBlockerIsTransferredToEmbedded
+-org.chromium.android_webview.test.AwContentsClientFullScreenTest.testPowerSaveBlockerIsTransferredToFullscreen
+-org.chromium.android_webview.test.AwContentsClientFullScreenTest.testPowerSaveBlockerIsEnabledDuringFullscreenPlayback_videoInsideDiv
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index dc64967..5078659 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -3346,9 +3346,12 @@
     "OutOfBlinkCors": [
         {
             "platforms": [
-                "windows",
+                "android",
+                "chromeos",
+                "ios",
+                "linux",
                 "mac",
-                "linux"
+                "windows"
             ],
             "experiments": [
                 {
diff --git a/third_party/blink/common/cache_storage/cache_storage_utils.cc b/third_party/blink/common/cache_storage/cache_storage_utils.cc
index 2955cee..16af01e 100644
--- a/third_party/blink/common/cache_storage/cache_storage_utils.cc
+++ b/third_party/blink/common/cache_storage/cache_storage_utils.cc
@@ -4,6 +4,9 @@
 
 #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 
+#include "base/atomic_sequence_num.h"
+#include "base/process/process_handle.h"
+
 namespace blink {
 namespace cache_storage {
 
@@ -12,5 +15,18 @@
 // static
 const char kDuplicateOperationBaseMessage[] = "duplicate requests";
 
+int64_t CreateTraceId() {
+  // The top 32-bits are the unique process identifier.
+  int64_t id = base::GetUniqueIdForProcess();
+  id <<= 32;
+
+  // The bottom 32-bits are an atomic number sequence specific to this
+  // process.
+  static base::AtomicSequenceNumber seq;
+  id += (seq.GetNext() & 0x0ffff);
+
+  return id;
+}
+
 }  // namespace cache_storage
 }  // namespace blink
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index bd7fb4a..ea0654d4 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -7,6 +7,7 @@
 import("//third_party/blink/public/public_features.gni")
 import("//third_party/blink/renderer/config.gni")
 import("//third_party/blink/renderer/core/core.gni")
+import("//third_party/webrtc/webrtc.gni")
 import("//tools/grit/grit_rule.gni")
 import("//tools/grit/repack.gni")
 
@@ -140,6 +141,7 @@
     "platform/modules/media_capabilities/web_media_decoding_configuration.h",
     "platform/modules/media_capabilities/web_video_configuration.h",
     "platform/modules/mediastream/media_stream_audio_deliverer.h",
+    "platform/modules/mediastream/media_stream_audio_processor_options.h",
     "platform/modules/mediastream/media_stream_audio_source.h",
     "platform/modules/mediastream/media_stream_audio_track.h",
     "platform/modules/mediastream/media_stream_types.h",
@@ -386,6 +388,12 @@
     "web/mac/web_substring_util.h",
     "web/modules/autofill/web_form_element_observer.h",
     "web/modules/autofill/web_form_element_observer_callback.h",
+    "web/modules/mediastream/media_stream_constraints_util.h",
+    "web/modules/mediastream/media_stream_constraints_util_sets.h",
+    "web/modules/mediastream/media_stream_constraints_util_video_device.h",
+    "web/modules/mediastream/media_stream_video_source.h",
+    "web/modules/mediastream/media_stream_video_track.h",
+    "web/modules/mediastream/video_track_adapter.h",
     "web/modules/service_worker/web_service_worker_context_client.h",
     "web/modules/service_worker/web_service_worker_context_proxy.h",
     "web/web_active_fling_parameters.h",
@@ -534,8 +542,6 @@
     "//services/ws/public/mojom/ime",
     "//skia",
     "//third_party/blink/public/common",
-    "//third_party/webrtc/api:libjingle_peerconnection_api",
-    "//third_party/webrtc/rtc_base:rtc_base",
     "//ui/accessibility:ax_enums_mojo",
     "//url",
   ]
@@ -553,6 +559,12 @@
     "//services/device/public/mojom:mojom_shared_cpp_sources",
     "//services/network/public/cpp:cpp",
     "//services/network/public/mojom",
+    "//third_party/webrtc/api:libjingle_peerconnection_api",
+    "//third_party/webrtc/media:rtc_media_base",
+    "//third_party/webrtc/modules/audio_processing:api",
+    "//third_party/webrtc/rtc_base:rtc_base",
+    "//third_party/webrtc/rtc_base:rtc_task_queue",
+    "//third_party/webrtc_overrides:init_webrtc",
     "//v8:v8_headers",
   ]
 }
diff --git a/third_party/blink/public/common/cache_storage/cache_storage_utils.h b/third_party/blink/public/common/cache_storage/cache_storage_utils.h
index 561b386..abee012e 100644
--- a/third_party/blink/public/common/cache_storage/cache_storage_utils.h
+++ b/third_party/blink/public/common/cache_storage/cache_storage_utils.h
@@ -5,6 +5,9 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_CACHE_STORAGE_CACHE_STORAGE_UTILS_H_
 #define THIRD_PARTY_BLINK_PUBLIC_COMMON_CACHE_STORAGE_CACHE_STORAGE_UTILS_H_
 
+#include <cstdint>
+#include <memory>
+
 #include "third_party/blink/public/common/common_export.h"
 
 namespace blink {
@@ -18,6 +21,12 @@
 // duplicate rejection finally ships.
 BLINK_COMMON_EXPORT extern const char kDuplicateOperationBaseMessage[];
 
+// Create a trace ID for a cache_storage operation.  The ID value is
+// guaranteed to be globally unique across all processes and threads.
+// It can be used to trace across process boundaries.  When passing to
+// a TRACE_EVENT* macro it should be wrapped in TRACE_ID_GLOBAL().
+BLINK_COMMON_EXPORT int64_t CreateTraceId();
+
 }  // namespace cache_storage
 }  // namespace blink
 
diff --git a/third_party/blink/public/common/messaging/transferable_message.h b/third_party/blink/public/common/messaging/transferable_message.h
index 5b68cc6..9d134b4 100644
--- a/third_party/blink/public/common/messaging/transferable_message.h
+++ b/third_party/blink/public/common/messaging/transferable_message.h
@@ -37,12 +37,16 @@
   std::vector<SkBitmap> image_bitmap_contents_array;
 
   // Whether the recipient should have a user gesture when it processes this
-  // message.
+  // message. This is a legacy bit used only without User Activation v2.
   bool has_user_gesture = false;
 
   // The state of user activation.
   mojom::UserActivationSnapshotPtr user_activation;
 
+  // Whether the state of user activation should be transferred to the
+  // destination frame.
+  bool transfer_user_activation = false;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(TransferableMessage);
 };
diff --git a/third_party/blink/public/common/messaging/transferable_message_struct_traits.h b/third_party/blink/public/common/messaging/transferable_message_struct_traits.h
index a6ad220d..0fd5213 100644
--- a/third_party/blink/public/common/messaging/transferable_message_struct_traits.h
+++ b/third_party/blink/public/common/messaging/transferable_message_struct_traits.h
@@ -50,6 +50,10 @@
     return input.user_activation;
   }
 
+  static bool transfer_user_activation(blink::TransferableMessage& input) {
+    return input.transfer_user_activation;
+  }
+
   static bool Read(blink::mojom::TransferableMessage::DataView data,
                    blink::TransferableMessage* out);
 };
diff --git a/third_party/blink/public/mojom/cache_storage/cache_storage.mojom b/third_party/blink/public/mojom/cache_storage/cache_storage.mojom
index a9775d9..f58c843c 100644
--- a/third_party/blink/public/mojom/cache_storage/cache_storage.mojom
+++ b/third_party/blink/public/mojom/cache_storage/cache_storage.mojom
@@ -102,47 +102,47 @@
 interface CacheStorageCache {
   // Returns the first cached response that matches |request| according to
   // options specified on |query_options|.
-  Match(blink.mojom.FetchAPIRequest request, CacheQueryOptions query_options)
+  Match(blink.mojom.FetchAPIRequest request, CacheQueryOptions query_options, int64 trace_id)
       => (MatchResult result);
 
   // Returns all cached responses that match |request| according to options
   // specified on |query_options|.
-  MatchAll(blink.mojom.FetchAPIRequest? request, CacheQueryOptions query_options)
+  MatchAll(blink.mojom.FetchAPIRequest? request, CacheQueryOptions query_options, int64 trace_id)
       => (MatchAllResult result);
 
   // Returns all keys (which are requests) of matching |request| and
   // |query_options|.
-  Keys(blink.mojom.FetchAPIRequest? request, CacheQueryOptions query_options)
+  Keys(blink.mojom.FetchAPIRequest? request, CacheQueryOptions query_options, int64 trace_id)
       => (CacheKeysResult result);
 
   // Perform a batch of operations, used for PUT and DELETE operations.
-  Batch(array<BatchOperation> batch_operations, bool fail_on_duplicates)
+  Batch(array<BatchOperation> batch_operations, bool fail_on_duplicates, int64 trace_id)
       => (CacheStorageVerboseError result);
 
   // Sets |side_data| if there is an entry of which key is |url| and the entry
   // has the same |response_time|.
   SetSideData(url.mojom.Url url, mojo_base.mojom.Time response_time,
-              array<uint8> side_data) => (CacheStorageError result);
+              array<uint8> side_data, int64 trace_id) => (CacheStorageError result);
 };
 
 // Handles global CacheStorage methods, directly relates to methods available on
 // spec: https://w3c.github.io/ServiceWorker/#cachestorage-interface
 interface CacheStorage {
   // Returns kSuccess if |cache_name| exists or kErrorNotFound if not.
-  Has(mojo_base.mojom.String16 cache_name) => (CacheStorageError result);
+  Has(mojo_base.mojom.String16 cache_name, int64 trace_id) => (CacheStorageError result);
 
   // Removes a given cache.
-  Delete(mojo_base.mojom.String16 cache_name) => (CacheStorageError result);
+  Delete(mojo_base.mojom.String16 cache_name, int64 trace_id) => (CacheStorageError result);
 
   // Returns all cache names managed on this origin.
-  Keys() => (array<mojo_base.mojom.String16> keys);
+  Keys(int64 trace_id) => (array<mojo_base.mojom.String16> keys);
 
   // Returns the first cached response that matches |request| and
   // |match_options|. It can search on all caches if |cache_name| isn't provided
   // on |match_options|.
-  Match(blink.mojom.FetchAPIRequest request, MultiCacheQueryOptions match_options)
+  Match(blink.mojom.FetchAPIRequest request, MultiCacheQueryOptions match_options, int64 trace_id)
       => (MatchResult result);
 
   // Opens and returns a mojo interface to a cache, it creates if doesn't exist.
-  Open(mojo_base.mojom.String16 cache_name) => (OpenResult result);
+  Open(mojo_base.mojom.String16 cache_name, int64 trace_id) => (OpenResult result);
 };
diff --git a/content/renderer/media/stream/media_stream_audio_processor_options.h b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h
similarity index 72%
rename from content/renderer/media/stream/media_stream_audio_processor_options.h
rename to third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h
index d7888e87..07a69de 100644
--- a/content/renderer/media/stream/media_stream_audio_processor_options.h
+++ b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
+#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
 
 #include <string>
 #include <vector>
@@ -13,10 +13,10 @@
 #include "base/optional.h"
 #include "base/threading/thread_checker.h"
 #include "build/build_config.h"
-#include "content/common/content_export.h"
 #include "media/base/audio_point.h"
 #include "media/base/audio_processing.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
 #include "third_party/webrtc/media/base/media_channel.h"
@@ -29,7 +29,7 @@
 
 }
 
-namespace content {
+namespace blink {
 
 using webrtc::AudioProcessing;
 
@@ -41,7 +41,7 @@
 #endif
 
 // Simple struct with audio-processing properties.
-struct CONTENT_EXPORT AudioProcessingProperties {
+struct BLINK_PLATFORM_EXPORT AudioProcessingProperties {
   enum class EchoCancellationType {
     // Echo cancellation disabled.
     kEchoCancellationDisabled,
@@ -91,44 +91,51 @@
 };
 
 // Enables the echo cancellation in |audio_processing|.
-void EnableEchoCancellation(AudioProcessing* audio_processing);
+BLINK_PLATFORM_EXPORT void EnableEchoCancellation(
+    AudioProcessing* audio_processing);
 
 // Enables the noise suppression in |audio_processing|.
-void EnableNoiseSuppression(AudioProcessing* audio_processing,
-                            webrtc::NoiseSuppression::Level ns_level);
+BLINK_PLATFORM_EXPORT void EnableNoiseSuppression(
+    AudioProcessing* audio_processing,
+    webrtc::NoiseSuppression::Level ns_level);
 
 // Enables the typing detection in |audio_processing|.
-void EnableTypingDetection(AudioProcessing* audio_processing,
-                           webrtc::TypingDetection* typing_detector);
+BLINK_PLATFORM_EXPORT void EnableTypingDetection(
+    AudioProcessing* audio_processing,
+    webrtc::TypingDetection* typing_detector);
 
 // Starts the echo cancellation dump in
 // |audio_processing|. |worker_queue| must be kept alive until either
 // |audio_processing| is destroyed, or
 // StopEchoCancellationDump(audio_processing) is called.
-void StartEchoCancellationDump(AudioProcessing* audio_processing,
-                               base::File aec_dump_file,
-                               rtc::TaskQueue* worker_queue);
+BLINK_PLATFORM_EXPORT void StartEchoCancellationDump(
+    AudioProcessing* audio_processing,
+    base::File aec_dump_file,
+    rtc::TaskQueue* worker_queue);
 
 // Stops the echo cancellation dump in |audio_processing|.
 // This method has no impact if echo cancellation dump has not been started on
 // |audio_processing|.
-void StopEchoCancellationDump(AudioProcessing* audio_processing);
+BLINK_PLATFORM_EXPORT void StopEchoCancellationDump(
+    AudioProcessing* audio_processing);
 
 // Loads fixed gains for pre-amplifier and gain control from config JSON string.
-CONTENT_EXPORT void GetExtraGainConfig(
+BLINK_PLATFORM_EXPORT void GetExtraGainConfig(
     const base::Optional<std::string>& audio_processing_platform_config_json,
     base::Optional<double>* pre_amplifier_fixed_gain_factor,
     base::Optional<double>* gain_control_compression_gain_db);
 
 // Enables automatic gain control. If optional |fixed_gain| is set, will set the
 // gain control mode to use the fixed gain.
-void EnableAutomaticGainControl(AudioProcessing* audio_processing,
-                                base::Optional<double> compression_gain_db);
+BLINK_PLATFORM_EXPORT void EnableAutomaticGainControl(
+    AudioProcessing* audio_processing,
+    base::Optional<double> compression_gain_db);
 
 // Enables pre-amplifier with given gain factor if the optional |factor| is set.
-void ConfigPreAmplifier(webrtc::AudioProcessing::Config* apm_config,
-                        base::Optional<double> fixed_gain_factor);
+BLINK_PLATFORM_EXPORT void ConfigPreAmplifier(
+    webrtc::AudioProcessing::Config* apm_config,
+    base::Optional<double> fixed_gain_factor);
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_MEDIA_STREAM_AUDIO_PROCESSOR_OPTIONS_H_
diff --git a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h
index 4cfa28e..570e6ca 100644
--- a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h
+++ b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h
@@ -41,14 +41,14 @@
 // needed, and/or calls to DeliverDataToTracks() must be made at very specific
 // times.
 //
-// An instance of this class is owned by blink::WebMediaStreamSource.
+// An instance of this class is owned by WebMediaStreamSource.
 //
 // Usage example:
 //
 //   class MyAudioSource : public MediaStreamAudioSource { ... };
 //
-//   blink::WebMediaStreamSource blink_source = ...;
-//   blink::WebMediaStreamTrack blink_track = ...;
+//   WebMediaStreamSource blink_source = ...;
+//   WebMediaStreamTrack blink_track = ...;
 //   blink_source.setExtraData(new MyAudioSource());  // Takes ownership.
 //   if (MediaStreamAudioSource::From(blink_source)
 //           ->ConnectToTrack(blink_track)) {
@@ -60,7 +60,7 @@
 //   // MediaStreamAudioTrack instance created.
 //   CHECK(MediaStreamAudioTrack::From(blink_track));
 class BLINK_PLATFORM_EXPORT MediaStreamAudioSource
-    : public blink::WebPlatformMediaStreamSource {
+    : public WebPlatformMediaStreamSource {
  public:
   explicit MediaStreamAudioSource(bool is_local_source);
   MediaStreamAudioSource(bool is_local_source, bool disable_local_echo);
@@ -68,8 +68,7 @@
 
   // Returns the MediaStreamAudioSource instance owned by the given blink
   // |source| or null.
-  static MediaStreamAudioSource* From(
-      const blink::WebMediaStreamSource& source);
+  static MediaStreamAudioSource* From(const WebMediaStreamSource& source);
 
   // Provides a weak reference to this MediaStreamAudioSource. The weak pointer
   // may only be dereferenced on the main thread.
@@ -86,7 +85,7 @@
   // implementation of the content::MediaStreamAudioTrack interface, which
   // becomes associated with and owned by |track|. Returns true if the source
   // was successfully started.
-  bool ConnectToTrack(const blink::WebMediaStreamTrack& track);
+  bool ConnectToTrack(const WebMediaStreamTrack& track);
 
   // Returns the current format of the audio passing through this source to the
   // sinks. This can return invalid parameters if the source has not yet been
@@ -127,7 +126,7 @@
   // Stops the source and start the |new_device|.
   // A default no-op implementation is provided in this base class. Subclasses
   // should override this method.
-  virtual void ChangeSourceImpl(const blink::MediaStreamDevice& new_device);
+  virtual void ChangeSourceImpl(const MediaStreamDevice& new_device);
 
   // Called by subclasses to update the format of the audio passing through this
   // source to the sinks. This may be called at any time, before or after
@@ -154,7 +153,7 @@
  private:
   // MediaStreamSource override.
   void DoStopSource() final;
-  void DoChangeSource(const blink::MediaStreamDevice& new_device) final;
+  void DoChangeSource(const MediaStreamDevice& new_device) final;
 
   // Removes |track| from the list of instances that get a copy of the source
   // audio data. The "stop callback" that was provided to the track calls
diff --git a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h
index 323b29c..a9f39cc 100644
--- a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h
+++ b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h
@@ -24,10 +24,10 @@
 
 // Provides the part of the audio pipeline delivering audio from a
 // MediaStreamAudioSource to one or more WebMediaStreamAudioSinks. An instance
-// of this class is owned by blink::WebMediaStreamTrack, and clients should use
+// of this class is owned by WebMediaStreamTrack, and clients should use
 // From() to gain access to a MediaStreamAudioTrack.
 class BLINK_PLATFORM_EXPORT MediaStreamAudioTrack
-    : public blink::WebPlatformMediaStreamTrack {
+    : public WebPlatformMediaStreamTrack {
  public:
   explicit MediaStreamAudioTrack(bool is_local_track);
 
@@ -35,7 +35,7 @@
 
   // Returns the MediaStreamAudioTrack instance owned by the given blink |track|
   // or null.
-  static MediaStreamAudioTrack* From(const blink::WebMediaStreamTrack& track);
+  static MediaStreamAudioTrack* From(const WebMediaStreamTrack& track);
 
   // Provides a weak reference to this MediaStreamAudioTrack which is
   // invalidated when Stop() is called. The weak pointer may only be
@@ -68,7 +68,7 @@
   // MediaStreamTrack override.
   void SetEnabled(bool enabled) override;
   void SetContentHint(
-      blink::WebMediaStreamTrack::ContentHintType content_hint) override;
+      WebMediaStreamTrack::ContentHintType content_hint) override;
 
   // Returns a unique class identifier. Some subclasses override and use this
   // method to provide safe down-casting to their type.
diff --git a/third_party/blink/public/platform/modules/mediastream/web_media_stream_renderer_factory.h b/third_party/blink/public/platform/modules/mediastream/web_media_stream_renderer_factory.h
index 20f6de2a..fa501f7 100644
--- a/third_party/blink/public/platform/modules/mediastream/web_media_stream_renderer_factory.h
+++ b/third_party/blink/public/platform/modules/mediastream/web_media_stream_renderer_factory.h
@@ -31,14 +31,14 @@
   // Returns a WebMediaStreamVideoRenderer that uses the given task runners.
   // |io_task_runner| is used for passing video frames.
   virtual scoped_refptr<WebMediaStreamVideoRenderer> GetVideoRenderer(
-      const blink::WebMediaStream& web_stream,
+      const WebMediaStream& web_stream,
       const base::Closure& error_cb,
       const WebMediaStreamVideoRenderer::RepaintCB& repaint_cb,
       scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) = 0;
 
   virtual scoped_refptr<WebMediaStreamAudioRenderer> GetAudioRenderer(
-      const blink::WebMediaStream& web_stream,
+      const WebMediaStream& web_stream,
       int render_frame_id,
       const std::string& device_id) = 0;
 };
diff --git a/third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h b/third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h
index d7b6475..3228996 100644
--- a/third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h
+++ b/third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h
@@ -13,15 +13,14 @@
 
 // MediaStreamSink is the base interface for MediaStreamAudioSink and
 // MediaStreamVideoSink. It allows an implementation to receive notifications
-// about state changes on a blink::WebMediaStreamSource object or such an
-// object underlying a blink::WebMediaStreamTrack.
+// about state changes on a WebMediaStreamSource object or such an
+// object underlying a WebMediaStreamTrack.
 class BLINK_PLATFORM_EXPORT WebMediaStreamSink {
  public:
-  virtual void OnReadyStateChanged(
-      blink::WebMediaStreamSource::ReadyState state) {}
+  virtual void OnReadyStateChanged(WebMediaStreamSource::ReadyState state) {}
   virtual void OnEnabledChanged(bool enabled) {}
   virtual void OnContentHintChanged(
-      blink::WebMediaStreamTrack::ContentHintType content_hint) {}
+      WebMediaStreamTrack::ContentHintType content_hint) {}
 
  protected:
   virtual ~WebMediaStreamSink() {}
diff --git a/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h b/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h
index 5dcf040..c0ae2411 100644
--- a/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h
+++ b/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h
@@ -88,9 +88,9 @@
  private:
   MediaStreamDevice device_;
   SourceStoppedCallback stop_callback_;
-  blink::WebPrivatePtr<MediaStreamSource,
-                       kWebPrivatePtrDestructionSameThread,
-                       WebPrivatePtrStrength::kWeak>
+  WebPrivatePtr<MediaStreamSource,
+                kWebPrivatePtrDestructionSameThread,
+                WebPrivatePtrStrength::kWeak>
       owner_;
 
   DISALLOW_COPY_AND_ASSIGN(WebPlatformMediaStreamSource);
diff --git a/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h b/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h
index cb89fb10..c74a1ce 100644
--- a/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h
+++ b/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h
@@ -14,19 +14,19 @@
 namespace blink {
 
 // WebPlatformMediaStreamTrack is a low-level object backing a
-// blink::WebMediaStreamTrack.
+// WebMediaStreamTrack.
 class BLINK_PLATFORM_EXPORT WebPlatformMediaStreamTrack {
  public:
   explicit WebPlatformMediaStreamTrack(bool is_local_track);
   virtual ~WebPlatformMediaStreamTrack();
 
   static WebPlatformMediaStreamTrack* GetTrack(
-      const blink::WebMediaStreamTrack& track);
+      const WebMediaStreamTrack& track);
 
   virtual void SetEnabled(bool enabled) = 0;
 
   virtual void SetContentHint(
-      blink::WebMediaStreamTrack::ContentHintType content_hint) = 0;
+      WebMediaStreamTrack::ContentHintType content_hint) = 0;
 
   // If |callback| is not null, it is invoked when the track has stopped.
   virtual void StopAndNotify(base::OnceClosure callback) = 0;
@@ -34,7 +34,7 @@
   void Stop() { StopAndNotify(base::OnceClosure()); }
 
   // TODO(hta): Make method pure virtual when all tracks have the method.
-  virtual void GetSettings(blink::WebMediaStreamTrack::Settings& settings) {}
+  virtual void GetSettings(WebMediaStreamTrack::Settings& settings) {}
 
   bool is_local_track() const { return is_local_track_; }
 
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index e89fff83..07dbad1 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -676,6 +676,10 @@
 
   virtual void UpdateWebRTCAPICount(WebRTCAPIName api_name) {}
 
+  virtual base::Optional<double> GetWebRtcMaxCaptureFrameRate() {
+    return base::nullopt;
+  }
+
   // WebWorker ----------------------------------------------------------
 
   virtual std::unique_ptr<WebDedicatedWorkerHostFactoryClient>
diff --git a/third_party/blink/public/platform/web_rtc_ice_candidate.h b/third_party/blink/public/platform/web_rtc_ice_candidate.h
index 68d67f92..39087b8 100644
--- a/third_party/blink/public/platform/web_rtc_ice_candidate.h
+++ b/third_party/blink/public/platform/web_rtc_ice_candidate.h
@@ -43,20 +43,26 @@
  public:
   REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
 
-  // TODO(guidou): Support setting sdp_m_line_index to -1 to indicate the
-  // absence of a value for sdp_m_line_index. crbug.com/614958
+  // Creates a new WebRTCICECandidate using |candidate|, |sdp_mid| and
+  // |sdp_m_line_index|. If |sdp_m_line_index| is negative, it is
+  // considered as having no value.
   static scoped_refptr<WebRTCICECandidate> Create(WebString candidate,
                                                   WebString sdp_mid,
-                                                  uint16_t sdp_m_line_index);
+                                                  int sdp_m_line_index);
 
-  static scoped_refptr<WebRTCICECandidate> Create(WebString candidate,
-                                                  WebString sdp_mid,
-                                                  uint16_t sdp_m_line_index,
-                                                  WebString username_fragment);
+  // Creates a new WebRTCICECandidate using |candidate|, |sdp_mid|,
+  // |sdp_m_line_index|, and |username_fragment|.
+  static scoped_refptr<WebRTCICECandidate> Create(
+      WebString candidate,
+      WebString sdp_mid,
+      base::Optional<uint16_t> sdp_m_line_index,
+      WebString username_fragment);
 
   const WebString& Candidate() const { return candidate_; }
   const WebString& SdpMid() const { return sdp_mid_; }
-  uint16_t SdpMLineIndex() const { return sdp_m_line_index_; }
+  const base::Optional<uint16_t>& SdpMLineIndex() const {
+    return sdp_m_line_index_;
+  }
   const WebString& Foundation() const { return foundation_; }
   const WebString& Component() const { return component_; }
   const base::Optional<uint32_t>& Priority() const { return priority_; }
@@ -74,11 +80,11 @@
 
   WebRTCICECandidate(WebString candidate,
                      WebString sdp_mid,
-                     uint16_t sdp_m_line_index);
+                     base::Optional<uint16_t> sdp_m_line_index);
 
   WebRTCICECandidate(WebString candidate,
                      WebString sdp_mid,
-                     uint16_t sdp_m_line_index,
+                     base::Optional<uint16_t> sdp_m_line_index,
                      WebString username_fragment);
 
   void PopulateFields(bool use_username_from_candidate);
@@ -87,7 +93,7 @@
 
   WebString candidate_;
   WebString sdp_mid_;
-  uint16_t sdp_m_line_index_;
+  base::Optional<uint16_t> sdp_m_line_index_;
   WebString foundation_;
   WebString component_;
   base::Optional<uint32_t> priority_;
diff --git a/third_party/blink/public/web/modules/mediastream/DEPS b/third_party/blink/public/web/modules/mediastream/DEPS
new file mode 100644
index 0000000..53880d2
--- /dev/null
+++ b/third_party/blink/public/web/modules/mediastream/DEPS
@@ -0,0 +1,16 @@
+include_rules = [
+    # TODO(crbug.com/923394): Remove this dependency once STL types are
+    # migrated to WTF types in mediastream.
+    "+base/stl_util.h",
+
+    "+base/compiler_specific.h",
+    "+base/logging.h",
+    "+base/gtest_prod_util.h",
+    "+base/memory/weak_ptr.h",
+    "+base/sequence_checker.h",
+    "+base/single_thread_task_runner.h",
+    "+base/threading/thread_checker.h",
+    "+media/base",
+    "+media/capture",
+    "+ui/gfx/geometry/size.h"
+]
diff --git a/content/renderer/media/stream/media_stream_constraints_util.h b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h
similarity index 89%
rename from content/renderer/media/stream/media_stream_constraints_util.h
rename to third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h
index f227c36..b6df0a16 100644
--- a/content/renderer/media/stream/media_stream_constraints_util.h
+++ b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h
@@ -2,23 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
 
 #include <string>
 
 #include "base/logging.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
-#include "content/renderer/media/stream/video_track_adapter.h"
 #include "media/base/video_facing.h"
 #include "media/capture/video_capture_types.h"
-#include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
+#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-shared.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 
-namespace content {
+namespace blink {
 
 extern const double kMinDeviceCaptureFrameRate;
 
@@ -54,7 +54,7 @@
 // If SelectSettings fails, the HasValue() method returns false and
 // failed_constraint_name() returns the name of one of the (possibly multiple)
 // constraints that could not be satisfied.
-class CONTENT_EXPORT VideoCaptureSettings {
+class BLINK_EXPORT VideoCaptureSettings {
  public:
   // Creates an object without value and with an empty failed constraint name.
   VideoCaptureSettings();
@@ -79,7 +79,7 @@
   VideoCaptureSettings& operator=(VideoCaptureSettings&& other);
   ~VideoCaptureSettings();
 
-  bool HasValue() const { return failed_constraint_name_ == nullptr; }
+  bool HasValue() const { return !failed_constraint_name_; }
 
   // Convenience accessors for fields embedded in |capture_params_|.
   const media::VideoCaptureFormat& Format() const {
@@ -164,7 +164,7 @@
 // If SelectSettings fails, the HasValue() method returns false and
 // failed_constraint_name() returns the name of one of the (possibly multiple)
 // constraints that could not be satisfied.
-class CONTENT_EXPORT AudioCaptureSettings {
+class BLINK_EXPORT AudioCaptureSettings {
  public:
   enum class ProcessingType {
     // System echo cancellation can be enabled, but all other processing is
@@ -197,7 +197,7 @@
   AudioCaptureSettings(AudioCaptureSettings&& other);
   AudioCaptureSettings& operator=(AudioCaptureSettings&& other);
 
-  bool HasValue() const { return failed_constraint_name_ == nullptr; }
+  bool HasValue() const { return !failed_constraint_name_; }
 
   // Accessors.
   const char* failed_constraint_name() const { return failed_constraint_name_; }
@@ -229,7 +229,7 @@
 // Method to get boolean value of constraint with |name| from constraints.
 // Returns true if the constraint is specified in either mandatory or optional
 // constraints.
-CONTENT_EXPORT bool GetConstraintValueAsBoolean(
+BLINK_EXPORT bool GetConstraintValueAsBoolean(
     const blink::WebMediaConstraints& constraints,
     const blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*picker,
     bool* value);
@@ -237,17 +237,17 @@
 // Method to get int value of constraint with |name| from constraints.
 // Returns true if the constraint is specified in either mandatory or Optional
 // constraints.
-CONTENT_EXPORT bool GetConstraintValueAsInteger(
+BLINK_EXPORT bool GetConstraintValueAsInteger(
     const blink::WebMediaConstraints& constraints,
     const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
     int* value);
 
-CONTENT_EXPORT bool GetConstraintMinAsInteger(
+BLINK_EXPORT bool GetConstraintMinAsInteger(
     const blink::WebMediaConstraints& constraints,
     const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
     int* value);
 
-CONTENT_EXPORT bool GetConstraintMaxAsInteger(
+BLINK_EXPORT bool GetConstraintMaxAsInteger(
     const blink::WebMediaConstraints& constraints,
     const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
     int* value);
@@ -255,17 +255,17 @@
 // Method to get double precision value of constraint with |name| from
 // constraints. Returns true if the constraint is specified in either mandatory
 // or Optional constraints.
-CONTENT_EXPORT bool GetConstraintValueAsDouble(
+BLINK_EXPORT bool GetConstraintValueAsDouble(
     const blink::WebMediaConstraints& constraints,
     const blink::DoubleConstraint blink::WebMediaTrackConstraintSet::*picker,
     double* value);
 
-CONTENT_EXPORT bool GetConstraintMinAsDouble(
+BLINK_EXPORT bool GetConstraintMinAsDouble(
     const blink::WebMediaConstraints& constraints,
     const blink::DoubleConstraint blink::WebMediaTrackConstraintSet::*picker,
     double* value);
 
-CONTENT_EXPORT bool GetConstraintMaxAsDouble(
+BLINK_EXPORT bool GetConstraintMaxAsDouble(
     const blink::WebMediaConstraints& constraints,
     const blink::DoubleConstraint blink::WebMediaTrackConstraintSet::*picker,
     double* value);
@@ -273,7 +273,7 @@
 // Method to get std::string value of constraint with |name| from constraints.
 // Returns true if the constraint is specified in either mandatory or Optional
 // constraints.
-CONTENT_EXPORT bool GetConstraintValueAsString(
+BLINK_EXPORT bool GetConstraintValueAsString(
     const blink::WebMediaConstraints& constraints,
     const blink::StringConstraint blink::WebMediaTrackConstraintSet::*picker,
     std::string* value);
@@ -291,7 +291,8 @@
              : nullptr;
 }
 
-std::string GetMediaStreamSource(const blink::WebMediaConstraints& constraints);
+BLINK_EXPORT std::string GetMediaStreamSource(
+    const blink::WebMediaConstraints& constraints);
 bool IsDeviceCapture(const blink::WebMediaConstraints& constraints);
 
 // This function selects track settings from a set of candidate resolutions and
@@ -319,7 +320,7 @@
 // aspectRatio and frameRate are used.
 // This function has undefined behavior if any of |resolution_set| or
 // |frame_rate_set| are empty.
-CONTENT_EXPORT VideoTrackAdapterSettings SelectVideoTrackAdapterSettings(
+BLINK_EXPORT VideoTrackAdapterSettings SelectVideoTrackAdapterSettings(
     const blink::WebMediaTrackConstraintSet& basic_constraint_set,
     const media_constraints::ResolutionSet& resolution_set,
     const media_constraints::NumericRangeSet<double>& frame_rate_set,
@@ -329,7 +330,8 @@
 // Generic distance function between two values for numeric constraints. Based
 // on the fitness-distance function described in
 // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance
-double NumericConstraintFitnessDistance(double value1, double value2);
+BLINK_EXPORT double NumericConstraintFitnessDistance(double value1,
+                                                     double value2);
 
 // Fitness distance between |value| and |constraint|.
 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
@@ -339,7 +341,7 @@
 
 // This method computes capabilities for a video source based on the given
 // |formats|. |facing_mode| is valid only in case of video device capture.
-CONTENT_EXPORT blink::WebMediaStreamSource::Capabilities
+BLINK_EXPORT blink::WebMediaStreamSource::Capabilities
 ComputeCapabilitiesForVideoSource(
     const blink::WebString& device_id,
     const media::VideoCaptureFormats& formats,
@@ -347,6 +349,6 @@
     bool is_device_capture,
     const base::Optional<std::string>& group_id = base::nullopt);
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_H_
diff --git a/content/renderer/media/stream/media_stream_constraints_util_sets.h b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h
similarity index 90%
rename from content/renderer/media/stream/media_stream_constraints_util_sets.h
rename to third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h
index d79c525d..5bbd567 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_sets.h
+++ b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_
 
 #include <algorithm>
 #include <limits>
@@ -15,14 +15,12 @@
 #include "base/logging.h"
 #include "base/optional.h"
 #include "base/stl_util.h"
-#include "content/common/content_export.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 
 namespace blink {
-struct WebMediaTrackConstraintSet;
-}
 
-namespace content {
+struct WebMediaTrackConstraintSet;
 
 template <typename ConstraintType>
 bool ConstraintHasMax(const ConstraintType& constraint) {
@@ -220,23 +218,25 @@
   return Contains(true) && Contains(false);
 }
 
-DiscreteSet<std::string> StringSetFromConstraint(
-    const blink::StringConstraint& constraint);
-DiscreteSet<bool> BoolSetFromConstraint(
-    const blink::BooleanConstraint& constraint);
+// TODO(crbug.com/704136): Remove BLINK_EXPORT when this file is moved
+// out of blink/public/platform.
+BLINK_EXPORT DiscreteSet<std::string> StringSetFromConstraint(
+    const StringConstraint& constraint);
+BLINK_EXPORT DiscreteSet<bool> BoolSetFromConstraint(
+    const BooleanConstraint& constraint);
 
 // This class represents a set of (height, width) screen resolution candidates
 // determined by width, height and aspect-ratio constraints.
 // This class supports widths and heights from 0 to kMaxDimension, both
 // inclusive and aspect ratios from 0.0 to positive infinity, both inclusive.
-class CONTENT_EXPORT ResolutionSet {
+class BLINK_EXPORT ResolutionSet {
  public:
   static const int kMaxDimension = std::numeric_limits<int>::max();
 
   // Helper class that represents (height, width) points on a plane.
   // TODO(guidou): Use a generic point/vector class that uses double once it
   // becomes available (e.g., a gfx::Vector2dD).
-  class CONTENT_EXPORT Point {
+  class BLINK_EXPORT Point {
    public:
     // Creates a (|height|, |width|) point. |height| and |width| must be finite.
     Point(double height, double width);
@@ -371,7 +371,7 @@
   //
   // This function has undefined behavior if this set is empty.
   Point SelectClosestPointToIdeal(
-      const blink::WebMediaTrackConstraintSet& constraint_set,
+      const WebMediaTrackConstraintSet& constraint_set,
       int default_height,
       int default_width) const;
 
@@ -389,36 +389,14 @@
   // Returns a ResolutionCandidateSet initialized with |constraint_set|'s
   // width, height and aspectRatio constraints.
   static ResolutionSet FromConstraintSet(
-      const blink::WebMediaTrackConstraintSet& constraint_set);
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest,
-                           ResolutionVertices);
-  FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest,
-                           ResolutionPointSetClosestPoint);
-  FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest,
-                           ResolutionLineSetClosestPoint);
-  FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest,
-                           ResolutionGeneralSetClosestPoint);
-  FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest,
-                           ResolutionIdealOutsideSinglePoint);
-
-  // Implements SelectClosestPointToIdeal() for the case when only the ideal
-  // aspect ratio is provided.
-  Point SelectClosestPointToIdealAspectRatio(double ideal_aspect_ratio,
-                                             int default_height,
-                                             int default_width) const;
+      const WebMediaTrackConstraintSet& constraint_set);
 
   // Returns the closest point in this set to |point|. If |point| is included in
   // this set, Point is returned. If this set is empty, behavior is undefined.
+  // TODO(crbug.com/704136): Make this method private once dependent tests are
+  // moved to Blink.
   Point ClosestPointTo(const Point& point) const;
 
-  // Returns the vertices of the set that have the property accessed
-  // by |accessor| closest to |value|. The returned vector always has one or two
-  // elements. Behavior is undefined if the set is empty.
-  std::vector<Point> GetClosestVertices(double (Point::*accessor)() const,
-                                        double value) const;
-
   // Returns a list of the vertices defined by the constraints on a height-width
   // Cartesian plane.
   // If the list is empty, the set is empty.
@@ -430,8 +408,23 @@
   // consecutive vertices (modulo the size of the list) corresponds to a side of
   // the polygon, with the vertices given in counterclockwise order.
   // The list cannot contain more than six points.
+  // TODO(crbug.com/704136): Make this method private once dependent tests are
+  // moved to Blink.
   std::vector<Point> ComputeVertices() const;
 
+ private:
+  // Implements SelectClosestPointToIdeal() for the case when only the ideal
+  // aspect ratio is provided.
+  Point SelectClosestPointToIdealAspectRatio(double ideal_aspect_ratio,
+                                             int default_height,
+                                             int default_width) const;
+
+  // Returns the vertices of the set that have the property accessed
+  // by |accessor| closest to |value|. The returned vector always has one or two
+  // elements. Behavior is undefined if the set is empty.
+  std::vector<Point> GetClosestVertices(double (Point::*accessor)() const,
+                                        double value) const;
+
   // Adds |point| to |vertices| if |point| is included in this candidate set.
   void TryAddVertex(std::vector<ResolutionSet::Point>* vertices,
                     const ResolutionSet::Point& point) const;
@@ -445,19 +438,19 @@
 };
 
 // Scalar multiplication for Points.
-CONTENT_EXPORT ResolutionSet::Point operator*(double d,
-                                              const ResolutionSet::Point& p);
+BLINK_EXPORT ResolutionSet::Point operator*(double d,
+                                            const ResolutionSet::Point& p);
 
 // This function returns a set of bools from a resizeMode StringConstraint.
 // If |resize_mode_constraint| includes
-// blink::WebMediaStreamTrack::kResizeModeNone, false is included in the
+// WebMediaStreamTrack::kResizeModeNone, false is included in the
 // returned value. If |resize_mode_constraint| includes
-// blink::WebMediaStreamTrack::kResizeModeRescale, true is included in the
+// WebMediaStreamTrack::kResizeModeRescale, true is included in the
 // returned value.
-CONTENT_EXPORT DiscreteSet<bool> RescaleSetFromConstraint(
-    const blink::StringConstraint& resize_mode_constraint);
+BLINK_EXPORT DiscreteSet<bool> RescaleSetFromConstraint(
+    const StringConstraint& resize_mode_constraint);
 
 }  // namespace media_constraints
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_device.h b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h
similarity index 84%
rename from content/renderer/media/stream/media_stream_constraints_util_video_device.h
rename to third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h
index 4210b02..e4b6005c 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_video_device.h
+++ b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h
@@ -2,42 +2,42 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_DEVICE_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_DEVICE_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_DEVICE_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_DEVICE_H_
 
 #include <string>
 #include <vector>
 
 #include "base/optional.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "media/capture/video_capture_types.h"
+#include "third_party/blink/public/platform/web_common.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 
 namespace blink {
 class WebString;
 class WebMediaConstraints;
 }  // namespace blink
 
-namespace content {
+namespace blink {
 
 // Calculates and returns videoKind value for |format|.
 // See https://w3c.github.io/mediacapture-depth.
-CONTENT_EXPORT blink::WebString GetVideoKindForFormat(
-    const media::VideoCaptureFormat& format);
+BLINK_EXPORT WebString
+GetVideoKindForFormat(const media::VideoCaptureFormat& format);
 
-CONTENT_EXPORT blink::WebMediaStreamTrack::FacingMode ToWebFacingMode(
+BLINK_EXPORT WebMediaStreamTrack::FacingMode ToWebFacingMode(
     media::VideoFacingMode video_facing);
 
-CONTENT_EXPORT blink::WebMediaStreamTrack::DisplayCaptureSurfaceType
-ToWebDisplaySurface(media::mojom::DisplayCaptureSurfaceType display_surface);
+BLINK_EXPORT WebMediaStreamTrack::DisplayCaptureSurfaceType ToWebDisplaySurface(
+    media::mojom::DisplayCaptureSurfaceType display_surface);
 
-CONTENT_EXPORT blink::WebMediaStreamTrack::CursorCaptureType
-ToWebCursorCaptureType(media::mojom::CursorCaptureType cursor);
+BLINK_EXPORT WebMediaStreamTrack::CursorCaptureType ToWebCursorCaptureType(
+    media::mojom::CursorCaptureType cursor);
 
 // This is a temporary struct to bridge blink and content mojo types.
 // TODO(crbug.com/704136): Replace references to this type with the blink mojo
 // type once all dependent types are migrated to Blink.
-struct CONTENT_EXPORT VideoInputDeviceCapabilities {
+struct BLINK_EXPORT VideoInputDeviceCapabilities {
   VideoInputDeviceCapabilities(std::string device_id,
                                std::string group_id,
                                std::vector<media::VideoCaptureFormat> formats,
@@ -53,7 +53,7 @@
   media::VideoFacingMode facing_mode;
 };
 
-struct CONTENT_EXPORT VideoDeviceCaptureCapabilities {
+struct BLINK_EXPORT VideoDeviceCaptureCapabilities {
   VideoDeviceCaptureCapabilities();
   VideoDeviceCaptureCapabilities(VideoDeviceCaptureCapabilities&& other);
   ~VideoDeviceCaptureCapabilities();
@@ -131,13 +131,13 @@
 // the track_adapter_settings() accessor. For more details about the algorithm
 // for track adapter settings, see the SelectVideoTrackAdapterSettings
 // documentation.
-VideoCaptureSettings CONTENT_EXPORT SelectSettingsVideoDeviceCapture(
+VideoCaptureSettings BLINK_EXPORT SelectSettingsVideoDeviceCapture(
     const VideoDeviceCaptureCapabilities& capabilities,
-    const blink::WebMediaConstraints& constraints,
+    const WebMediaConstraints& constraints,
     int default_width,
     int default_height,
     double default_frame_rate);
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_DEVICE_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_VIDEO_DEVICE_H_
diff --git a/content/renderer/media/stream/media_stream_video_source.h b/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
similarity index 89%
rename from content/renderer/media/stream/media_stream_video_source.h
rename to third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
index 4ebb5fd..b7c6b339 100644
--- a/content/renderer/media/stream/media_stream_video_source.h
+++ b/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_VIDEO_SOURCE_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_VIDEO_SOURCE_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_VIDEO_SOURCE_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_VIDEO_SOURCE_H_
 
 #include <memory>
 #include <string>
@@ -14,13 +14,13 @@
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
 #include "base/sequence_checker.h"
-#include "content/common/content_export.h"
 #include "media/base/video_frame.h"
 #include "media/capture/video_capture_types.h"
 #include "third_party/blink/public/common/media/video_capture.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_types.h"
 #include "third_party/blink/public/platform/modules/mediastream/secure_display_link_tracker.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
@@ -29,7 +29,7 @@
 class SingleThreadTaskRunner;
 }
 
-namespace content {
+namespace blink {
 
 class MediaStreamVideoTrack;
 class VideoTrackAdapter;
@@ -42,8 +42,8 @@
 // MediaStreamVideoSources such as local video capture, video sources received
 // on a PeerConnection or a source created in NaCl.
 // All methods calls will be done from the main render thread.
-class CONTENT_EXPORT MediaStreamVideoSource
-    : public blink::WebPlatformMediaStreamSource {
+class BLINK_EXPORT MediaStreamVideoSource
+    : public WebPlatformMediaStreamSource {
  public:
   enum {
     // Default resolution. If no constraints are specified and the delegate
@@ -59,20 +59,19 @@
   // RestartCallback is used for both the StopForRestart and Restart operations.
   using RestartCallback = base::OnceCallback<void(RestartResult)>;
 
-
   MediaStreamVideoSource();
   ~MediaStreamVideoSource() override;
 
   // Returns the MediaStreamVideoSource object owned by |source|.
   static MediaStreamVideoSource* GetVideoSource(
-      const blink::WebMediaStreamSource& source);
+      const WebMediaStreamSource& source);
 
   // Puts |track| in the registered tracks list.
   void AddTrack(MediaStreamVideoTrack* track,
                 const VideoTrackAdapterSettings& track_adapter_settings,
-                const blink::VideoCaptureDeliverFrameCB& frame_callback,
-                const blink::VideoTrackSettingsCallback& settings_callback,
-                const blink::VideoTrackFormatCallback& format_callback,
+                const VideoCaptureDeliverFrameCB& frame_callback,
+                const VideoTrackSettingsCallback& settings_callback,
+                const VideoTrackFormatCallback& format_callback,
                 const ConstraintsCallback& callback);
   void RemoveTrack(MediaStreamVideoTrack* track, base::OnceClosure callback);
 
@@ -164,11 +163,11 @@
 
  protected:
   // MediaStreamSource implementation.
-  void DoChangeSource(const blink::MediaStreamDevice& new_device) override;
+  void DoChangeSource(const MediaStreamDevice& new_device) override;
   void DoStopSource() override;
 
   // Sets ready state and notifies the ready state to all registered tracks.
-  virtual void SetReadyState(blink::WebMediaStreamSource::ReadyState state);
+  virtual void SetReadyState(WebMediaStreamSource::ReadyState state);
 
   // Sets muted state and notifies it to all registered tracks.
   virtual void SetMutedState(bool state);
@@ -178,8 +177,8 @@
   // An implementation must call |frame_callback| on the IO thread with the
   // captured frames.
   virtual void StartSourceImpl(
-      const blink::VideoCaptureDeliverFrameCB& frame_callback) = 0;
-  void OnStartDone(blink::MediaStreamRequestResult result);
+      const VideoCaptureDeliverFrameCB& frame_callback) = 0;
+  void OnStartDone(MediaStreamRequestResult result);
 
   // A subclass that supports restart must override this method such that it
   // immediately stop producing video frames after this method is called.
@@ -241,7 +240,7 @@
   virtual void OnCapturingLinkSecured(bool is_secure) {}
 
   // Optionally overridden by subclasses to implement changing source.
-  virtual void ChangeSourceImpl(const blink::MediaStreamDevice& new_device) {}
+  virtual void ChangeSourceImpl(const MediaStreamDevice& new_device) {}
 
   enum State {
     NEW,
@@ -268,7 +267,7 @@
 
   // Actually adds |track| to this source, provided the source has started.
   void FinalizeAddTrack(MediaStreamVideoTrack* track,
-                        const blink::VideoCaptureDeliverFrameCB& frame_callback,
+                        const VideoCaptureDeliverFrameCB& frame_callback,
                         const VideoTrackAdapterSettings& adapter_settings);
   void StartFrameMonitoring();
   void UpdateTrackSettings(MediaStreamVideoTrack* track,
@@ -280,9 +279,9 @@
   struct PendingTrackInfo {
     PendingTrackInfo(
         MediaStreamVideoTrack* track,
-        const blink::VideoCaptureDeliverFrameCB& frame_callback,
-        const blink::VideoTrackSettingsCallback& settings_callback,
-        const blink::VideoTrackFormatCallback& format_callback,
+        const VideoCaptureDeliverFrameCB& frame_callback,
+        const VideoTrackSettingsCallback& settings_callback,
+        const VideoTrackFormatCallback& format_callback,
         std::unique_ptr<VideoTrackAdapterSettings> adapter_settings,
         const ConstraintsCallback& callback);
     PendingTrackInfo(PendingTrackInfo&& other);
@@ -290,9 +289,9 @@
     ~PendingTrackInfo();
 
     MediaStreamVideoTrack* track;
-    blink::VideoCaptureDeliverFrameCB frame_callback;
-    blink::VideoTrackSettingsCallback settings_callback;
-    blink::VideoTrackFormatCallback format_callback;
+    VideoCaptureDeliverFrameCB frame_callback;
+    VideoTrackSettingsCallback settings_callback;
+    VideoTrackFormatCallback format_callback;
     // TODO(guidou): Make |adapter_settings| a regular field instead of a
     // unique_ptr.
     std::unique_ptr<VideoTrackAdapterSettings> adapter_settings;
@@ -316,7 +315,7 @@
   std::vector<MediaStreamVideoTrack*> suspended_tracks_;
 
   // This is used for tracking if all connected video sinks are secure.
-  blink::SecureDisplayLinkTracker<MediaStreamVideoTrack> secure_tracker_;
+  SecureDisplayLinkTracker<MediaStreamVideoTrack> secure_tracker_;
 
   // This flag enables a heuristic to detect device rotation based on frame
   // size.
@@ -328,6 +327,6 @@
   DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoSource);
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_VIDEO_SOURCE_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_VIDEO_SOURCE_H_
diff --git a/content/renderer/media/stream/media_stream_video_track.h b/third_party/blink/public/web/modules/mediastream/media_stream_video_track.h
similarity index 92%
rename from content/renderer/media/stream/media_stream_video_track.h
rename to third_party/blink/public/web/modules/mediastream/media_stream_video_track.h
index 997d5b65..536bd11 100644
--- a/content/renderer/media/stream/media_stream_video_track.h
+++ b/third_party/blink/public/web/modules/mediastream/media_stream_video_track.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_VIDEO_TRACK_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_VIDEO_TRACK_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_VIDEO_TRACK_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_VIDEO_TRACK_H_
 
 #include <memory>
 #include <vector>
@@ -13,14 +13,14 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
 #include "third_party/blink/public/platform/modules/mediastream/secure_display_link_tracker.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h"
 #include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
-namespace content {
+namespace blink {
 
 class VideoTrackAdapterSettings;
 
@@ -28,7 +28,7 @@
 // blink::WebMediaStreamTrack in content. It is owned by the blink object
 // and can be retrieved from a blink object using
 // WebMediaStreamTrack::getExtraData() or MediaStreamVideoTrack::GetVideoTrack.
-class CONTENT_EXPORT MediaStreamVideoTrack
+class BLINK_EXPORT MediaStreamVideoTrack
     : public blink::WebPlatformMediaStreamTrack {
  public:
   // Help method to create a blink::WebMediaStreamTrack and a
@@ -95,9 +95,7 @@
   const base::Optional<bool>& noise_reduction() const {
     return noise_reduction_;
   }
-  bool is_screencast() const {
-    return is_screencast_;
-  }
+  bool is_screencast() const { return is_screencast_; }
   const base::Optional<double>& min_frame_rate() const {
     return min_frame_rate_;
   }
@@ -184,6 +182,6 @@
   DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoTrack);
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_VIDEO_TRACK_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_MEDIA_STREAM_VIDEO_TRACK_H_
diff --git a/content/renderer/media/stream/video_track_adapter.h b/third_party/blink/public/web/modules/mediastream/video_track_adapter.h
similarity index 84%
rename from content/renderer/media/stream/video_track_adapter.h
rename to third_party/blink/public/web/modules/mediastream/video_track_adapter.h
index 4280f1b..57c33d6 100644
--- a/content/renderer/media/stream/video_track_adapter.h
+++ b/third_party/blink/public/web/modules/mediastream/video_track_adapter.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_VIDEO_TRACK_ADAPTER_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_VIDEO_TRACK_ADAPTER_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_VIDEO_TRACK_ADAPTER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_VIDEO_TRACK_ADAPTER_H_
 
 #include <stdint.h>
 
@@ -13,15 +13,15 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
 #include "media/base/video_frame.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_types.h"
+#include "third_party/blink/public/platform/web_common.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "ui/gfx/geometry/size.h"
 
-namespace content {
+namespace blink {
 
-class CONTENT_EXPORT VideoTrackAdapterSettings {
+class BLINK_EXPORT VideoTrackAdapterSettings {
  public:
   // Creates a VideoTrackAdapterSettings with no target resolution or frame rate
   // and without any constraints on the resolution.
@@ -76,7 +76,7 @@
 // the IO-thread.
 // Adaptations is done by wrapping the original media::VideoFrame in a new
 // media::VideoFrame with a new visible_rect and natural_size.
-class VideoTrackAdapter
+class BLINK_EXPORT VideoTrackAdapter
     : public base::RefCountedThreadSafe<VideoTrackAdapter> {
  public:
   using OnMutedCallback = base::Callback<void(bool mute_state)>;
@@ -93,9 +93,9 @@
   // |source_frame_rate| is used to calculate a prudent interval to check for
   // passing frames and inform of the result via |on_muted_state_callback|.
   void AddTrack(const MediaStreamVideoTrack* track,
-                blink::VideoCaptureDeliverFrameCB frame_callback,
-                blink::VideoTrackSettingsCallback settings_callback,
-                blink::VideoTrackFormatCallback track_callback,
+                VideoCaptureDeliverFrameCB frame_callback,
+                VideoTrackSettingsCallback settings_callback,
+                VideoTrackFormatCallback track_callback,
                 const VideoTrackAdapterSettings& settings);
   void RemoveTrack(const MediaStreamVideoTrack* track);
   void ReconfigureTrack(const MediaStreamVideoTrack* track,
@@ -124,28 +124,26 @@
   // Returns true if |desired_size| is updated successfully, false otherwise.
   // |desired_size| is not updated |settings| has rescaling disabled and
   // |input_size| is invalid.
-  CONTENT_EXPORT static bool CalculateDesiredSize(
-      bool is_rotated,
-      const gfx::Size& input_size,
-      const VideoTrackAdapterSettings& settings,
-      gfx::Size* desired_size);
+  static bool CalculateDesiredSize(bool is_rotated,
+                                   const gfx::Size& input_size,
+                                   const VideoTrackAdapterSettings& settings,
+                                   gfx::Size* desired_size);
 
  private:
   virtual ~VideoTrackAdapter();
   friend class base::RefCountedThreadSafe<VideoTrackAdapter>;
 
   void AddTrackOnIO(const MediaStreamVideoTrack* track,
-                    blink::VideoCaptureDeliverFrameCB frame_callback,
-                    blink::VideoTrackSettingsCallback settings_callback,
-                    blink::VideoTrackFormatCallback track_callback,
+                    VideoCaptureDeliverFrameCB frame_callback,
+                    VideoTrackSettingsCallback settings_callback,
+                    VideoTrackFormatCallback track_callback,
                     const VideoTrackAdapterSettings& settings);
   void RemoveTrackOnIO(const MediaStreamVideoTrack* track);
   void ReconfigureTrackOnIO(const MediaStreamVideoTrack* track,
                             const VideoTrackAdapterSettings& settings);
 
-  void StartFrameMonitoringOnIO(
-    const OnMutedCallback& on_muted_state_callback,
-    double source_frame_rate);
+  void StartFrameMonitoringOnIO(const OnMutedCallback& on_muted_state_callback,
+                                double source_frame_rate);
   void StopFrameMonitoringOnIO();
   void SetSourceFrameSizeOnIO(const gfx::Size& frame_size);
 
@@ -193,6 +191,6 @@
   DISALLOW_COPY_AND_ASSIGN(VideoTrackAdapter);
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_VIDEO_TRACK_ADAPTER_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_MEDIASTREAM_VIDEO_TRACK_ADAPTER_H_
diff --git a/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc b/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc
index 1c3037b..41825fc 100644
--- a/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc
@@ -104,20 +104,21 @@
 
 TEST(ToV8Test, numeric) {
   V8TestingScope scope;
-  TEST_TOV8("0", static_cast<int>(0));
-  TEST_TOV8("1", static_cast<int>(1));
-  TEST_TOV8("-1", static_cast<int>(-1));
-
-  TEST_TOV8("-2", static_cast<long>(-2));
-  TEST_TOV8("2", static_cast<unsigned>(2));
-  TEST_TOV8("2", static_cast<unsigned long>(2));
+  TEST_TOV8("0", static_cast<int32_t>(0));
+  TEST_TOV8("1", static_cast<int32_t>(1));
+  TEST_TOV8("-1", static_cast<int32_t>(-1));
+  TEST_TOV8("2", static_cast<uint32_t>(2));
 
   TEST_TOV8("-2147483648", std::numeric_limits<int32_t>::min());
   TEST_TOV8("2147483647", std::numeric_limits<int32_t>::max());
   TEST_TOV8("4294967295", std::numeric_limits<uint32_t>::max());
   // v8::Number can represent exact numbers in [-(2^53-1), 2^53-1].
-  TEST_TOV8("-9007199254740991", -9007199254740991);  // -(2^53-1)
-  TEST_TOV8("9007199254740991", 9007199254740991);    // 2^53-1
+  TEST_TOV8("-9007199254740991",
+            static_cast<int64_t>(-9007199254740991));  // -(2^53-1)
+  TEST_TOV8("9007199254740991",
+            static_cast<int64_t>(9007199254740991));  // 2^53-1
+  TEST_TOV8("9007199254740991",
+            static_cast<uint64_t>(9007199254740991));  // 2^53-1
 
   TEST_TOV8("0.5", static_cast<double>(0.5));
   TEST_TOV8("-0.5", static_cast<float>(-0.5));
@@ -169,25 +170,25 @@
 
 TEST(ToV8Test, basicTypeVectors) {
   V8TestingScope scope;
-  Vector<int> int_vector;
-  int_vector.push_back(42);
-  int_vector.push_back(23);
-  TEST_TOV8("42,23", int_vector);
+  Vector<int32_t> int32_vector;
+  int32_vector.push_back(42);
+  int32_vector.push_back(23);
+  TEST_TOV8("42,23", int32_vector);
 
-  Vector<long> long_vector;
-  long_vector.push_back(31773);
-  long_vector.push_back(404);
-  TEST_TOV8("31773,404", long_vector);
+  Vector<int64_t> int64_vector;
+  int64_vector.push_back(31773);
+  int64_vector.push_back(404);
+  TEST_TOV8("31773,404", int64_vector);
 
-  Vector<unsigned> unsigned_vector;
-  unsigned_vector.push_back(1);
-  unsigned_vector.push_back(2);
-  TEST_TOV8("1,2", unsigned_vector);
+  Vector<uint32_t> uint32_vector;
+  uint32_vector.push_back(1);
+  uint32_vector.push_back(2);
+  TEST_TOV8("1,2", uint32_vector);
 
-  Vector<unsigned long> unsigned_long_vector;
-  unsigned_long_vector.push_back(1001);
-  unsigned_long_vector.push_back(2002);
-  TEST_TOV8("1001,2002", unsigned_long_vector);
+  Vector<uint64_t> uint64_vector;
+  uint64_vector.push_back(1001);
+  uint64_vector.push_back(2002);
+  TEST_TOV8("1001,2002", uint64_vector);
 
   Vector<float> float_vector;
   float_vector.push_back(0.125);
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
index e3f6ccb..86bc4121 100644
--- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -406,7 +406,7 @@
 
   for (const CSSValue* item : list) {
     const CSSValuePair& pair = ToCSSValuePair(*item);
-    AtomicString identifier(ToCSSCustomIdentValue(pair.First()).Value());
+    AtomicString identifier(To<CSSCustomIdentValue>(pair.First()).Value());
     int counter_value = ToCSSPrimitiveValue(pair.Second()).GetIntValue();
     CounterDirectives& directives =
     map.insert(identifier, CounterDirectives()).stored_value->value;
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 0fbe847b..08dd74f 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1710,30 +1710,6 @@
 jumbo_source_set("unit_tests") {
   testonly = true
   sources = [
-    "animation/animation_clock_test.cc",
-    "animation/animation_effect_test.cc",
-    "animation/animation_input_helpers_test.cc",
-    "animation/animation_sim_test.cc",
-    "animation/animation_test.cc",
-    "animation/animation_test_helper.cc",
-    "animation/animation_test_helper.h",
-    "animation/animation_time_delta_test.cc",
-    "animation/compositor_animations_test.cc",
-    "animation/css/css_animations_test.cc",
-    "animation/css/css_transition_data_test.cc",
-    "animation/document_timeline_test.cc",
-    "animation/effect_input_test.cc",
-    "animation/effect_stack_test.cc",
-    "animation/interpolable_value_test.cc",
-    "animation/interpolation_effect_test.cc",
-    "animation/keyframe_effect_model_test.cc",
-    "animation/keyframe_effect_test.cc",
-    "animation/list_interpolation_functions_test.cc",
-    "animation/property_handle_test.cc",
-    "animation/scroll_timeline_test.cc",
-    "animation/scroll_timeline_util_test.cc",
-    "animation/timing_calculations_test.cc",
-    "animation/timing_input_test.cc",
     "clipboard/data_object_test.cc",
     "clipboard/data_transfer_test.cc",
     "content_capture/content_capture_test.cc",
@@ -2271,6 +2247,7 @@
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/blink/renderer/core/accessibility:unit_tests",
+    "//third_party/blink/renderer/core/animation:unit_tests",
     "//third_party/blink/renderer/core/editing:unit_tests",
     "//third_party/blink/renderer/core/fileapi:unit_tests",
   ]
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS
index fd9ba6f6..aadf5873 100644
--- a/third_party/blink/renderer/core/DEPS
+++ b/third_party/blink/renderer/core/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
     "+base/atomic_sequence_num.h",
     "+base/files/file.h",
+    "+base/mac/foundation_util.h",
     "+base/memory/scoped_refptr.h",
     "+base/metrics/field_trial_params.h",
     "+base/strings/stringprintf.h",
diff --git a/third_party/blink/renderer/core/animation/BUILD.gn b/third_party/blink/renderer/core/animation/BUILD.gn
index 8dcf27c7..9f7da0d 100644
--- a/third_party/blink/renderer/core/animation/BUILD.gn
+++ b/third_party/blink/renderer/core/animation/BUILD.gn
@@ -243,3 +243,32 @@
     "worklet_animation_controller.h",
   ]
 }
+
+blink_core_tests("unit_tests") {
+  sources = [
+    "animation_clock_test.cc",
+    "animation_effect_test.cc",
+    "animation_input_helpers_test.cc",
+    "animation_sim_test.cc",
+    "animation_test.cc",
+    "animation_test_helper.cc",
+    "animation_test_helper.h",
+    "animation_time_delta_test.cc",
+    "compositor_animations_test.cc",
+    "css/css_animations_test.cc",
+    "css/css_transition_data_test.cc",
+    "document_timeline_test.cc",
+    "effect_input_test.cc",
+    "effect_stack_test.cc",
+    "interpolable_value_test.cc",
+    "interpolation_effect_test.cc",
+    "keyframe_effect_model_test.cc",
+    "keyframe_effect_test.cc",
+    "list_interpolation_functions_test.cc",
+    "property_handle_test.cc",
+    "scroll_timeline_test.cc",
+    "scroll_timeline_util_test.cc",
+    "timing_calculations_test.cc",
+    "timing_input_test.cc",
+  ]
+}
diff --git a/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc b/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
index ee5cb16..f687e99 100644
--- a/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
@@ -510,21 +510,21 @@
 
 InterpolationValue basic_shape_interpolation_functions::MaybeConvertCSSValue(
     const CSSValue& value) {
-  if (value.IsBasicShapeCircleValue()) {
-    return circle_functions::ConvertCSSValue(
-        cssvalue::ToCSSBasicShapeCircleValue(value));
+  if (auto* circle_value =
+          DynamicTo<cssvalue::CSSBasicShapeCircleValue>(value)) {
+    return circle_functions::ConvertCSSValue(*circle_value);
   }
-  if (value.IsBasicShapeEllipseValue()) {
-    return ellipse_functions::ConvertCSSValue(
-        cssvalue::ToCSSBasicShapeEllipseValue(value));
+
+  if (auto* ellipse_value =
+          DynamicTo<cssvalue::CSSBasicShapeEllipseValue>(value)) {
+    return ellipse_functions::ConvertCSSValue(*ellipse_value);
   }
-  if (value.IsBasicShapeInsetValue()) {
-    return inset_functions::ConvertCSSValue(
-        cssvalue::ToCSSBasicShapeInsetValue(value));
+  if (auto* inset_value = DynamicTo<cssvalue::CSSBasicShapeInsetValue>(value)) {
+    return inset_functions::ConvertCSSValue(*inset_value);
   }
-  if (value.IsBasicShapePolygonValue()) {
-    return polygon_functions::ConvertCSSValue(
-        cssvalue::ToCSSBasicShapePolygonValue(value));
+  if (auto* polygon_value =
+          DynamicTo<cssvalue::CSSBasicShapePolygonValue>(value)) {
+    return polygon_functions::ConvertCSSValue(*polygon_value);
   }
   return nullptr;
 }
diff --git a/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
index fa2106d..05efb71 100644
--- a/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
@@ -83,8 +83,8 @@
 
 std::unique_ptr<InterpolableValue>
 CSSColorInterpolationType::MaybeCreateInterpolableColor(const CSSValue& value) {
-  if (value.IsColorValue())
-    return CreateInterpolableColor(ToCSSColorValue(value).Value());
+  if (auto* color_value = DynamicTo<CSSColorValue>(value))
+    return CreateInterpolableColor(color_value->Value());
   if (!value.IsIdentifierValue())
     return nullptr;
   const CSSIdentifierValue& identifier_value = ToCSSIdentifierValue(value);
diff --git a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
index 2eb8bc3..4ad3083 100644
--- a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
@@ -157,8 +157,7 @@
   std::unique_ptr<InterpolableList> numbers = InterpolableList::Create(length);
   Vector<AtomicString> tags;
   for (wtf_size_t i = 0; i < length; ++i) {
-    const cssvalue::CSSFontVariationValue& item =
-        cssvalue::ToCSSFontVariationValue(list.Item(i));
+    const auto& item = To<cssvalue::CSSFontVariationValue>(list.Item(i));
     numbers->Set(i, InterpolableNumber::Create(item.Value()));
     tags.push_back(item.Tag());
   }
diff --git a/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
index bcddce8..a7705d7 100644
--- a/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
@@ -196,11 +196,11 @@
     const CSSValue& value,
     const StyleResolverState*,
     ConversionCheckers&) const {
-  if (!value.IsBorderImageSliceValue())
+  if (!IsA<cssvalue::CSSBorderImageSliceValue>(value))
     return nullptr;
 
   const cssvalue::CSSBorderImageSliceValue& slice =
-      cssvalue::ToCSSBorderImageSliceValue(value);
+      To<cssvalue::CSSBorderImageSliceValue>(value);
   std::unique_ptr<InterpolableList> list =
       InterpolableList::Create(kSideIndexCount);
   const CSSValue* sides[kSideIndexCount];
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_interpolation_type.cc
index 101252c..bde99df2 100644
--- a/third_party/blink/renderer/core/animation/css_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_interpolation_type.cc
@@ -172,7 +172,7 @@
   if (GetProperty().IsCSSCustomProperty()) {
     DCHECK(css_environment.HasVariableResolver());
     return MaybeConvertCustomPropertyDeclaration(
-        ToCSSCustomPropertyDeclaration(*value), state,
+        To<CSSCustomPropertyDeclaration>(*value), state,
         css_environment.VariableResolver(), conversion_checkers);
   }
 
diff --git a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
index ed715ba..90a036d 100644
--- a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
@@ -185,7 +185,7 @@
   if (value.IsValueList()) {
     CSSLengthArray length_array;
     for (const CSSValue* item : ToCSSValueList(value)) {
-      const CSSFunctionValue& transform_function = ToCSSFunctionValue(*item);
+      const auto& transform_function = To<CSSFunctionValue>(*item);
       if (transform_function.FunctionType() == CSSValueMatrix ||
           transform_function.FunctionType() == CSSValueMatrix3d) {
         length_array.type_flags.Set(CSSPrimitiveValue::kUnitTypePixels);
diff --git a/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
index 5ade91cd..9fe0001 100644
--- a/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
@@ -62,9 +62,8 @@
     const InterpolationEnvironment& environment,
     const InterpolationValue& underlying,
     ConversionCheckers& conversion_checkers) const {
-  const CSSCustomPropertyDeclaration& declaration =
-      *ToCSSCustomPropertyDeclaration(
-          ToCSSPropertySpecificKeyframe(keyframe).Value());
+  const auto& declaration = *To<CSSCustomPropertyDeclaration>(
+      ToCSSPropertySpecificKeyframe(keyframe).Value());
   DCHECK_EQ(GetProperty().CustomPropertyName(), declaration.GetName());
   if (!declaration.Value() || !declaration.Value()->NeedsVariableResolution()) {
     return nullptr;
diff --git a/third_party/blink/renderer/core/animation/filter_interpolation_functions.cc b/third_party/blink/renderer/core/animation/filter_interpolation_functions.cc
index 1e21c15e..81abea2 100644
--- a/third_party/blink/renderer/core/animation/filter_interpolation_functions.cc
+++ b/third_party/blink/renderer/core/animation/filter_interpolation_functions.cc
@@ -97,7 +97,7 @@
   if (value.IsURIValue())
     return nullptr;
 
-  const CSSFunctionValue& filter = ToCSSFunctionValue(value);
+  const auto& filter = To<CSSFunctionValue>(value);
   DCHECK_LE(filter.length(), 1u);
   FilterOperation::OperationType type =
       FilterOperationResolver::FilterOperationForType(filter.FunctionType());
diff --git a/third_party/blink/renderer/core/animation/string_keyframe.cc b/third_party/blink/renderer/core/animation/string_keyframe.cc
index d696d00..d7d1a81 100644
--- a/third_party/blink/renderer/core/animation/string_keyframe.cc
+++ b/third_party/blink/renderer/core/animation/string_keyframe.cc
@@ -86,7 +86,7 @@
         << property.PropertyID() << ").";
     if (property.IDEquals(CSSPropertyVariable)) {
       properties.insert(PropertyHandle(
-          ToCSSCustomPropertyDeclaration(property_reference.Value())
+          To<CSSCustomPropertyDeclaration>(property_reference.Value())
               .GetName()));
     } else {
       properties.insert(PropertyHandle(property, false));
diff --git a/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc b/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
index 2ddf7ae7..ac94bcd 100644
--- a/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
+++ b/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
@@ -40,7 +40,7 @@
     return "";
   CSSPropertyValueSet::PropertyReference property = PropertySet().PropertyAt(i);
   if (property.Id() == CSSPropertyVariable)
-    return ToCSSCustomPropertyDeclaration(property.Value()).GetName();
+    return To<CSSCustomPropertyDeclaration>(property.Value()).GetName();
   return property.Property().GetPropertyName();
 }
 
diff --git a/third_party/blink/renderer/core/css/basic_shape_functions.cc b/third_party/blink/renderer/core/css/basic_shape_functions.cc
index 78bd7d9a..1a5ebed5 100644
--- a/third_party/blink/renderer/core/css/basic_shape_functions.cc
+++ b/third_party/blink/renderer/core/css/basic_shape_functions.cc
@@ -287,9 +287,9 @@
     const CSSValue& basic_shape_value) {
   scoped_refptr<BasicShape> basic_shape;
 
-  if (basic_shape_value.IsBasicShapeCircleValue()) {
-    const cssvalue::CSSBasicShapeCircleValue& circle_value =
-        cssvalue::ToCSSBasicShapeCircleValue(basic_shape_value);
+  if (IsA<cssvalue::CSSBasicShapeCircleValue>(basic_shape_value)) {
+    const auto& circle_value =
+        To<cssvalue::CSSBasicShapeCircleValue>(basic_shape_value);
     scoped_refptr<BasicShapeCircle> circle = BasicShapeCircle::Create();
 
     circle->SetCenterX(
@@ -299,9 +299,9 @@
     circle->SetRadius(CssValueToBasicShapeRadius(state, circle_value.Radius()));
 
     basic_shape = std::move(circle);
-  } else if (basic_shape_value.IsBasicShapeEllipseValue()) {
-    const cssvalue::CSSBasicShapeEllipseValue& ellipse_value =
-        cssvalue::ToCSSBasicShapeEllipseValue(basic_shape_value);
+  } else if (IsA<cssvalue::CSSBasicShapeEllipseValue>(basic_shape_value)) {
+    const auto& ellipse_value =
+        To<cssvalue::CSSBasicShapeEllipseValue>(basic_shape_value);
     scoped_refptr<BasicShapeEllipse> ellipse = BasicShapeEllipse::Create();
 
     ellipse->SetCenterX(
@@ -314,9 +314,9 @@
         CssValueToBasicShapeRadius(state, ellipse_value.RadiusY()));
 
     basic_shape = std::move(ellipse);
-  } else if (basic_shape_value.IsBasicShapePolygonValue()) {
+  } else if (IsA<cssvalue::CSSBasicShapePolygonValue>(basic_shape_value)) {
     const cssvalue::CSSBasicShapePolygonValue& polygon_value =
-        cssvalue::ToCSSBasicShapePolygonValue(basic_shape_value);
+        To<cssvalue::CSSBasicShapePolygonValue>(basic_shape_value);
     scoped_refptr<BasicShapePolygon> polygon = BasicShapePolygon::Create();
 
     polygon->SetWindRule(polygon_value.GetWindRule());
@@ -327,9 +327,9 @@
                            ConvertToLength(state, values.at(i + 1).Get()));
 
     basic_shape = std::move(polygon);
-  } else if (basic_shape_value.IsBasicShapeInsetValue()) {
+  } else if (IsA<cssvalue::CSSBasicShapeInsetValue>(basic_shape_value)) {
     const cssvalue::CSSBasicShapeInsetValue& rect_value =
-        cssvalue::ToCSSBasicShapeInsetValue(basic_shape_value);
+        To<cssvalue::CSSBasicShapeInsetValue>(basic_shape_value);
     scoped_refptr<BasicShapeInset> rect = BasicShapeInset::Create();
 
     rect->SetTop(ConvertToLength(state, rect_value.Top()));
diff --git a/third_party/blink/renderer/core/css/css_axis_value.h b/third_party/blink/renderer/core/css/css_axis_value.h
index c0d7aee2..29a67d5 100644
--- a/third_party/blink/renderer/core/css/css_axis_value.h
+++ b/third_party/blink/renderer/core/css/css_axis_value.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/core/css/css_value_list.h"
 #include "third_party/blink/renderer/core/css_value_keywords.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -38,7 +39,10 @@
   CSSValueID axis_name_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSAxisValue, IsAxisValue());
+template <>
+struct DowncastTraits<CSSAxisValue> {
+  static bool AllowFrom(const CSSValue& value) { return value.IsAxisValue(); }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/css/css_basic_shape_values.h b/third_party/blink/renderer/core/css/css_basic_shape_values.h
index 037514d..5663c954 100644
--- a/third_party/blink/renderer/core/css/css_basic_shape_values.h
+++ b/third_party/blink/renderer/core/css/css_basic_shape_values.h
@@ -35,6 +35,7 @@
 #include "third_party/blink/renderer/core/css/css_value.h"
 #include "third_party/blink/renderer/core/css/css_value_pair.h"
 #include "third_party/blink/renderer/platform/graphics/graphics_types.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
@@ -209,15 +210,35 @@
   Member<CSSValuePair> bottom_left_radius_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSBasicShapeCircleValue,
-                            IsBasicShapeCircleValue());
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSBasicShapeEllipseValue,
-                            IsBasicShapeEllipseValue());
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSBasicShapePolygonValue,
-                            IsBasicShapePolygonValue());
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSBasicShapeInsetValue, IsBasicShapeInsetValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSBasicShapeCircleValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsBasicShapeCircleValue();
+  }
+};
+
+template <>
+struct DowncastTraits<cssvalue::CSSBasicShapeEllipseValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsBasicShapeEllipseValue();
+  }
+};
+
+template <>
+struct DowncastTraits<cssvalue::CSSBasicShapePolygonValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsBasicShapePolygonValue();
+  }
+};
+
+template <>
+struct DowncastTraits<cssvalue::CSSBasicShapeInsetValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsBasicShapeInsetValue();
+  }
+};
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_BASIC_SHAPE_VALUES_H_
diff --git a/third_party/blink/renderer/core/css/css_border_image_slice_value.h b/third_party/blink/renderer/core/css/css_border_image_slice_value.h
index c19bb059..4aef394 100644
--- a/third_party/blink/renderer/core/css/css_border_image_slice_value.h
+++ b/third_party/blink/renderer/core/css/css_border_image_slice_value.h
@@ -28,6 +28,7 @@
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/core/css/css_quad_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 namespace cssvalue {
@@ -58,10 +59,15 @@
   bool fill_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSBorderImageSliceValue,
-                            IsBorderImageSliceValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSBorderImageSliceValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsBorderImageSliceValue();
+  }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_BORDER_IMAGE_SLICE_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_color_value.h b/third_party/blink/renderer/core/css/css_color_value.h
index a63b22a..97c2a3c 100644
--- a/third_party/blink/renderer/core/css/css_color_value.h
+++ b/third_party/blink/renderer/core/css/css_color_value.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/core/css/css_value.h"
 #include "third_party/blink/renderer/platform/graphics/color.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
@@ -45,9 +46,13 @@
   Color color_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSColorValue, IsColorValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSColorValue> {
+  static bool AllowFrom(const CSSValue& value) { return value.IsColorValue(); }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_COLOR_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_content_distribution_value.h b/third_party/blink/renderer/core/css/css_content_distribution_value.h
index a9da14f..5ce5f7fe 100644
--- a/third_party/blink/renderer/core/css/css_content_distribution_value.h
+++ b/third_party/blink/renderer/core/css/css_content_distribution_value.h
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_value.h"
 #include "third_party/blink/renderer/core/css/css_value_pair.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 namespace cssvalue {
@@ -47,10 +48,15 @@
   CSSValueID overflow_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSContentDistributionValue,
-                            IsContentDistributionValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSContentDistributionValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsContentDistributionValue();
+  }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_CONTENT_DISTRIBUTION_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_counter_value.h b/third_party/blink/renderer/core/css/css_counter_value.h
index 1cc4f25..cdd6072 100644
--- a/third_party/blink/renderer/core/css/css_counter_value.h
+++ b/third_party/blink/renderer/core/css/css_counter_value.h
@@ -24,6 +24,7 @@
 #include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_string_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
@@ -66,10 +67,15 @@
   Member<CSSStringValue> separator_;        // string
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSCounterValue, IsCounterValue());
-
 }  // namespace cssvalue
 
+template <>
+struct DowncastTraits<cssvalue::CSSCounterValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsCounterValue();
+  }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_COUNTER_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_crossfade_value.h b/third_party/blink/renderer/core/css/css_crossfade_value.h
index f5d5df37..4c793c7 100644
--- a/third_party/blink/renderer/core/css/css_crossfade_value.h
+++ b/third_party/blink/renderer/core/css/css_crossfade_value.h
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
 #include "third_party/blink/renderer/core/loader/resource/image_resource_observer.h"
 #include "third_party/blink/renderer/platform/graphics/image.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -116,9 +117,15 @@
   CrossfadeSubimageObserverProxy crossfade_subimage_observer_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSCrossfadeValue, IsCrossfadeValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSCrossfadeValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsCrossfadeValue();
+  }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_CROSSFADE_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_cursor_image_value.h b/third_party/blink/renderer/core/css/css_cursor_image_value.h
index affb948e..919e296 100644
--- a/third_party/blink/renderer/core/css/css_cursor_image_value.h
+++ b/third_party/blink/renderer/core/css/css_cursor_image_value.h
@@ -23,6 +23,7 @@
 
 #include "third_party/blink/renderer/core/css/css_value.h"
 #include "third_party/blink/renderer/platform/geometry/int_point.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -58,10 +59,15 @@
   bool hot_spot_specified_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSCursorImageValue, IsCursorImageValue());
-
 }  // namespace cssvalue
 
+template <>
+struct DowncastTraits<cssvalue::CSSCursorImageValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsCursorImageValue();
+  }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_CURSOR_IMAGE_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_custom_ident_value.h b/third_party/blink/renderer/core/css/css_custom_ident_value.h
index 12800f70..6bbd7fe 100644
--- a/third_party/blink/renderer/core/css/css_custom_ident_value.h
+++ b/third_party/blink/renderer/core/css/css_custom_ident_value.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/css/css_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
 
 namespace blink {
@@ -50,7 +51,12 @@
   CSSPropertyID property_id_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSCustomIdentValue, IsCustomIdentValue());
+template <>
+struct DowncastTraits<CSSCustomIdentValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsCustomIdentValue();
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/css/css_custom_property_declaration.h b/third_party/blink/renderer/core/css/css_custom_property_declaration.h
index c81b2d1d..c70ba6c5 100644
--- a/third_party/blink/renderer/core/css/css_custom_property_declaration.h
+++ b/third_party/blink/renderer/core/css/css_custom_property_declaration.h
@@ -8,6 +8,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/core/css/css_value.h"
 #include "third_party/blink/renderer/core/css/css_variable_data.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
 
 namespace blink {
@@ -68,8 +69,12 @@
   CSSValueID value_id_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSCustomPropertyDeclaration,
-                            IsCustomPropertyDeclaration());
+template <>
+struct DowncastTraits<CSSCustomPropertyDeclaration> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsCustomPropertyDeclaration();
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/css/css_font_face_src_value.h b/third_party/blink/renderer/core/css/css_font_face_src_value.h
index e850ea3..d242096 100644
--- a/third_party/blink/renderer/core/css/css_font_face_src_value.h
+++ b/third_party/blink/renderer/core/css/css_font_face_src_value.h
@@ -30,6 +30,7 @@
 #include "third_party/blink/renderer/core/css/css_value.h"
 #include "third_party/blink/renderer/core/loader/resource/font_resource.h"
 #include "third_party/blink/renderer/platform/weborigin/referrer.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
@@ -129,7 +130,12 @@
   mutable Member<FontResourceHelper> fetched_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSFontFaceSrcValue, IsFontFaceSrcValue());
+template <>
+struct DowncastTraits<CSSFontFaceSrcValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsFontFaceSrcValue();
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/css/css_font_family_value.h b/third_party/blink/renderer/core/css/css_font_family_value.h
index 4ed587d..197efeb0 100644
--- a/third_party/blink/renderer/core/css/css_font_family_value.h
+++ b/third_party/blink/renderer/core/css/css_font_family_value.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_FONT_FAMILY_VALUE_H_
 
 #include "third_party/blink/renderer/core/css/css_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
@@ -33,7 +34,12 @@
   String string_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSFontFamilyValue, IsFontFamilyValue());
+template <>
+struct DowncastTraits<CSSFontFamilyValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsFontFamilyValue();
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/css/css_font_feature_value.h b/third_party/blink/renderer/core/css/css_font_feature_value.h
index e9c07bd..99c67aee5 100644
--- a/third_party/blink/renderer/core/css/css_font_feature_value.h
+++ b/third_party/blink/renderer/core/css/css_font_feature_value.h
@@ -27,6 +27,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_FONT_FEATURE_VALUE_H_
 
 #include "third_party/blink/renderer/core/css/css_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
@@ -54,9 +55,15 @@
   const int value_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSFontFeatureValue, IsFontFeatureValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSFontFeatureValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsFontFeatureValue();
+  }
+};
+
 }  // namespace blink
 
 #endif
diff --git a/third_party/blink/renderer/core/css/css_font_style_range_value.h b/third_party/blink/renderer/core/css/css_font_style_range_value.h
index 7330a1bf..b6c439e 100644
--- a/third_party/blink/renderer/core/css/css_font_style_range_value.h
+++ b/third_party/blink/renderer/core/css/css_font_style_range_value.h
@@ -28,6 +28,7 @@
 
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_value_list.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 namespace cssvalue {
@@ -72,9 +73,15 @@
   Member<const CSSValueList> oblique_values_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSFontStyleRangeValue, IsFontStyleRangeValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSFontStyleRangeValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsFontStyleRangeValue();
+  }
+};
+
 }  // namespace blink
 
 #endif
diff --git a/third_party/blink/renderer/core/css/css_font_variation_value.h b/third_party/blink/renderer/core/css/css_font_variation_value.h
index 6f08ebc5..f142a51 100644
--- a/third_party/blink/renderer/core/css/css_font_variation_value.h
+++ b/third_party/blink/renderer/core/css/css_font_variation_value.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_FONT_VARIATION_VALUE_H_
 
 #include "third_party/blink/renderer/core/css/css_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace blink {
@@ -34,9 +35,15 @@
   const float value_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSFontVariationValue, IsFontVariationValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSFontVariationValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsFontVariationValue();
+  }
+};
+
 }  // namespace blink
 
 #endif
diff --git a/third_party/blink/renderer/core/css/css_function_value.h b/third_party/blink/renderer/core/css/css_function_value.h
index ffc0cbb..9c84fa3 100644
--- a/third_party/blink/renderer/core/css/css_function_value.h
+++ b/third_party/blink/renderer/core/css/css_function_value.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/core/css/css_value_list.h"
 #include "third_party/blink/renderer/core/css_value_keywords.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 
 namespace blink {
 
@@ -34,7 +35,12 @@
   const CSSValueID value_id_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSFunctionValue, IsFunctionValue());
+template <>
+struct DowncastTraits<CSSFunctionValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsFunctionValue();
+  }
+};
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/css/css_gradient_value.cc b/third_party/blink/renderer/core/css/css_gradient_value.cc
index 3da9265..f10ce32f 100644
--- a/third_party/blink/renderer/core/css/css_gradient_value.cc
+++ b/third_party/blink/renderer/core/css/css_gradient_value.cc
@@ -129,15 +129,15 @@
   scoped_refptr<Gradient> gradient;
   switch (GetClassType()) {
     case kLinearGradientClass:
-      gradient = ToCSSLinearGradientValue(this)->CreateGradient(
+      gradient = To<CSSLinearGradientValue>(this)->CreateGradient(
           conversion_data, size, document, style);
       break;
     case kRadialGradientClass:
-      gradient = ToCSSRadialGradientValue(this)->CreateGradient(
+      gradient = To<CSSRadialGradientValue>(this)->CreateGradient(
           conversion_data, size, document, style);
       break;
     case kConicGradientClass:
-      gradient = ToCSSConicGradientValue(this)->CreateGradient(
+      gradient = To<CSSConicGradientValue>(this)->CreateGradient(
           conversion_data, size, document, style);
       break;
     default:
diff --git a/third_party/blink/renderer/core/css/css_gradient_value.h b/third_party/blink/renderer/core/css/css_gradient_value.h
index 443422f..245b232 100644
--- a/third_party/blink/renderer/core/css/css_gradient_value.h
+++ b/third_party/blink/renderer/core/css/css_gradient_value.h
@@ -30,6 +30,7 @@
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_image_generator_value.h"
 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
@@ -150,8 +151,6 @@
   bool is_cacheable_ : 1;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSGradientValue, IsGradientValue());
-
 class CSSLinearGradientValue final : public CSSGradientValue {
  public:
   static CSSGradientValue* Create(
@@ -201,8 +200,6 @@
   Member<const CSSPrimitiveValue> angle_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSLinearGradientValue, IsLinearGradientValue());
-
 class CSSRadialGradientValue final : public CSSGradientValue {
  public:
   static CSSGradientValue* Create(
@@ -296,8 +293,6 @@
   Member<const CSSPrimitiveValue> end_vertical_size_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSRadialGradientValue, IsRadialGradientValue());
-
 class CSSConicGradientValue final : public CSSGradientValue {
  public:
   static CSSGradientValue* Create(const CSSValue* x,
@@ -336,9 +331,36 @@
   Member<const CSSPrimitiveValue> from_angle_;
 };
 
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSConicGradientValue, IsConicGradientValue());
-
 }  // namespace cssvalue
+
+template <>
+struct DowncastTraits<cssvalue::CSSGradientValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsGradientValue();
+  }
+};
+
+template <>
+struct DowncastTraits<cssvalue::CSSLinearGradientValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsLinearGradientValue();
+  }
+};
+
+template <>
+struct DowncastTraits<cssvalue::CSSRadialGradientValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsRadialGradientValue();
+  }
+};
+
+template <>
+struct DowncastTraits<cssvalue::CSSConicGradientValue> {
+  static bool AllowFrom(const CSSValue& value) {
+    return value.IsConicGradientValue();
+  }
+};
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_GRADIENT_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_image_generator_value.cc b/third_party/blink/renderer/core/css/css_image_generator_value.cc
index b6c0f61..a202405 100644
--- a/third_party/blink/renderer/core/css/css_image_generator_value.cc
+++ b/third_party/blink/renderer/core/css/css_image_generator_value.cc
@@ -32,10 +32,10 @@
 
 namespace blink {
 
-using cssvalue::ToCSSCrossfadeValue;
-using cssvalue::ToCSSConicGradientValue;
-using cssvalue::ToCSSLinearGradientValue;
-using cssvalue::ToCSSRadialGradientValue;
+using cssvalue::CSSConicGradientValue;
+using cssvalue::CSSCrossfadeValue;
+using cssvalue::CSSLinearGradientValue;
+using cssvalue::CSSRadialGradientValue;
 
 Image* GeneratedImageCache::GetImage(const FloatSize& size) const {
   if (size.IsEmpty())
@@ -94,8 +94,8 @@
 }
 
 CSSImageGeneratorValue* CSSImageGeneratorValue::ValueWithURLsMadeAbsolute() {
-  if (IsCrossfadeValue())
-    return ToCSSCrossfadeValue(this)->ValueWithURLsMadeAbsolute();
+  if (auto* crossface_value = DynamicTo<CSSCrossfadeValue>(this))
+    return crossface_value->ValueWithURLsMadeAbsolute();
   return this;
 }
 
@@ -152,20 +152,20 @@
     const FloatSize& target_size) {
   switch (GetClassType()) {
     case kCrossfadeClass:
-      return ToCSSCrossfadeValue(this)->GetImage(client, document, style,
-                                                 target_size);
+      return To<CSSCrossfadeValue>(this)->GetImage(client, document, style,
+                                                   target_size);
     case kLinearGradientClass:
-      return ToCSSLinearGradientValue(this)->GetImage(client, document, style,
-                                                      target_size);
+      return To<CSSLinearGradientValue>(this)->GetImage(client, document, style,
+                                                        target_size);
     case kPaintClass:
       return ToCSSPaintValue(this)->GetImage(client, document, style,
                                              target_size);
     case kRadialGradientClass:
-      return ToCSSRadialGradientValue(this)->GetImage(client, document, style,
-                                                      target_size);
+      return To<CSSRadialGradientValue>(this)->GetImage(client, document, style,
+                                                        target_size);
     case kConicGradientClass:
-      return ToCSSConicGradientValue(this)->GetImage(client, document, style,
-                                                     target_size);
+      return To<CSSConicGradientValue>(this)->GetImage(client, document, style,
+                                                       target_size);
     default:
       NOTREACHED();
   }
@@ -175,15 +175,15 @@
 bool CSSImageGeneratorValue::IsFixedSize() const {
   switch (GetClassType()) {
     case kCrossfadeClass:
-      return ToCSSCrossfadeValue(this)->IsFixedSize();
+      return To<CSSCrossfadeValue>(this)->IsFixedSize();
     case kLinearGradientClass:
-      return ToCSSLinearGradientValue(this)->IsFixedSize();
+      return To<CSSLinearGradientValue>(this)->IsFixedSize();
     case kPaintClass:
       return ToCSSPaintValue(this)->IsFixedSize();
     case kRadialGradientClass:
-      return ToCSSRadialGradientValue(this)->IsFixedSize();
+      return To<CSSRadialGradientValue>(this)->IsFixedSize();
     case kConicGradientClass:
-      return ToCSSConicGradientValue(this)->IsFixedSize();
+      return To<CSSConicGradientValue>(this)->IsFixedSize();
     default:
       NOTREACHED();
   }
@@ -195,16 +195,16 @@
     const FloatSize& default_object_size) {
   switch (GetClassType()) {
     case kCrossfadeClass:
-      return ToCSSCrossfadeValue(this)->FixedSize(document,
-                                                  default_object_size);
+      return To<CSSCrossfadeValue>(this)->FixedSize(document,
+                                                    default_object_size);
     case kLinearGradientClass:
-      return ToCSSLinearGradientValue(this)->FixedSize(document);
+      return To<CSSLinearGradientValue>(this)->FixedSize(document);
     case kPaintClass:
       return ToCSSPaintValue(this)->FixedSize(document);
     case kRadialGradientClass:
-      return ToCSSRadialGradientValue(this)->FixedSize(document);
+      return To<CSSRadialGradientValue>(this)->FixedSize(document);
     case kConicGradientClass:
-      return ToCSSConicGradientValue(this)->FixedSize(document);
+      return To<CSSConicGradientValue>(this)->FixedSize(document);
     default:
       NOTREACHED();
   }
@@ -214,15 +214,15 @@
 bool CSSImageGeneratorValue::IsPending() const {
   switch (GetClassType()) {
     case kCrossfadeClass:
-      return ToCSSCrossfadeValue(this)->IsPending();
+      return To<CSSCrossfadeValue>(this)->IsPending();
     case kLinearGradientClass:
-      return ToCSSLinearGradientValue(this)->IsPending();
+      return To<CSSLinearGradientValue>(this)->IsPending();
     case kPaintClass:
       return ToCSSPaintValue(this)->IsPending();
     case kRadialGradientClass:
-      return ToCSSRadialGradientValue(this)->IsPending();
+      return To<CSSRadialGradientValue>(this)->IsPending();
     case kConicGradientClass:
-      return ToCSSConicGradientValue(this)->IsPending();
+      return To<CSSConicGradientValue>(this)->IsPending();
     default:
       NOTREACHED();
   }
@@ -233,15 +233,15 @@
                                              const ComputedStyle& style) const {
   switch (GetClassType()) {
     case kCrossfadeClass:
-      return ToCSSCrossfadeValue(this)->KnownToBeOpaque(document, style);
+      return To<CSSCrossfadeValue>(this)->KnownToBeOpaque(document, style);
     case kLinearGradientClass:
-      return ToCSSLinearGradientValue(this)->KnownToBeOpaque(document, style);
+      return To<CSSLinearGradientValue>(this)->KnownToBeOpaque(document, style);
     case kPaintClass:
       return ToCSSPaintValue(this)->KnownToBeOpaque(document, style);
     case kRadialGradientClass:
-      return ToCSSRadialGradientValue(this)->KnownToBeOpaque(document, style);
+      return To<CSSRadialGradientValue>(this)->KnownToBeOpaque(document, style);
     case kConicGradientClass:
-      return ToCSSConicGradientValue(this)->KnownToBeOpaque(document, style);
+      return To<CSSConicGradientValue>(this)->KnownToBeOpaque(document, style);
     default:
       NOTREACHED();
   }
@@ -251,19 +251,19 @@
 void CSSImageGeneratorValue::LoadSubimages(const Document& document) {
   switch (GetClassType()) {
     case kCrossfadeClass:
-      ToCSSCrossfadeValue(this)->LoadSubimages(document);
+      To<CSSCrossfadeValue>(this)->LoadSubimages(document);
       break;
     case kLinearGradientClass:
-      ToCSSLinearGradientValue(this)->LoadSubimages(document);
+      To<CSSLinearGradientValue>(this)->LoadSubimages(document);
       break;
     case kPaintClass:
       ToCSSPaintValue(this)->LoadSubimages(document);
       break;
     case kRadialGradientClass:
-      ToCSSRadialGradientValue(this)->LoadSubimages(document);
+      To<CSSRadialGradientValue>(this)->LoadSubimages(document);
       break;
     case kConicGradientClass:
-      ToCSSConicGradientValue(this)->LoadSubimages(document);
+      To<CSSConicGradientValue>(this)->LoadSubimages(document);
       break;
     default:
       NOTREACHED();
diff --git a/third_party/blink/renderer/core/css/css_property_value.cc b/third_party/blink/renderer/core/css/css_property_value.cc
index 8d9162e..4250b2b 100644
--- a/third_party/blink/renderer/core/css/css_property_value.cc
+++ b/third_party/blink/renderer/core/css/css_property_value.cc
@@ -51,7 +51,8 @@
 CSSPropertyName CSSPropertyValue::Name() const {
   if (Id() != CSSPropertyVariable)
     return CSSPropertyName(Id());
-  return CSSPropertyName(ToCSSCustomPropertyDeclaration(value_)->GetName());
+  return CSSPropertyName(
+      To<CSSCustomPropertyDeclaration>(value_.Get())->GetName());
 }
 
 bool CSSPropertyValue::operator==(const CSSPropertyValue& other) const {
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc
index 7ea34f2..324a8d4 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.cc
+++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -62,7 +62,7 @@
 CSSPropertyName CSSPropertyValueSet::PropertyReference::Name() const {
   if (Id() != CSSPropertyVariable)
     return CSSPropertyName(Id());
-  return CSSPropertyName(ToCSSCustomPropertyDeclaration(Value()).GetName());
+  return CSSPropertyName(To<CSSCustomPropertyDeclaration>(Value()).GetName());
 }
 
 ImmutableCSSPropertyValueSet* CSSPropertyValueSet::ImmutableCopyIfNeeded()
@@ -143,7 +143,7 @@
                             const AtomicString& custom_property_name) {
   DCHECK_EQ(id, CSSPropertyVariable);
   return metadata.Property().PropertyID() == id &&
-         ToCSSCustomPropertyDeclaration(value).GetName() ==
+         To<CSSCustomPropertyDeclaration>(value).GetName() ==
              custom_property_name;
 }
 
diff --git a/third_party/blink/renderer/core/css/css_selector_list.cc b/third_party/blink/renderer/core/css/css_selector_list.cc
index 5a4542f..8665232 100644
--- a/third_party/blink/renderer/core/css/css_selector_list.cc
+++ b/third_party/blink/renderer/core/css/css_selector_list.cc
@@ -137,14 +137,14 @@
   std::vector<const CSSSelector*> selector_boundaries =
       SelectorBoundaries(*this);
 
-  size_t i = 0;
+  size_t begin = 0;
   CSSSelectorList transformed = this->Copy();
-  while (!selector_boundaries[i]->HasPseudoIs() &&
-         !selector_boundaries[i]->HasPseudoWhere())
-    ++i;
+  while (!selector_boundaries[begin]->HasPseudoIs() &&
+         !selector_boundaries[begin]->HasPseudoWhere())
+    ++begin;
 
-  const CSSSelector* selector_to_expand_begin = selector_boundaries[i];
-  const CSSSelector* selector_to_expand_end = selector_boundaries[i + 1];
+  const CSSSelector* selector_to_expand_begin = selector_boundaries[begin];
+  const CSSSelector* selector_to_expand_end = selector_boundaries[begin + 1];
   unsigned selector_to_expand_length =
       static_cast<unsigned>(selector_to_expand_end - selector_to_expand_begin);
 
diff --git a/third_party/blink/renderer/core/css/css_value.cc b/third_party/blink/renderer/core/css/css_value.cc
index 081b3ae1..d53f204b 100644
--- a/third_party/blink/renderer/core/css/css_value.cc
+++ b/third_party/blink/renderer/core/css/css_value.cc
@@ -108,11 +108,11 @@
   if (IsValueList())
     return ToCSSValueList(this)->HasFailedOrCanceledSubresources();
   if (GetClassType() == kFontFaceSrcClass)
-    return ToCSSFontFaceSrcValue(this)->HasFailedOrCanceledSubresources();
+    return To<CSSFontFaceSrcValue>(this)->HasFailedOrCanceledSubresources();
   if (GetClassType() == kImageClass)
     return ToCSSImageValue(this)->HasFailedOrCanceledSubresources();
   if (GetClassType() == kCrossfadeClass)
-    return ToCSSCrossfadeValue(this)->HasFailedOrCanceledSubresources();
+    return To<CSSCrossfadeValue>(this)->HasFailedOrCanceledSubresources();
   if (GetClassType() == kImageSetClass)
     return ToCSSImageSetValue(this)->HasFailedOrCanceledSubresources();
 
@@ -262,49 +262,49 @@
 String CSSValue::CssText() const {
   switch (GetClassType()) {
     case kAxisClass:
-      return ToCSSAxisValue(this)->CustomCSSText();
+      return To<CSSAxisValue>(this)->CustomCSSText();
     case kBasicShapeCircleClass:
-      return ToCSSBasicShapeCircleValue(this)->CustomCSSText();
+      return To<CSSBasicShapeCircleValue>(this)->CustomCSSText();
     case kBasicShapeEllipseClass:
-      return ToCSSBasicShapeEllipseValue(this)->CustomCSSText();
+      return To<CSSBasicShapeEllipseValue>(this)->CustomCSSText();
     case kBasicShapePolygonClass:
-      return ToCSSBasicShapePolygonValue(this)->CustomCSSText();
+      return To<CSSBasicShapePolygonValue>(this)->CustomCSSText();
     case kBasicShapeInsetClass:
-      return ToCSSBasicShapeInsetValue(this)->CustomCSSText();
+      return To<CSSBasicShapeInsetValue>(this)->CustomCSSText();
     case kBorderImageSliceClass:
-      return ToCSSBorderImageSliceValue(this)->CustomCSSText();
+      return To<CSSBorderImageSliceValue>(this)->CustomCSSText();
     case kColorClass:
-      return ToCSSColorValue(this)->CustomCSSText();
+      return To<CSSColorValue>(this)->CustomCSSText();
     case kCounterClass:
-      return ToCSSCounterValue(this)->CustomCSSText();
+      return To<CSSCounterValue>(this)->CustomCSSText();
     case kCursorImageClass:
-      return ToCSSCursorImageValue(this)->CustomCSSText();
+      return To<CSSCursorImageValue>(this)->CustomCSSText();
     case kFontFaceSrcClass:
-      return ToCSSFontFaceSrcValue(this)->CustomCSSText();
+      return To<CSSFontFaceSrcValue>(this)->CustomCSSText();
     case kFontFamilyClass:
-      return ToCSSFontFamilyValue(this)->CustomCSSText();
+      return To<CSSFontFamilyValue>(this)->CustomCSSText();
     case kFontFeatureClass:
-      return ToCSSFontFeatureValue(this)->CustomCSSText();
+      return To<CSSFontFeatureValue>(this)->CustomCSSText();
     case kFontStyleRangeClass:
-      return ToCSSFontStyleRangeValue(this)->CustomCSSText();
+      return To<CSSFontStyleRangeValue>(this)->CustomCSSText();
     case kFontVariationClass:
-      return ToCSSFontVariationValue(this)->CustomCSSText();
+      return To<CSSFontVariationValue>(this)->CustomCSSText();
     case kFunctionClass:
-      return ToCSSFunctionValue(this)->CustomCSSText();
+      return To<CSSFunctionValue>(this)->CustomCSSText();
     case kLayoutFunctionClass:
       return ToCSSLayoutFunctionValue(this)->CustomCSSText();
     case kLinearGradientClass:
-      return ToCSSLinearGradientValue(this)->CustomCSSText();
+      return To<CSSLinearGradientValue>(this)->CustomCSSText();
     case kRadialGradientClass:
-      return ToCSSRadialGradientValue(this)->CustomCSSText();
+      return To<CSSRadialGradientValue>(this)->CustomCSSText();
     case kConicGradientClass:
-      return ToCSSConicGradientValue(this)->CustomCSSText();
+      return To<CSSConicGradientValue>(this)->CustomCSSText();
     case kCrossfadeClass:
-      return ToCSSCrossfadeValue(this)->CustomCSSText();
+      return To<CSSCrossfadeValue>(this)->CustomCSSText();
     case kPaintClass:
       return ToCSSPaintValue(this)->CustomCSSText();
     case kCustomIdentClass:
-      return ToCSSCustomIdentValue(this)->CustomCSSText();
+      return To<CSSCustomIdentValue>(this)->CustomCSSText();
     case kImageClass:
       return ToCSSImageValue(this)->CustomCSSText();
     case kInheritedClass:
@@ -352,11 +352,11 @@
     case kImageSetClass:
       return ToCSSImageSetValue(this)->CustomCSSText();
     case kCSSContentDistributionClass:
-      return ToCSSContentDistributionValue(this)->CustomCSSText();
+      return To<CSSContentDistributionValue>(this)->CustomCSSText();
     case kVariableReferenceClass:
       return ToCSSVariableReferenceValue(this)->CustomCSSText();
     case kCustomPropertyDeclarationClass:
-      return ToCSSCustomPropertyDeclaration(this)->CustomCSSText();
+      return To<CSSCustomPropertyDeclaration>(this)->CustomCSSText();
     case kPendingSubstitutionValueClass:
       return ToCSSPendingSubstitutionValue(this)->CustomCSSText();
     case kInvalidVariableValueClass:
@@ -369,70 +369,70 @@
 void CSSValue::FinalizeGarbageCollectedObject() {
   switch (GetClassType()) {
     case kAxisClass:
-      ToCSSAxisValue(this)->~CSSAxisValue();
+      To<CSSAxisValue>(this)->~CSSAxisValue();
       return;
     case kBasicShapeCircleClass:
-      ToCSSBasicShapeCircleValue(this)->~CSSBasicShapeCircleValue();
+      To<CSSBasicShapeCircleValue>(this)->~CSSBasicShapeCircleValue();
       return;
     case kBasicShapeEllipseClass:
-      ToCSSBasicShapeEllipseValue(this)->~CSSBasicShapeEllipseValue();
+      To<CSSBasicShapeEllipseValue>(this)->~CSSBasicShapeEllipseValue();
       return;
     case kBasicShapePolygonClass:
-      ToCSSBasicShapePolygonValue(this)->~CSSBasicShapePolygonValue();
+      To<CSSBasicShapePolygonValue>(this)->~CSSBasicShapePolygonValue();
       return;
     case kBasicShapeInsetClass:
-      ToCSSBasicShapeInsetValue(this)->~CSSBasicShapeInsetValue();
+      To<CSSBasicShapeInsetValue>(this)->~CSSBasicShapeInsetValue();
       return;
     case kBorderImageSliceClass:
-      ToCSSBorderImageSliceValue(this)->~CSSBorderImageSliceValue();
+      To<CSSBorderImageSliceValue>(this)->~CSSBorderImageSliceValue();
       return;
     case kColorClass:
-      ToCSSColorValue(this)->~CSSColorValue();
+      To<CSSColorValue>(this)->~CSSColorValue();
       return;
     case kCounterClass:
-      ToCSSCounterValue(this)->~CSSCounterValue();
+      To<CSSCounterValue>(this)->~CSSCounterValue();
       return;
     case kCursorImageClass:
-      ToCSSCursorImageValue(this)->~CSSCursorImageValue();
+      To<CSSCursorImageValue>(this)->~CSSCursorImageValue();
       return;
     case kFontFaceSrcClass:
-      ToCSSFontFaceSrcValue(this)->~CSSFontFaceSrcValue();
+      To<CSSFontFaceSrcValue>(this)->~CSSFontFaceSrcValue();
       return;
     case kFontFamilyClass:
-      ToCSSFontFamilyValue(this)->~CSSFontFamilyValue();
+      To<CSSFontFamilyValue>(this)->~CSSFontFamilyValue();
       return;
     case kFontFeatureClass:
-      ToCSSFontFeatureValue(this)->~CSSFontFeatureValue();
+      To<CSSFontFeatureValue>(this)->~CSSFontFeatureValue();
       return;
     case kFontStyleRangeClass:
-      ToCSSFontStyleRangeValue(this)->~CSSFontStyleRangeValue();
+      To<CSSFontStyleRangeValue>(this)->~CSSFontStyleRangeValue();
       return;
     case kFontVariationClass:
-      ToCSSFontVariationValue(this)->~CSSFontVariationValue();
+      To<CSSFontVariationValue>(this)->~CSSFontVariationValue();
       return;
     case kFunctionClass:
-      ToCSSFunctionValue(this)->~CSSFunctionValue();
+      To<CSSFunctionValue>(this)->~CSSFunctionValue();
       return;
     case kLayoutFunctionClass:
       ToCSSLayoutFunctionValue(this)->~CSSLayoutFunctionValue();
       return;
     case kLinearGradientClass:
-      ToCSSLinearGradientValue(this)->~CSSLinearGradientValue();
+      To<CSSLinearGradientValue>(this)->~CSSLinearGradientValue();
       return;
     case kRadialGradientClass:
-      ToCSSRadialGradientValue(this)->~CSSRadialGradientValue();
+      To<CSSRadialGradientValue>(this)->~CSSRadialGradientValue();
       return;
     case kConicGradientClass:
-      ToCSSConicGradientValue(this)->~CSSConicGradientValue();
+      To<CSSConicGradientValue>(this)->~CSSConicGradientValue();
       return;
     case kCrossfadeClass:
-      ToCSSCrossfadeValue(this)->~CSSCrossfadeValue();
+      To<CSSCrossfadeValue>(this)->~CSSCrossfadeValue();
       return;
     case kPaintClass:
       ToCSSPaintValue(this)->~CSSPaintValue();
       return;
     case kCustomIdentClass:
-      ToCSSCustomIdentValue(this)->~CSSCustomIdentValue();
+      To<CSSCustomIdentValue>(this)->~CSSCustomIdentValue();
       return;
     case kImageClass:
       ToCSSImageValue(this)->~CSSImageValue();
@@ -505,13 +505,13 @@
       ToCSSImageSetValue(this)->~CSSImageSetValue();
       return;
     case kCSSContentDistributionClass:
-      ToCSSContentDistributionValue(this)->~CSSContentDistributionValue();
+      To<CSSContentDistributionValue>(this)->~CSSContentDistributionValue();
       return;
     case kVariableReferenceClass:
       ToCSSVariableReferenceValue(this)->~CSSVariableReferenceValue();
       return;
     case kCustomPropertyDeclarationClass:
-      ToCSSCustomPropertyDeclaration(this)->~CSSCustomPropertyDeclaration();
+      To<CSSCustomPropertyDeclaration>(this)->~CSSCustomPropertyDeclaration();
       return;
     case kPendingSubstitutionValueClass:
       ToCSSPendingSubstitutionValue(this)->~CSSPendingSubstitutionValue();
@@ -526,70 +526,70 @@
 void CSSValue::Trace(blink::Visitor* visitor) {
   switch (GetClassType()) {
     case kAxisClass:
-      ToCSSAxisValue(this)->TraceAfterDispatch(visitor);
+      To<CSSAxisValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kBasicShapeCircleClass:
-      ToCSSBasicShapeCircleValue(this)->TraceAfterDispatch(visitor);
+      To<CSSBasicShapeCircleValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kBasicShapeEllipseClass:
-      ToCSSBasicShapeEllipseValue(this)->TraceAfterDispatch(visitor);
+      To<CSSBasicShapeEllipseValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kBasicShapePolygonClass:
-      ToCSSBasicShapePolygonValue(this)->TraceAfterDispatch(visitor);
+      To<CSSBasicShapePolygonValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kBasicShapeInsetClass:
-      ToCSSBasicShapeInsetValue(this)->TraceAfterDispatch(visitor);
+      To<CSSBasicShapeInsetValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kBorderImageSliceClass:
-      ToCSSBorderImageSliceValue(this)->TraceAfterDispatch(visitor);
+      To<CSSBorderImageSliceValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kColorClass:
-      ToCSSColorValue(this)->TraceAfterDispatch(visitor);
+      To<CSSColorValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kCounterClass:
-      ToCSSCounterValue(this)->TraceAfterDispatch(visitor);
+      To<CSSCounterValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kCursorImageClass:
-      ToCSSCursorImageValue(this)->TraceAfterDispatch(visitor);
+      To<CSSCursorImageValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kFontFaceSrcClass:
-      ToCSSFontFaceSrcValue(this)->TraceAfterDispatch(visitor);
+      To<CSSFontFaceSrcValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kFontFamilyClass:
-      ToCSSFontFamilyValue(this)->TraceAfterDispatch(visitor);
+      To<CSSFontFamilyValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kFontFeatureClass:
-      ToCSSFontFeatureValue(this)->TraceAfterDispatch(visitor);
+      To<CSSFontFeatureValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kFontStyleRangeClass:
-      ToCSSFontStyleRangeValue(this)->TraceAfterDispatch(visitor);
+      To<CSSFontStyleRangeValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kFontVariationClass:
-      ToCSSFontVariationValue(this)->TraceAfterDispatch(visitor);
+      To<CSSFontVariationValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kFunctionClass:
-      ToCSSFunctionValue(this)->TraceAfterDispatch(visitor);
+      To<CSSFunctionValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kLayoutFunctionClass:
       ToCSSLayoutFunctionValue(this)->TraceAfterDispatch(visitor);
       return;
     case kLinearGradientClass:
-      ToCSSLinearGradientValue(this)->TraceAfterDispatch(visitor);
+      To<CSSLinearGradientValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kRadialGradientClass:
-      ToCSSRadialGradientValue(this)->TraceAfterDispatch(visitor);
+      To<CSSRadialGradientValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kConicGradientClass:
-      ToCSSConicGradientValue(this)->TraceAfterDispatch(visitor);
+      To<CSSConicGradientValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kCrossfadeClass:
-      ToCSSCrossfadeValue(this)->TraceAfterDispatch(visitor);
+      To<CSSCrossfadeValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kPaintClass:
       ToCSSPaintValue(this)->TraceAfterDispatch(visitor);
       return;
     case kCustomIdentClass:
-      ToCSSCustomIdentValue(this)->TraceAfterDispatch(visitor);
+      To<CSSCustomIdentValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kImageClass:
       ToCSSImageValue(this)->TraceAfterDispatch(visitor);
@@ -661,13 +661,13 @@
       ToCSSImageSetValue(this)->TraceAfterDispatch(visitor);
       return;
     case kCSSContentDistributionClass:
-      ToCSSContentDistributionValue(this)->TraceAfterDispatch(visitor);
+      To<CSSContentDistributionValue>(this)->TraceAfterDispatch(visitor);
       return;
     case kVariableReferenceClass:
       ToCSSVariableReferenceValue(this)->TraceAfterDispatch(visitor);
       return;
     case kCustomPropertyDeclarationClass:
-      ToCSSCustomPropertyDeclaration(this)->TraceAfterDispatch(visitor);
+      To<CSSCustomPropertyDeclaration>(this)->TraceAfterDispatch(visitor);
       return;
     case kPendingSubstitutionValueClass:
       ToCSSPendingSubstitutionValue(this)->TraceAfterDispatch(visitor);
diff --git a/third_party/blink/renderer/core/css/cssom/css_keyword_value.cc b/third_party/blink/renderer/core/css/cssom/css_keyword_value.cc
index a1de447..5fc850c54 100644
--- a/third_party/blink/renderer/core/css/cssom/css_keyword_value.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_keyword_value.cc
@@ -36,14 +36,13 @@
     return MakeGarbageCollected<CSSKeywordValue>(
         getValueName(ToCSSIdentifierValue(value).GetValueID()));
   }
-  if (value.IsCustomIdentValue()) {
-    const CSSCustomIdentValue& ident_value = ToCSSCustomIdentValue(value);
-    if (ident_value.IsKnownPropertyID()) {
+  if (const auto* ident_value = DynamicTo<CSSCustomIdentValue>(value)) {
+    if (ident_value->IsKnownPropertyID()) {
       // CSSPropertyID represents the LHS of a CSS declaration, and
       // CSSKeywordValue represents a RHS.
       return nullptr;
     }
-    return MakeGarbageCollected<CSSKeywordValue>(ident_value.Value());
+    return MakeGarbageCollected<CSSKeywordValue>(ident_value->Value());
   }
   NOTREACHED();
   return nullptr;
diff --git a/third_party/blink/renderer/core/css/cssom/css_transform_component.cc b/third_party/blink/renderer/core/css/cssom/css_transform_component.cc
index 0ae130af..da8b16c 100644
--- a/third_party/blink/renderer/core/css/cssom/css_transform_component.cc
+++ b/third_party/blink/renderer/core/css/cssom/css_transform_component.cc
@@ -17,40 +17,40 @@
 
 CSSTransformComponent* CSSTransformComponent::FromCSSValue(
     const CSSValue& value) {
-  if (!value.IsFunctionValue())
+  const auto* function_value = DynamicTo<CSSFunctionValue>(value);
+  if (!function_value)
     return nullptr;
 
-  const CSSFunctionValue& function_value = ToCSSFunctionValue(value);
-  switch (function_value.FunctionType()) {
+  switch (function_value->FunctionType()) {
     case CSSValueMatrix:
     case CSSValueMatrix3d:
-      return CSSMatrixComponent::FromCSSValue(function_value);
+      return CSSMatrixComponent::FromCSSValue(*function_value);
     case CSSValuePerspective:
-      return CSSPerspective::FromCSSValue(function_value);
+      return CSSPerspective::FromCSSValue(*function_value);
     case CSSValueRotate:
     case CSSValueRotateX:
     case CSSValueRotateY:
     case CSSValueRotateZ:
     case CSSValueRotate3d:
-      return CSSRotate::FromCSSValue(function_value);
+      return CSSRotate::FromCSSValue(*function_value);
     case CSSValueScale:
     case CSSValueScaleX:
     case CSSValueScaleY:
     case CSSValueScaleZ:
     case CSSValueScale3d:
-      return CSSScale::FromCSSValue(function_value);
+      return CSSScale::FromCSSValue(*function_value);
     case CSSValueSkew:
-      return CSSSkew::FromCSSValue(function_value);
+      return CSSSkew::FromCSSValue(*function_value);
     case CSSValueSkewX:
-      return CSSSkewX::FromCSSValue(function_value);
+      return CSSSkewX::FromCSSValue(*function_value);
     case CSSValueSkewY:
-      return CSSSkewY::FromCSSValue(function_value);
+      return CSSSkewY::FromCSSValue(*function_value);
     case CSSValueTranslate:
     case CSSValueTranslateX:
     case CSSValueTranslateY:
     case CSSValueTranslateZ:
     case CSSValueTranslate3d:
-      return CSSTranslate::FromCSSValue(function_value);
+      return CSSTranslate::FromCSSValue(*function_value);
     default:
       return nullptr;
   }
diff --git a/third_party/blink/renderer/core/css/cssom/style_value_factory.cc b/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
index 73d9f24f..939d4d2 100644
--- a/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
+++ b/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
@@ -39,9 +39,9 @@
     return CSSKeywordValue::FromCSSValue(value);
   if (value.IsVariableReferenceValue())
     return CSSUnparsedValue::FromCSSValue(ToCSSVariableReferenceValue(value));
-  if (value.IsCustomPropertyDeclaration()) {
-    return CSSUnparsedValue::FromCSSValue(
-        ToCSSCustomPropertyDeclaration(value));
+  if (auto* custom_prop_declaration =
+          DynamicTo<CSSCustomPropertyDeclaration>(value)) {
+    return CSSUnparsedValue::FromCSSValue(*custom_prop_declaration);
   }
   return nullptr;
 }
diff --git a/third_party/blink/renderer/core/css/font_face.cc b/third_party/blink/renderer/core/css/font_face.cc
index f983d2b6..044b297 100644
--- a/third_party/blink/renderer/core/css/font_face.cc
+++ b/third_party/blink/renderer/core/css/font_face.cc
@@ -352,15 +352,15 @@
   return true;
 }
 
-bool FontFace::SetFamilyValue(const CSSValue& family_value) {
+bool FontFace::SetFamilyValue(const CSSValue& value) {
   AtomicString family;
-  if (family_value.IsFontFamilyValue()) {
-    family = AtomicString(ToCSSFontFamilyValue(family_value).Value());
-  } else if (family_value.IsIdentifierValue()) {
+  if (auto* family_value = DynamicTo<CSSFontFamilyValue>(value)) {
+    family = AtomicString(family_value->Value());
+  } else if (value.IsIdentifierValue()) {
     // We need to use the raw text for all the generic family types, since
     // @font-face is a way of actually defining what font to use for those
     // types.
-    switch (ToCSSIdentifierValue(family_value).GetValueID()) {
+    switch (ToCSSIdentifierValue(value).GetValueID()) {
       case CSSValueSerif:
         family = font_family_names::kWebkitSerif;
         break;
@@ -578,9 +578,8 @@
         default:
           break;
       }
-    } else if (style_->IsFontStyleRangeValue()) {
-      const cssvalue::CSSFontStyleRangeValue* range_value =
-          cssvalue::ToCSSFontStyleRangeValue(style_);
+    } else if (const auto* range_value =
+                   DynamicTo<cssvalue::CSSFontStyleRangeValue>(style_.Get())) {
       if (range_value->GetFontStyleValue()->IsIdentifierValue()) {
         CSSValueID font_style_id =
             range_value->GetFontStyleValue()->GetValueID();
@@ -701,7 +700,7 @@
   for (int i = 0; i < src_length; i++) {
     // An item in the list either specifies a string (local font name) or a URL
     // (remote font to download).
-    const CSSFontFaceSrcValue& item = ToCSSFontFaceSrcValue(src_list.Item(i));
+    const CSSFontFaceSrcValue& item = To<CSSFontFaceSrcValue>(src_list.Item(i));
 
     if (!item.IsLocal()) {
       if (ContextAllowsDownload(context) && item.IsSupportedFormat()) {
diff --git a/third_party/blink/renderer/core/css/parser/css_parser.cc b/third_party/blink/renderer/core/css/parser/css_parser.cc
index 99112138..c14a5f49 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser.cc
@@ -240,9 +240,11 @@
         StrictCSSParserContext(SecureContextMode::kInsecureContext));
   }
 
-  if (!value || !value->IsColorValue())
+  auto* color_value = DynamicTo<CSSColorValue>(value);
+  if (!color_value)
     return false;
-  color = ToCSSColorValue(*value).Value();
+
+  color = color_value->Value();
   return true;
 }
 
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_test.cc b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_test.cc
index de6ef40a3..90dfdaae 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_test.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths_test.cc
@@ -115,7 +115,7 @@
                                                    kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 }
 
 TEST(CSSParserFastPathsTest, ParseColorWithNewSyntax) {
@@ -123,27 +123,27 @@
       CSSParserFastPaths::ParseColor("rgba(0 0 0)", kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 
   value = CSSParserFastPaths::ParseColor("rgba(0 0 0 / 1)", kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 
   value = CSSParserFastPaths::ParseColor("rgba(0, 0, 0, 1)", kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 
   value = CSSParserFastPaths::ParseColor("RGBA(0 0 0 / 1)", kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 
   value = CSSParserFastPaths::ParseColor("RGB(0 0 0 / 1)", kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 
   value = CSSParserFastPaths::ParseColor("rgba(0 0 0 0)", kHTMLStandardMode);
   EXPECT_EQ(nullptr, value);
@@ -164,25 +164,25 @@
                                                    kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 
   value =
       CSSParserFastPaths::ParseColor("rgb(0.0, 0.0, 0.0)", kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 
   value =
       CSSParserFastPaths::ParseColor("rgb(0.0 , 0.0,0.0)", kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kBlack, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<CSSColorValue>(*value).Value());
 
   value = CSSParserFastPaths::ParseColor("rgb(254.5, 254.5, 254.5)",
                                          kHTMLStandardMode);
   EXPECT_NE(nullptr, value);
   EXPECT_TRUE(value->IsColorValue());
-  EXPECT_EQ(Color::kWhite, ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kWhite, To<CSSColorValue>(*value).Value());
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
index 1dcd1a1..f8389b1 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -109,8 +109,8 @@
   bool did_parse = false;
   bool did_change = false;
   if (!parser.parsed_properties_.IsEmpty()) {
-    const CSSCustomPropertyDeclaration* parsed_declaration =
-        ToCSSCustomPropertyDeclaration(parser.parsed_properties_[0].Value());
+    const auto* parsed_declaration =
+        To<CSSCustomPropertyDeclaration>(parser.parsed_properties_[0].Value());
     if (parsed_declaration->Value() && registry) {
       const PropertyRegistration* registration =
           registry->Registration(property_name);
@@ -144,7 +144,7 @@
 
     if (property.Id() == CSSPropertyVariable) {
       const AtomicString& name =
-          ToCSSCustomPropertyDeclaration(property.Value())->GetName();
+          To<CSSCustomPropertyDeclaration>(property.Value())->GetName();
       if (seen_custom_properties.Contains(name))
         continue;
       seen_custom_properties.insert(name);
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc b/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
index 34d072e0..241e783 100644
--- a/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
+++ b/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
@@ -319,7 +319,7 @@
       CSSPropertyBackgroundColor, "rgba(0, 0, 0, 1)",
       StrictCSSParserContext(SecureContextMode::kSecureContext));
   ASSERT_TRUE(value);
-  EXPECT_EQ(Color::kBlack, cssvalue::ToCSSColorValue(*value).Value());
+  EXPECT_EQ(Color::kBlack, To<cssvalue::CSSColorValue>(*value).Value());
 }
 
 TEST(CSSPropertyParserTest, IncompleteColor) {
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index 475b3a6e..599453409 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -1624,8 +1624,7 @@
   if (value.IsPrimitiveValue() || value.IsIdentifierValue())
     return IsGridBreadthFixedSized(value);
 
-  DCHECK(value.IsFunctionValue());
-  auto& function = ToCSSFunctionValue(value);
+  auto& function = To<CSSFunctionValue>(value);
   if (function.FunctionType() == CSSValueFitContent)
     return false;
 
@@ -2291,12 +2290,14 @@
                   CSSParserTokenRange& range,
                   CSSParserMode css_parser_mode,
                   bool use_legacy_parsing) {
-  unsigned i = 0;
-  for (; i < 4 && !range.AtEnd() && range.Peek().GetType() != kDelimiterToken;
-       ++i) {
-    horizontal_radii[i] = css_property_parser_helpers::ConsumeLengthOrPercent(
-        range, css_parser_mode, kValueRangeNonNegative);
-    if (!horizontal_radii[i])
+  unsigned horizontal_value_count = 0;
+  for (; horizontal_value_count < 4 && !range.AtEnd() &&
+         range.Peek().GetType() != kDelimiterToken;
+       ++horizontal_value_count) {
+    horizontal_radii[horizontal_value_count] =
+        css_property_parser_helpers::ConsumeLengthOrPercent(
+            range, css_parser_mode, kValueRangeNonNegative);
+    if (!horizontal_radii[horizontal_value_count])
       return false;
   }
   if (!horizontal_radii[0])
@@ -2304,7 +2305,7 @@
   if (range.AtEnd()) {
     // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to
     // border-radius: l1 / l2;
-    if (use_legacy_parsing && i == 2) {
+    if (use_legacy_parsing && horizontal_value_count == 2) {
       vertical_radii[0] = horizontal_radii[1];
       horizontal_radii[1] = nullptr;
     } else {
@@ -2316,7 +2317,7 @@
   } else {
     if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
       return false;
-    for (i = 0; i < 4 && !range.AtEnd(); ++i) {
+    for (unsigned i = 0; i < 4 && !range.AtEnd(); ++i) {
       vertical_radii[i] = css_property_parser_helpers::ConsumeLengthOrPercent(
           range, css_parser_mode, kValueRangeNonNegative);
       if (!vertical_radii[i])
diff --git a/third_party/blink/renderer/core/css/properties/longhands/contain_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/contain_custom.cc
index b6fab7d..cfcbfe0a 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/contain_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/contain_custom.cc
@@ -31,7 +31,7 @@
   CSSIdentifierValue* style = nullptr;
   CSSIdentifierValue* paint = nullptr;
   while (true) {
-    CSSValueID id = range.Peek().Id();
+    id = range.Peek().Id();
     if (id == CSSValueSize && !size)
       size = css_property_parser_helpers::ConsumeIdent(range);
     else if (id == CSSValueLayout && !layout)
diff --git a/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc
index ee8e477a..6791af22 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc
@@ -148,9 +148,8 @@
         item->IsImageValue()) {
       next_content =
           ContentData::Create(state.GetStyleImage(CSSPropertyContent, *item));
-    } else if (item->IsCounterValue()) {
-      const cssvalue::CSSCounterValue* counter_value =
-          cssvalue::ToCSSCounterValue(item.Get());
+    } else if (const auto* counter_value =
+                   DynamicTo<cssvalue::CSSCounterValue>(item.Get())) {
       const auto list_style_type =
           CssValueIDToPlatformEnum<EListStyleType>(counter_value->ListStyle());
       std::unique_ptr<CounterContent> counter =
@@ -180,16 +179,17 @@
       next_content = ContentData::Create(quote_type);
     } else {
       String string;
-      if (item->IsFunctionValue()) {
-        const CSSFunctionValue* function_value = ToCSSFunctionValue(item.Get());
+      if (const auto* function_value =
+              DynamicTo<CSSFunctionValue>(item.Get())) {
         DCHECK_EQ(function_value->FunctionType(), CSSValueAttr);
         state.Style()->SetHasAttrContent();
         // TODO: Can a namespace be specified for an attr(foo)?
         QualifiedName attr(
-            g_null_atom, ToCSSCustomIdentValue(function_value->Item(0)).Value(),
+            g_null_atom,
+            To<CSSCustomIdentValue>(function_value->Item(0)).Value(),
             g_null_atom);
-        const AtomicString& value = state.GetElement()->getAttribute(attr);
-        string = value.IsNull() ? g_empty_string : value.GetString();
+        const AtomicString& attr_value = state.GetElement()->getAttribute(attr);
+        string = attr_value.IsNull() ? g_empty_string : attr_value.GetString();
       } else {
         string = ToCSSStringValue(*item).Value();
       }
diff --git a/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc
index 4b93b78a..2a15e4a 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc
@@ -116,12 +116,11 @@
   if (value.IsValueList()) {
     state.Style()->SetCursor(ECursor::kAuto);
     for (const auto& item : ToCSSValueList(value)) {
-      if (item->IsCursorImageValue()) {
-        const cssvalue::CSSCursorImageValue& cursor =
-            cssvalue::ToCSSCursorImageValue(*item);
-        const CSSValue& image = cursor.ImageValue();
+      if (const auto* cursor =
+              DynamicTo<cssvalue::CSSCursorImageValue>(*item)) {
+        const CSSValue& image = cursor->ImageValue();
         state.Style()->AddCursor(state.GetStyleImage(CSSPropertyCursor, image),
-                                 cursor.HotSpotSpecified(), cursor.HotSpot());
+                                 cursor->HotSpotSpecified(), cursor->HotSpot());
       } else {
         state.Style()->SetCursor(
             ToCSSIdentifierValue(*item).ConvertTo<ECursor>());
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc b/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
index d68af9e..31785246 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
@@ -62,8 +62,7 @@
 
 void CustomProperty::ApplyValue(StyleResolverState& state,
                                 const CSSValue& value) const {
-  const CSSCustomPropertyDeclaration& declaration =
-      ToCSSCustomPropertyDeclaration(value);
+  const auto& declaration = To<CSSCustomPropertyDeclaration>(value);
 
   bool is_inherited_property = IsInherited();
   bool initial = declaration.IsInitial(is_inherited_property);
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc b/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
index af4ec4c..4833ae7 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
@@ -153,9 +153,9 @@
       property, "100px", CSSParserLocalContext().WithAnimationTainted(false));
 
   EXPECT_TRUE(
-      ToCSSCustomPropertyDeclaration(value1)->Value()->IsAnimationTainted());
+      To<CSSCustomPropertyDeclaration>(value1)->Value()->IsAnimationTainted());
   EXPECT_FALSE(
-      ToCSSCustomPropertyDeclaration(value2)->Value()->IsAnimationTainted());
+      To<CSSCustomPropertyDeclaration>(value2)->Value()->IsAnimationTainted());
 }
 
 TEST_F(CustomPropertyTest, ParseSingleValueTyped) {
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc
index 6468e778..3ce6efc 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc
@@ -102,12 +102,16 @@
     const CSSValueList& list = ToCSSValueList(value);
     DCHECK_EQ(list.length(), 2U);
     for (unsigned i = 0; i < 2; ++i) {
-      const CSSIdentifierValue& value = ToCSSIdentifierValue(list.Item(i));
-      if (value.GetValueID() == CSSValueFilled ||
-          value.GetValueID() == CSSValueOpen)
-        state.Style()->SetTextEmphasisFill(value.ConvertTo<TextEmphasisFill>());
-      else
-        state.Style()->SetTextEmphasisMark(value.ConvertTo<TextEmphasisMark>());
+      const CSSIdentifierValue& ident_value =
+          ToCSSIdentifierValue(list.Item(i));
+      if (ident_value.GetValueID() == CSSValueFilled ||
+          ident_value.GetValueID() == CSSValueOpen) {
+        state.Style()->SetTextEmphasisFill(
+            ident_value.ConvertTo<TextEmphasisFill>());
+      } else {
+        state.Style()->SetTextEmphasisMark(
+            ident_value.ConvertTo<TextEmphasisMark>());
+      }
     }
     state.Style()->SetTextEmphasisCustomMark(g_null_atom);
     return;
diff --git a/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc
index aefee07..bdf7b51 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc
@@ -111,9 +111,9 @@
   } else {
     DCHECK(value.IsValueList());
     for (auto& will_change_value : ToCSSValueList(value)) {
-      if (will_change_value->IsCustomIdentValue()) {
-        will_change_properties.push_back(
-            ToCSSCustomIdentValue(*will_change_value).ValueAsPropertyID());
+      if (auto* ident_value =
+              DynamicTo<CSSCustomIdentValue>(will_change_value.Get())) {
+        will_change_properties.push_back(ident_value->ValueAsPropertyID());
       } else if (ToCSSIdentifierValue(*will_change_value).GetValueID() ==
                  CSSValueContents) {
         will_change_contents = true;
diff --git a/third_party/blink/renderer/core/css/property_registry.cc b/third_party/blink/renderer/core/css/property_registry.cc
index 8bc06920..d74c6c2 100644
--- a/third_party/blink/renderer/core/css/property_registry.cc
+++ b/third_party/blink/renderer/core/css/property_registry.cc
@@ -32,7 +32,9 @@
     const Document& document,
     const AtomicString& property_name,
     const CSSValue* value) {
-  if (!value || !value->IsCustomPropertyDeclaration())
+  auto* custom_property_declaration =
+      DynamicTo<CSSCustomPropertyDeclaration>(value);
+  if (!custom_property_declaration)
     return value;
 
   const PropertyRegistry* registry = document.GetPropertyRegistry();
@@ -46,7 +48,7 @@
   if (!registration)
     return value;
 
-  CSSVariableData* tokens = ToCSSCustomPropertyDeclaration(value)->Value();
+  CSSVariableData* tokens = custom_property_declaration->Value();
 
   if (!tokens || tokens->NeedsVariableResolution())
     return value;
diff --git a/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc b/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
index d5874ad..31bdf1c 100644
--- a/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
+++ b/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
@@ -376,8 +376,8 @@
 AtomicString CSSToStyleMap::MapAnimationName(const CSSValue& value) {
   if (value.IsInitialValue())
     return CSSAnimationData::InitialName();
-  if (value.IsCustomIdentValue())
-    return AtomicString(ToCSSCustomIdentValue(value).Value());
+  if (auto* custom_ident_value = DynamicTo<CSSCustomIdentValue>(value))
+    return AtomicString(custom_ident_value->Value());
   DCHECK_EQ(ToCSSIdentifierValue(value).GetValueID(), CSSValueNone);
   return CSSAnimationData::InitialName();
 }
@@ -395,13 +395,12 @@
     const CSSValue& value) {
   if (value.IsInitialValue())
     return CSSTransitionData::InitialProperty();
-  if (value.IsCustomIdentValue()) {
-    const CSSCustomIdentValue& custom_ident_value =
-        ToCSSCustomIdentValue(value);
-    if (custom_ident_value.IsKnownPropertyID())
+  if (const auto* custom_ident_value = DynamicTo<CSSCustomIdentValue>(value)) {
+    if (custom_ident_value->IsKnownPropertyID()) {
       return CSSTransitionData::TransitionProperty(
-          custom_ident_value.ValueAsPropertyID());
-    return CSSTransitionData::TransitionProperty(custom_ident_value.Value());
+          custom_ident_value->ValueAsPropertyID());
+    }
+    return CSSTransitionData::TransitionProperty(custom_ident_value->Value());
   }
   if (ToCSSIdentifierValue(value).GetValueID() == CSSValueAll)
     return CSSTransitionData::InitialProperty();
@@ -551,12 +550,12 @@
 void CSSToStyleMap::MapNinePieceImageSlice(StyleResolverState&,
                                            const CSSValue& value,
                                            NinePieceImage& image) {
-  if (!value.IsBorderImageSliceValue())
+  if (!IsA<cssvalue::CSSBorderImageSliceValue>(value))
     return;
 
   // Retrieve the border image value.
-  const cssvalue::CSSBorderImageSliceValue& border_image_slice =
-      cssvalue::ToCSSBorderImageSliceValue(value);
+  const auto& border_image_slice =
+      To<cssvalue::CSSBorderImageSliceValue>(value);
 
   // Set up a length box to represent our image slices.
   LengthBox box;
diff --git a/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc b/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc
index 42139d63..32a0e78 100644
--- a/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc
@@ -120,12 +120,14 @@
   if (!ResolveTokenRange(range, options, result))
     return Fallback::kFail;
   if (registration) {
-    CSSParserTokenRange range(result.tokens);
-    range = range.MakeSubRange(&range.Peek(first_fallback_token), range.end());
+    CSSParserTokenRange resolved_range(result.tokens);
+    resolved_range = resolved_range.MakeSubRange(
+        &resolved_range.Peek(first_fallback_token), resolved_range.end());
     const CSSParserContext* context =
         StrictCSSParserContext(state_.GetDocument().GetSecureContextMode());
     const bool is_animation_tainted = false;
-    if (!registration->Syntax().Parse(range, context, is_animation_tainted))
+    if (!registration->Syntax().Parse(resolved_range, context,
+                                      is_animation_tainted))
       return Fallback::kFail;
   }
   return Fallback::kSuccess;
diff --git a/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc b/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc
index 82077dc..1fd10ad 100644
--- a/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc
@@ -179,7 +179,7 @@
       continue;
     }
 
-    const CSSFunctionValue* filter_value = ToCSSFunctionValue(curr_value.Get());
+    const auto* filter_value = To<CSSFunctionValue>(curr_value.Get());
     FilterOperation::OperationType operation_type =
         FilterOperationForType(filter_value->FunctionType());
     CountFilterUse(operation_type, state.GetDocument());
@@ -261,7 +261,7 @@
     if (curr_value->IsURIValue())
       continue;
 
-    const CSSFunctionValue* filter_value = ToCSSFunctionValue(curr_value.Get());
+    const auto* filter_value = To<CSSFunctionValue>(curr_value.Get());
     FilterOperation::OperationType operation_type =
         FilterOperationForType(filter_value->FunctionType());
     // TODO(fserb): Take an ExecutionContext argument to this function,
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index 41c23e1..5e62ee4 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -194,9 +194,9 @@
     AtomicString& family_name,
     FontBuilder* font_builder,
     const Document* document_for_count) {
-  if (value.IsFontFamilyValue()) {
+  if (auto* font_family_value = DynamicTo<CSSFontFamilyValue>(value)) {
     generic_family = FontDescription::kNoFamily;
-    family_name = AtomicString(ToCSSFontFamilyValue(value).Value());
+    family_name = AtomicString(font_family_value->Value());
 #if defined(OS_MACOSX)
     if (family_name == FontCache::LegacySystemFontFamily()) {
       UseCounter::Count(*document_for_count, WebFeature::kBlinkMacSystemFont);
@@ -267,8 +267,7 @@
   scoped_refptr<FontFeatureSettings> settings = FontFeatureSettings::Create();
   int len = list.length();
   for (int i = 0; i < len; ++i) {
-    const cssvalue::CSSFontFeatureValue& feature =
-        ToCSSFontFeatureValue(list.Item(i));
+    const auto& feature = To<CSSFontFeatureValue>(list.Item(i));
     settings->Append(FontFeature(feature.Tag(), feature.Value()));
   }
   return settings;
@@ -286,8 +285,7 @@
       FontVariationSettings::Create();
   int len = list.length();
   for (int i = 0; i < len; ++i) {
-    const CSSFontVariationValue& feature =
-        ToCSSFontVariationValue(list.Item(i));
+    const auto& feature = To<CSSFontVariationValue>(list.Item(i));
     settings->Append(FontVariationAxis(feature.Tag(), feature.Value()));
   }
   return settings;
@@ -419,17 +417,16 @@
         NOTREACHED();
         return NormalSlopeValue();
     }
-  } else if (value.IsFontStyleRangeValue()) {
-    const CSSFontStyleRangeValue& style_range_value =
-        ToCSSFontStyleRangeValue(value);
-    const CSSValueList* values = style_range_value.GetObliqueValues();
+  } else if (const auto* style_range_value =
+                 DynamicTo<CSSFontStyleRangeValue>(value)) {
+    const CSSValueList* values = style_range_value->GetObliqueValues();
     CHECK_LT(values->length(), 2u);
     if (values->length()) {
       return FontSelectionValue(
           ToCSSPrimitiveValue(values->Item(0)).ComputeDegrees());
     } else {
       const CSSIdentifierValue* identifier_value =
-          style_range_value.GetFontStyleValue();
+          style_range_value->GetFontStyleValue();
       if (identifier_value->GetValueID() == CSSValueNormal)
         return NormalSlopeValue();
       if (identifier_value->GetValueID() == CSSValueItalic ||
@@ -693,7 +690,7 @@
   StyleContentAlignmentData alignment_data =
       ComputedStyleInitialValues::InitialContentAlignment();
   const CSSContentDistributionValue& content_value =
-      ToCSSContentDistributionValue(value);
+      To<CSSContentDistributionValue>(value);
   if (content_value.Distribution() != CSSValueInvalid) {
     alignment_data.SetDistribution(
         CSSIdentifierValue::Create(content_value.Distribution())
@@ -749,8 +746,8 @@
 
   GridPosition position;
 
-  if (value.IsCustomIdentValue()) {
-    position.SetNamedGridArea(ToCSSCustomIdentValue(value).Value());
+  if (auto* ident_value = DynamicTo<CSSCustomIdentValue>(value)) {
+    position.SetNamedGridArea(ident_value->Value());
     return position;
   }
 
@@ -784,8 +781,9 @@
     current_value = it != values.end() ? it->Get() : nullptr;
   }
 
-  if (current_value && current_value->IsCustomIdentValue()) {
-    grid_line_name = ToCSSCustomIdentValue(current_value)->Value();
+  auto* current_ident_value = DynamicTo<CSSCustomIdentValue>(current_value);
+  if (current_ident_value) {
+    grid_line_name = current_ident_value->Value();
     ++it;
   }
 
@@ -804,7 +802,7 @@
   if (value.IsPrimitiveValue() || value.IsIdentifierValue())
     return GridTrackSize(ConvertGridTrackBreadth(state, value));
 
-  auto& function = ToCSSFunctionValue(value);
+  auto& function = To<CSSFunctionValue>(value);
   if (function.FunctionType() == CSSValueFitContent) {
     SECURITY_DCHECK(function.length() == 1);
     return GridTrackSize(ConvertGridTrackBreadth(state, function.Item(0)),
@@ -828,7 +826,7 @@
 
   for (auto& named_grid_line_value : ToCSSValueList(value)) {
     String named_grid_line =
-        ToCSSCustomIdentValue(*named_grid_line_value).Value();
+        To<CSSCustomIdentValue>(*named_grid_line_value).Value();
     NamedGridLinesMap::AddResult result =
         named_grid_lines.insert(named_grid_line, Vector<size_t>());
     result.stored_value->value.push_back(current_named_grid_line);
@@ -1252,8 +1250,8 @@
       // For OffScreen canvas, we default to black and only parse non
       // Document dependent CSS colors.
       color = StyleColor(Color::kBlack);
-      if (shadow.color->IsColorValue()) {
-        color = ToCSSColorValue(*shadow.color).Value();
+      if (auto* color_value = DynamicTo<CSSColorValue>(shadow.color.Get())) {
+        color = color_value->Value();
       } else {
         CSSValueID value_id = ToCSSIdentifierValue(*shadow.color).GetValueID();
         switch (value_id) {
@@ -1309,11 +1307,11 @@
   CSSBoxType css_box = CSSBoxType::kMissing;
   const CSSValueList& value_list = ToCSSValueList(value);
   for (unsigned i = 0; i < value_list.length(); ++i) {
-    const CSSValue& value = value_list.Item(i);
-    if (value.IsBasicShapeValue()) {
-      shape = BasicShapeForValue(state, value);
+    const CSSValue& item_value = value_list.Item(i);
+    if (item_value.IsBasicShapeValue()) {
+      shape = BasicShapeForValue(state, item_value);
     } else {
-      css_box = ToCSSIdentifierValue(value).ConvertTo<CSSBoxType>();
+      css_box = ToCSSIdentifierValue(item_value).ConvertTo<CSSBoxType>();
     }
   }
 
@@ -1576,7 +1574,7 @@
   double z = 1;
   if (list.length() == 2) {
     // axis angle
-    const CSSAxisValue& axis = ToCSSAxisValue(list.Item(0));
+    const CSSAxisValue& axis = To<CSSAxisValue>(list.Item(0));
     x = axis.X();
     y = axis.Y();
     z = axis.Z();
@@ -1651,10 +1649,9 @@
     const CSSToLengthConversionData& css_to_length_conversion_data,
     const CSSValue& value) {
   // TODO(timloh): Images values can also contain lengths.
-  if (value.IsFunctionValue()) {
-    const CSSFunctionValue& function_value = ToCSSFunctionValue(value);
+  if (const auto* function_value = DynamicTo<CSSFunctionValue>(value)) {
     CSSFunctionValue* new_function =
-        CSSFunctionValue::Create(function_value.FunctionType());
+        CSSFunctionValue::Create(function_value->FunctionType());
     for (const CSSValue* inner_value : ToCSSValueList(value)) {
       new_function->Append(ComputeRegisteredPropertyValue(
           document, css_to_length_conversion_data, *inner_value));
diff --git a/third_party/blink/renderer/core/css/resolver/transform_builder.cc b/third_party/blink/renderer/core/css/resolver/transform_builder.cc
index e338e971..494c13f 100644
--- a/third_party/blink/renderer/core/css/resolver/transform_builder.cc
+++ b/third_party/blink/renderer/core/css/resolver/transform_builder.cc
@@ -103,10 +103,10 @@
 
 bool TransformBuilder::HasRelativeLengths(const CSSValueList& value_list) {
   for (auto& value : value_list) {
-    const CSSFunctionValue* transform_value = ToCSSFunctionValue(value.Get());
+    const CSSFunctionValue* transform_value = To<CSSFunctionValue>(value.Get());
 
     for (const CSSValue* item : *transform_value) {
-      const CSSPrimitiveValue& primitive_value = ToCSSPrimitiveValue(*item);
+      const auto& primitive_value = ToCSSPrimitiveValue(*item);
 
       if (primitive_value.IsCalculated()) {
         CSSCalcValue* css_calc_value = primitive_value.CssCalcValue();
@@ -138,7 +138,7 @@
 
   float zoom_factor = conversion_data.Zoom();
   for (auto& value : ToCSSValueList(in_value)) {
-    const CSSFunctionValue* transform_value = ToCSSFunctionValue(value.Get());
+    const auto* transform_value = To<CSSFunctionValue>(value.Get());
     TransformOperation::OperationType transform_type =
         GetTransformOperationType(transform_value->FunctionType());
 
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc
index b4a0943..dd32000 100644
--- a/third_party/blink/renderer/core/css/selector_checker.cc
+++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -762,11 +762,11 @@
     case CSSSelector::kPseudoNot:
       return CheckPseudoNot(context, result);
     case CSSSelector::kPseudoEmpty: {
-      bool result = true;
+      bool is_empty = true;
       bool has_whitespace = false;
       for (Node* n = element.firstChild(); n; n = n->nextSibling()) {
         if (n->IsElementNode()) {
-          result = false;
+          is_empty = false;
           break;
         }
         if (n->IsTextNode()) {
@@ -775,20 +775,20 @@
             if (text_node->ContainsOnlyWhitespaceOrEmpty()) {
               has_whitespace = true;
             } else {
-              result = false;
+              is_empty = false;
               break;
             }
           }
         }
       }
-      if (result && has_whitespace) {
+      if (is_empty && has_whitespace) {
         UseCounter::Count(context.element->GetDocument(),
                           WebFeature::kCSSSelectorEmptyWhitespaceOnlyFail);
-        result = false;
+        is_empty = false;
       }
       if (mode_ == kResolvingStyle)
         element.SetStyleAffectedByEmpty();
-      return result;
+      return is_empty;
     }
     case CSSSelector::kPseudoFirstChild:
       if (mode_ == kResolvingStyle) {
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index 5fb0822..3f244abe 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -635,10 +635,10 @@
   if (!rule->FontDisplay())
     return;
   for (const auto& family_value : rule->FontFamily()) {
-    if (family_value->IsFontFamilyValue()) {
-      default_font_display_map_.Set(
-          AtomicString(ToCSSFontFamilyValue(family_value)->Value()),
-          CSSValueToFontDisplay(rule->FontDisplay()));
+    if (auto* font_family_value =
+            DynamicTo<CSSFontFamilyValue>(family_value.Get())) {
+      default_font_display_map_.Set(AtomicString(font_family_value->Value()),
+                                    CSSValueToFontDisplay(rule->FontDisplay()));
     }
   }
 }
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc
index ea3d503..6f9a465 100644
--- a/third_party/blink/renderer/core/css/style_property_serializer.cc
+++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -93,10 +93,10 @@
       static_cast<CSSPropertyID>(index + firstCSSProperty);
   DCHECK(isCSSPropertyIDWithName(property_id));
   if (longhand_property_used_.test(index)) {
-    int index = property_set_->FindPropertyIndex(property_id);
-    DCHECK_NE(index, -1);
+    int real_index = property_set_->FindPropertyIndex(property_id);
+    DCHECK_NE(real_index, -1);
     return StylePropertySerializer::PropertyValueForSerializer(
-        property_set_->PropertyAt(index));
+        property_set_->PropertyAt(real_index));
   }
 
   CSSPropertyValueSet::PropertyReference property =
@@ -180,8 +180,7 @@
   StringBuilder result;
   if (is_not_first_decl)
     result.Append(' ');
-  const CSSCustomPropertyDeclaration* value =
-      ToCSSCustomPropertyDeclaration(property.Value());
+  const auto* value = To<CSSCustomPropertyDeclaration>(property.Value());
   SerializeIdentifier(value->GetName(), result, is_not_first_decl);
   result.Append(':');
   if (!value->Value())
diff --git a/third_party/blink/renderer/core/dom/text_link_colors.cc b/third_party/blink/renderer/core/dom/text_link_colors.cc
index 11927e5..ba12723 100644
--- a/third_party/blink/renderer/core/dom/text_link_colors.cc
+++ b/third_party/blink/renderer/core/dom/text_link_colors.cc
@@ -61,8 +61,8 @@
                                         Color current_color,
                                         ColorScheme color_scheme,
                                         bool for_visited_link) const {
-  if (value.IsColorValue())
-    return ToCSSColorValue(value).Value();
+  if (auto* color_value = DynamicTo<CSSColorValue>(value))
+    return color_value->Value();
 
   CSSValueID value_id = ToCSSIdentifierValue(value).GetValueID();
   switch (value_id) {
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc
index fa68d5d..46101f6c 100644
--- a/third_party/blink/renderer/core/editing/editing_style.cc
+++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -430,18 +430,20 @@
                        (value == "sub" || value == "super");
 }
 
-static Color CssValueToColor(const CSSValue* color_value) {
-  if (!color_value ||
-      (!color_value->IsColorValue() && !color_value->IsPrimitiveValue() &&
-       !color_value->IsIdentifierValue()))
+static Color CssValueToColor(const CSSValue* value) {
+  if (!value)
     return Color::kTransparent;
 
-  if (color_value->IsColorValue())
-    return ToCSSColorValue(color_value)->Value();
+  auto* color_value = DynamicTo<CSSColorValue>(value);
+  if (!color_value && !value->IsPrimitiveValue() && !value->IsIdentifierValue())
+    return Color::kTransparent;
+
+  if (color_value)
+    return color_value->Value();
 
   Color color = 0;
   // FIXME: Why ignore the return value?
-  CSSParser::ParseColor(color, color_value->CssText());
+  CSSParser::ParseColor(color, value->CssText());
   return color;
 }
 
diff --git a/third_party/blink/renderer/core/editing/editing_style_utilities.cc b/third_party/blink/renderer/core/editing/editing_style_utilities.cc
index 84676040..006df967 100644
--- a/third_party/blink/renderer/core/editing/editing_style_utilities.cc
+++ b/third_party/blink/renderer/core/editing/editing_style_utilities.cc
@@ -203,8 +203,8 @@
 bool EditingStyleUtilities::IsTransparentColorValue(const CSSValue* css_value) {
   if (!css_value)
     return true;
-  if (css_value->IsColorValue())
-    return !ToCSSColorValue(css_value)->Value().Alpha();
+  if (auto* color_value = DynamicTo<CSSColorValue>(css_value))
+    return !color_value->Value().Alpha();
   if (!css_value->IsIdentifierValue())
     return false;
   return ToCSSIdentifierValue(css_value)->GetValueID() == CSSValueTransparent;
diff --git a/third_party/blink/renderer/core/editing/web_substring_util.mm b/third_party/blink/renderer/core/editing/web_substring_util.mm
index c61ff3a9..0bfeeba 100644
--- a/third_party/blink/renderer/core/editing/web_substring_util.mm
+++ b/third_party/blink/renderer/core/editing/web_substring_util.mm
@@ -33,6 +33,7 @@
 
 #import <Cocoa/Cocoa.h>
 
+#include "base/mac/foundation_util.h"
 #include "third_party/blink/public/platform/web_rect.h"
 #include "third_party/blink/public/web/web_frame_widget.h"
 #include "third_party/blink/public/web/web_hit_test_result.h"
@@ -96,7 +97,7 @@
     FontPlatformData font_platform_data =
         style->GetFont().PrimaryFont()->PlatformData();
     font_platform_data.text_size_ *= font_scale;
-    NSFont* font = toNSFont(font_platform_data.CtFont());
+    NSFont* font = base::mac::CFToNSCast(font_platform_data.CtFont());
     // If the platform font can't be loaded, or the size is incorrect comparing
     // to the computed style, it's likely that the site is using a web font.
     // For now, just use the default font instead.
diff --git a/third_party/blink/renderer/core/events/message_event.cc b/third_party/blink/renderer/core/events/message_event.cc
index d8c5d5a..22ffd06 100644
--- a/third_party/blink/renderer/core/events/message_event.cc
+++ b/third_party/blink/renderer/core/events/message_event.cc
@@ -121,7 +121,8 @@
                            const String& last_event_id,
                            EventTarget* source,
                            Vector<MessagePortChannel> channels,
-                           UserActivation* user_activation)
+                           UserActivation* user_activation,
+                           bool transfer_user_activation)
     : Event(event_type_names::kMessage, Bubbles::kNo, Cancelable::kNo),
       data_type_(kDataTypeSerializedScriptValue),
       data_as_serialized_script_value_(
@@ -130,7 +131,8 @@
       last_event_id_(last_event_id),
       source_(source),
       channels_(std::move(channels)),
-      user_activation_(user_activation) {
+      user_activation_(user_activation),
+      transfer_user_activation_(transfer_user_activation) {
   DCHECK(IsValidSource(source_.Get()));
 }
 
@@ -203,7 +205,8 @@
                                     const String& last_event_id,
                                     EventTarget* source,
                                     MessagePortArray* ports,
-                                    UserActivation* user_activation) {
+                                    UserActivation* user_activation,
+                                    bool transfer_user_activation) {
   if (IsBeingDispatched())
     return;
 
@@ -218,6 +221,7 @@
   ports_ = ports;
   is_ports_dirty_ = true;
   user_activation_ = user_activation;
+  transfer_user_activation_ = transfer_user_activation;
 }
 
 void MessageEvent::initMessageEvent(const AtomicString& type,
diff --git a/third_party/blink/renderer/core/events/message_event.h b/third_party/blink/renderer/core/events/message_event.h
index 6d88a50..68100c8 100644
--- a/third_party/blink/renderer/core/events/message_event.h
+++ b/third_party/blink/renderer/core/events/message_event.h
@@ -77,10 +77,11 @@
                               const String& origin = String(),
                               const String& last_event_id = String(),
                               EventTarget* source = nullptr,
-                              UserActivation* user_activation = nullptr) {
+                              UserActivation* user_activation = nullptr,
+                              bool transfer_user_activation = false) {
     return MakeGarbageCollected<MessageEvent>(
         std::move(data), origin, last_event_id, source, std::move(channels),
-        user_activation);
+        user_activation, transfer_user_activation);
   }
   static MessageEvent* CreateError(const String& origin = String(),
                                    EventTarget* source = nullptr) {
@@ -118,7 +119,8 @@
                const String& last_event_id,
                EventTarget* source,
                Vector<MessagePortChannel>,
-               UserActivation* user_activation);
+               UserActivation* user_activation,
+               bool transfer_user_activation);
   // Creates a "messageerror" event.
   MessageEvent(const String& origin, EventTarget* source);
   MessageEvent(const String& data, const String& origin);
@@ -142,7 +144,8 @@
                         const String& last_event_id,
                         EventTarget* source,
                         MessagePortArray*,
-                        UserActivation* user_activation);
+                        UserActivation* user_activation,
+                        bool transfer_user_activation = false);
   void initMessageEvent(const AtomicString& type,
                         bool bubbles,
                         bool cancelable,
@@ -158,6 +161,7 @@
   MessagePortArray ports();
   bool isPortsDirty() const { return is_ports_dirty_; }
   UserActivation* userActivation() const { return user_activation_; }
+  bool transferUserActivation() const { return transfer_user_activation_; }
 
   Vector<MessagePortChannel> ReleaseChannels() { return std::move(channels_); }
 
@@ -242,6 +246,7 @@
   bool is_ports_dirty_ = true;
   Vector<MessagePortChannel> channels_;
   Member<UserActivation> user_activation_;
+  bool transfer_user_activation_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_dom_message_event.cc b/third_party/blink/renderer/core/exported/web_dom_message_event.cc
index ca4632ca8..3b15ac8 100644
--- a/third_party/blink/renderer/core/exported/web_dom_message_event.cc
+++ b/third_party/blink/renderer/core/exported/web_dom_message_event.cc
@@ -91,7 +91,8 @@
   // right?
   Unwrap<MessageEvent>()->initMessageEvent(
       "message", false, false, std::move(msg.message), origin,
-      "" /*lastEventId*/, window, ports, user_activation);
+      "" /*lastEventId*/, window, ports, user_activation,
+      msg.transfer_user_activation);
 }
 
 WebString WebDOMMessageEvent::Origin() const {
@@ -102,6 +103,8 @@
   BlinkTransferableMessage msg;
   msg.message = Unwrap<MessageEvent>()->DataAsSerializedScriptValue();
   msg.ports = Unwrap<MessageEvent>()->ReleaseChannels();
+  msg.transfer_user_activation =
+      Unwrap<MessageEvent>()->transferUserActivation();
   UserActivation* user_activation = Unwrap<MessageEvent>()->userActivation();
   TransferableMessage transferable_msg = ToTransferableMessage(std::move(msg));
   if (user_activation) {
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc
index 3b7d287..8e9bcebf 100644
--- a/third_party/blink/renderer/core/frame/dom_window.cc
+++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -493,10 +493,12 @@
   if (options->includeUserActivation())
     user_activation = UserActivation::CreateSnapshot(source);
 
-  MessageEvent* event =
-      MessageEvent::Create(std::move(channels), std::move(message),
-                           source_origin, String(), source, user_activation);
+  MessageEvent* event = MessageEvent::Create(
+      std::move(channels), std::move(message), source_origin, String(), source,
+      user_activation, options->transferUserActivation());
 
+  // TODO(928838): Transfer activation state in current renderer's frame tree if
+  // source frame has transient activation.
   SchedulePostMessage(event, std::move(target), source_document);
 }
 
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc
index 32f30d1f..4c86947 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -553,14 +553,12 @@
 
     AddImageToResources(style_image->CachedImage(),
                         style_image->CachedImage()->Url());
-  } else if (css_value.IsFontFaceSrcValue()) {
-    const CSSFontFaceSrcValue& font_face_src_value =
-        ToCSSFontFaceSrcValue(css_value);
-    if (font_face_src_value.IsLocal()) {
+  } else if (const auto* font_face_src_value =
+                 DynamicTo<CSSFontFaceSrcValue>(css_value)) {
+    if (font_face_src_value->IsLocal())
       return;
-    }
 
-    AddFontToResources(font_face_src_value.Fetch(&document, nullptr));
+    AddFontToResources(font_face_src_value->Fetch(&document, nullptr));
   } else if (css_value.IsValueList()) {
     const CSSValueList& css_value_list = ToCSSValueList(css_value);
     for (unsigned i = 0; i < css_value_list.length(); i++)
diff --git a/third_party/blink/renderer/core/frame/window_post_message_options.idl b/third_party/blink/renderer/core/frame/window_post_message_options.idl
index 41c8764..fe1d172 100644
--- a/third_party/blink/renderer/core/frame/window_post_message_options.idl
+++ b/third_party/blink/renderer/core/frame/window_post_message_options.idl
@@ -6,4 +6,5 @@
 
 dictionary WindowPostMessageOptions : PostMessageOptions {
     USVString targetOrigin = "/";
+    [RuntimeEnabled=UserActivationDelegation] boolean transferUserActivation = false;
 };
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc b/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
index 157d644..c601ed51 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
@@ -300,8 +300,12 @@
   EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(0);
   platform_->RunForPeriodSeconds(1);
 
-  // Seek to some time in the past. A completed seek should trigger a *single*
-  // timeupdate.
+  EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
+  Video()->pause();
+  platform_->RunUntilIdle();
+
+  // Seek to some time in the past. A completed seek while paused should trigger
+  // a *single* timeupdate.
   EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
   ASSERT_GE(WebMediaPlayer()->CurrentTime(), 1);
   Video()->setCurrentTime(WebMediaPlayer()->CurrentTime() - 1);
@@ -354,10 +358,14 @@
   ASSERT_GE(WebMediaPlayer()->CurrentTime(), 1);
   Video()->setCurrentTime(WebMediaPlayer()->CurrentTime() - 1);
   WebMediaPlayer()->FinishSeek();
+
+  // Expect another timeupdate after FinishSeek due to
+  // seeking -> begin scrubbing -> pause -> timeupdate.
+  EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
   platform_->RunUntilIdle();
 
   // Advancing the remainder of the last periodic timeupdate interval should be
-  // insufficient to triggger a new timeupdate event because the seek's
+  // insufficient to trigger a new timeupdate event because the seek's
   // timeupdate occurred only 125ms ago. We desire to fire periodic timeupdates
   // exactly every 250ms from the last timeupdate, and the seek's timeupdate
   // should reset that 250ms ms countdown.
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
index 8c86a55..996a36b72 100644
--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -227,13 +227,10 @@
 
   StyleGeneratedImage* gen_image = ToStyleGeneratedImage(style_image);
   CSSValue* image_css = gen_image->CssValue();
-  if (image_css->IsGradientValue()) {
-    cssvalue::CSSGradientValue* gradient =
-        cssvalue::ToCSSGradientValue(image_css);
+  if (auto* gradient = DynamicTo<cssvalue::CSSGradientValue>(image_css)) {
     BlendWithColorsFromGradient(gradient, colors, found_non_transparent_color,
                                 found_opaque_color, layout_object);
   }
-  return;
 }
 
 // Get the background colors behind the given rect in the given document, by
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
index 9e54602..248c8f22 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -19,7 +19,7 @@
 #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_relative_utils.h"
-#include "third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
 #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 
@@ -404,8 +404,8 @@
 
 template <typename Base>
 void LayoutNGMixin<Base>::Paint(const PaintInfo& paint_info) const {
-  if (PaintFragment())
-    NGBlockFlowPainter(*this).Paint(paint_info);
+  if (const NGPaintFragment* paint_fragment = PaintFragment())
+    NGBoxFragmentPainter(*paint_fragment).Paint(paint_info);
   else
     LayoutBlockFlow::Paint(paint_info);
 }
@@ -416,7 +416,8 @@
     const HitTestLocation& location_in_container,
     const LayoutPoint& accumulated_offset,
     HitTestAction action) {
-  if (!PaintFragment()) {
+  const NGPaintFragment* paint_fragment = PaintFragment();
+  if (!paint_fragment) {
     return LayoutBlockFlow::NodeAtPoint(result, location_in_container,
                                         accumulated_offset, action);
   }
@@ -440,8 +441,8 @@
                                    physical_offset))
     return true;
 
-  return NGBlockFlowPainter(*this).NodeAtPoint(result, location_in_container,
-                                               physical_offset, action);
+  return NGBoxFragmentPainter(*paint_fragment)
+      .NodeAtPoint(result, location_in_container, physical_offset, action);
 }
 
 template <typename Base>
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
index cd599b5..9a2791f 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
@@ -69,7 +69,7 @@
   NGPhysicalOffsetRect SelfInkOverflow() const;
 
   // Ink overflow including contents, in the local coordinates.
-  NGPhysicalOffsetRect InkOverflow(bool apply_clip) const;
+  NGPhysicalOffsetRect InkOverflow(bool apply_clip = true) const;
 
   // Ink overflow of children in local coordinates.
   NGPhysicalOffsetRect ContentsInkOverflow() const;
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
index 01576683..aa32a5d3 100644
--- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
+++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -46,6 +46,7 @@
         message.user_activation->has_been_active,
         message.user_activation->was_active);
   }
+  result.transfer_user_activation = message.transfer_user_activation;
   return result;
 }
 
@@ -76,6 +77,7 @@
         message.user_activation->has_been_active,
         message.user_activation->was_active);
   }
+  result.transfer_user_activation = message.transfer_user_activation;
   return result;
 }
 
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.h b/third_party/blink/renderer/core/messaging/blink_transferable_message.h
index 1e6fce8..06e4b05d 100644
--- a/third_party/blink/renderer/core/messaging/blink_transferable_message.h
+++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.h
@@ -33,6 +33,8 @@
 
   mojom::blink::UserActivationSnapshotPtr user_activation;
 
+  bool transfer_user_activation = false;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(BlinkTransferableMessage);
 };
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h b/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h
index 3194e3f..53ee100b 100644
--- a/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h
+++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h
@@ -61,6 +61,11 @@
     return input.user_activation;
   }
 
+  static bool transfer_user_activation(
+      const blink::BlinkTransferableMessage& input) {
+    return input.transfer_user_activation;
+  }
+
   static bool Read(blink::mojom::blink::TransferableMessage::DataView,
                    blink::BlinkTransferableMessage* out);
 };
diff --git a/third_party/blink/renderer/core/page/drag_controller.cc b/third_party/blink/renderer/core/page/drag_controller.cc
index fc6a0b1..68dbbe3 100644
--- a/third_party/blink/renderer/core/page/drag_controller.cc
+++ b/third_party/blink/renderer/core/page/drag_controller.cc
@@ -803,8 +803,9 @@
   if (HasEditableStyle(node))
     return true;
 
-  for (Node& node : NodeTraversal::InclusiveAncestorsOf(node)) {
-    if (node.IsHTMLElement() && ToHTMLElement(&node)->draggable())
+  for (Node& ancestor_node : NodeTraversal::InclusiveAncestorsOf(node)) {
+    if (ancestor_node.IsHTMLElement() &&
+        ToHTMLElement(&ancestor_node)->draggable())
       return false;
   }
 
@@ -1267,12 +1268,12 @@
       // a user can initiate a drag on a link without having any text
       // selected.  In this case, we should expand the selection to
       // the enclosing anchor element
-      if (Node* node = EnclosingAnchorElement(
+      if (Node* anchor = EnclosingAnchorElement(
               src->Selection()
                   .ComputeVisibleSelectionInDOMTreeDeprecated()
                   .Base())) {
         src->Selection().SetSelectionAndEndTyping(
-            SelectionInDOMTree::Builder().SelectAllChildren(*node).Build());
+            SelectionInDOMTree::Builder().SelectAllChildren(*anchor).Build());
       }
     }
 
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc
index d8eeefc1..225c345 100644
--- a/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -1047,9 +1047,9 @@
     }
 
     // Chrome doesn't want focus, so we should wrap focus.
-    ScopedFocusNavigation scope = ScopedFocusNavigation::CreateForDocument(
+    ScopedFocusNavigation doc_scope = ScopedFocusNavigation::CreateForDocument(
         *To<LocalFrame>(page_->MainFrame())->GetDocument(), owner_map);
-    element = FindFocusableElementRecursively(type, scope, owner_map);
+    element = FindFocusableElementRecursively(type, doc_scope, owner_map);
     element = FindFocusableElementDescendingDownIntoFrameDocument(type, element,
                                                                   owner_map);
 
diff --git a/third_party/blink/renderer/core/page/plugin_data.h b/third_party/blink/renderer/core/page/plugin_data.h
index c25e742..d0457cd 100644
--- a/third_party/blink/renderer/core/page/plugin_data.h
+++ b/third_party/blink/renderer/core/page/plugin_data.h
@@ -47,7 +47,6 @@
 
  private:
   friend class PluginData;
-  friend class PluginListBuilder;
 
   String type_;
   String description_;
@@ -80,7 +79,6 @@
  private:
   friend class MimeClassInfo;
   friend class PluginData;
-  friend class PluginListBuilder;
 
   String name_;
   String filename_;
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
index bc8b072..2e5aa2bc 100644
--- a/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
+++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc
@@ -292,13 +292,13 @@
     // the URL bar movement). Test it for scrolling so that we only promote if
     // we know we won't block scrolling the main document.
     if (ancestor->IsLayoutView()) {
-      const ComputedStyle* style = ancestor->Style();
-      DCHECK(style);
+      const ComputedStyle* ancestor_style = ancestor->Style();
+      DCHECK(ancestor_style);
 
       PaintLayerScrollableArea* area = ancestor->GetScrollableArea();
       DCHECK(area);
 
-      if (style->ScrollsOverflowY() && area->HasVerticalOverflow())
+      if (ancestor_style->ScrollsOverflowY() && area->HasVerticalOverflow())
         return false;
     } else {
       if (ancestor->ShouldClipOverflow() || ancestor->HasMask() ||
diff --git a/third_party/blink/renderer/core/paint/BUILD.gn b/third_party/blink/renderer/core/paint/BUILD.gn
index 13b93f65..157fb77a 100644
--- a/third_party/blink/renderer/core/paint/BUILD.gn
+++ b/third_party/blink/renderer/core/paint/BUILD.gn
@@ -121,8 +121,6 @@
     "list_marker_painter.h",
     "multi_column_set_painter.cc",
     "multi_column_set_painter.h",
-    "ng/ng_block_flow_painter.cc",
-    "ng/ng_block_flow_painter.h",
     "ng/ng_box_fragment_painter.cc",
     "ng/ng_box_fragment_painter.h",
     "ng/ng_fieldset_painter.cc",
diff --git a/third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.cc
deleted file mode 100644
index 0f48339..0000000
--- a/third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.
-
-#include "third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.h"
-
-#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
-#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
-#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
-#include "third_party/blink/renderer/core/paint/paint_info.h"
-
-namespace blink {
-
-void NGBlockFlowPainter::Paint(const PaintInfo& paint_info) {
-  const NGPaintFragment* paint_fragment = block_.PaintFragment();
-  DCHECK(paint_fragment);
-  PaintBoxFragment(*paint_fragment, paint_info);
-}
-
-void NGBlockFlowPainter::PaintBoxFragment(const NGPaintFragment& fragment,
-                                          const PaintInfo& paint_info) {
-  PaintInfo ng_paint_info(paint_info);
-  NGBoxFragmentPainter(fragment).Paint(ng_paint_info);
-}
-
-bool NGBlockFlowPainter::NodeAtPoint(
-    HitTestResult& result,
-    const HitTestLocation& location_in_container,
-    const LayoutPoint& physical_offset,
-    HitTestAction action) {
-  if (const NGPaintFragment* paint_fragment = block_.PaintFragment()) {
-    return NGBoxFragmentPainter(*paint_fragment)
-        .NodeAtPoint(result, location_in_container, physical_offset, action);
-  }
-  return false;
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.h b/third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.h
deleted file mode 100644
index 7c9af257..0000000
--- a/third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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 THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_BLOCK_FLOW_PAINTER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_BLOCK_FLOW_PAINTER_H_
-
-#include "third_party/blink/renderer/core/layout/api/hit_test_action.h"
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-
-namespace blink {
-
-class HitTestResult;
-class HitTestLocation;
-class LayoutPoint;
-struct PaintInfo;
-class LayoutBlockFlow;
-class NGPaintFragment;
-struct PaintInfo;
-
-// Painter for NGBlockFlow which represents the root of a LayoutNG sub-tree.
-// Paints the root fragment associated with the NGBlockFlow recursively, walking
-// the LayoutNG fragment tree instead of the legacy layout tree.
-class NGBlockFlowPainter {
-  STACK_ALLOCATED();
-
- public:
-  NGBlockFlowPainter(const LayoutBlockFlow& layout_block_flow)
-      : block_(layout_block_flow) {}
-  void Paint(const PaintInfo&);
-
-  // Hit tests this block flow
-  // @param physical_offset Physical offset of this block flow in paint layer.
-  bool NodeAtPoint(HitTestResult&,
-                   const HitTestLocation& location_in_container,
-                   const LayoutPoint& physical_offset,
-                   HitTestAction);
-
- private:
-  void PaintBoxFragment(const NGPaintFragment&, const PaintInfo&);
-
-  const LayoutBlockFlow& block_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_BLOCK_FLOW_PAINTER_H_
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index 38c33fd8..d75f831fa 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -137,14 +137,25 @@
     : BoxPainterBase(&box.GetLayoutObject()->GetDocument(),
                      box.Style(),
                      box.GetLayoutObject()->GeneratingNode()),
-      box_fragment_(box),
-      border_edges_(
-          NGBorderEdges::FromPhysical(box.PhysicalFragment().BorderEdges(),
-                                      box.Style().GetWritingMode())) {
+      box_fragment_(box) {
   DCHECK(box.PhysicalFragment().IsBox() ||
          box.PhysicalFragment().IsRenderedLegend());
 }
 
+const NGPhysicalBoxFragment& NGBoxFragmentPainter::PhysicalFragment() const {
+  return static_cast<const NGPhysicalBoxFragment&>(
+      box_fragment_.PhysicalFragment());
+}
+
+const NGBorderEdges& NGBoxFragmentPainter::BorderEdges() const {
+  if (border_edges_.has_value())
+    return *border_edges_;
+  const NGPhysicalBoxFragment& fragment = PhysicalFragment();
+  border_edges_ = NGBorderEdges::FromPhysical(
+      fragment.BorderEdges(), fragment.Style().GetWritingMode());
+  return *border_edges_;
+}
+
 void NGBoxFragmentPainter::Paint(const PaintInfo& paint_info) {
   if (PhysicalFragment().IsAtomicInline() &&
       !box_fragment_.HasSelfPaintingLayer())
@@ -321,15 +332,16 @@
   // all the stylesheets do load, styleResolverMayHaveChanged() on Document will
   // trigger a full paint invalidation.
   // TODO(layout-dev): Handle without delegating to LayoutObject.
-  LayoutObject* layout_object = box_fragment_.GetLayoutObject();
+  const NGPhysicalBoxFragment& fragment = PhysicalFragment();
+  LayoutObject* layout_object = fragment.GetLayoutObject();
   if (layout_object->GetDocument().DidLayoutWithPendingStylesheets() &&
       !layout_object->IsLayoutView()) {
     return;
   }
 
-  DCHECK(PhysicalFragment().ChildrenInline());
+  DCHECK(fragment.ChildrenInline());
 
-  LayoutRect overflow_rect(box_fragment_.ChildrenInkOverflow());
+  LayoutRect overflow_rect(fragment.InkOverflow(false).ToLayoutRect());
   overflow_rect.MoveBy(paint_offset);
   if (!paint_info.GetCullRect().Intersects(overflow_rect))
     return;
@@ -449,8 +461,9 @@
   DrawingRecorder recorder(paint_info.context, box_fragment_, paint_info.phase);
   LayoutRect paint_rect =
       LayoutRect(paint_offset, box_fragment_.Size().ToLayoutSize());
+  const NGBorderEdges& border_edges = BorderEdges();
   PaintMaskImages(paint_info, paint_rect, *box_fragment_.GetLayoutObject(),
-                  geometry, border_edges_.line_left, border_edges_.line_right);
+                  geometry, border_edges.line_left, border_edges.line_right);
 }
 
 // TODO(kojii): This logic is kept in sync with BoxPainter. Not much efforts to
@@ -567,13 +580,14 @@
       BackgroundIsKnownToBeOpaque(paint_info))
     recorder.SetKnownToBeOpaque();
 
+  const NGBorderEdges& border_edges = BorderEdges();
   bool needs_end_layer = false;
   if (!painting_overflow_contents) {
     bool skip_background = layout_box.BackgroundTransfersToView() ||
                            (paint_info.SkipRootBackground() &&
                             paint_info.PaintContainer() == layout_box);
-    PaintNormalBoxShadow(paint_info, paint_rect, style, border_edges_.line_left,
-                         border_edges_.line_right, skip_background);
+    PaintNormalBoxShadow(paint_info, paint_rect, style, border_edges.line_left,
+                         border_edges.line_right, skip_background);
 
     if (box_fragment_.HasSelfPaintingLayer() && layout_box.IsTableCell() &&
         ToLayoutTableCell(layout_box).Table()->ShouldCollapseBorders()) {
@@ -586,7 +600,7 @@
     } else if (BleedAvoidanceIsClipping(box_decoration_data.bleed_avoidance)) {
       state_saver.Save();
       FloatRoundedRect border = style.GetRoundedBorderFor(
-          paint_rect, border_edges_.line_left, border_edges_.line_right);
+          paint_rect, border_edges.line_left, border_edges.line_right);
       paint_info.context.ClipRoundedRect(border);
 
       if (box_decoration_data.bleed_avoidance == kBackgroundBleedClipLayer) {
@@ -618,8 +632,8 @@
 
   if (!painting_overflow_contents) {
     PaintInsetBoxShadowWithBorderRect(paint_info, paint_rect, style,
-                                      border_edges_.line_left,
-                                      border_edges_.line_right);
+                                      border_edges.line_left,
+                                      border_edges.line_right);
 
     // The theme will tell us whether or not we should also paint the CSS
     // border.
@@ -633,8 +647,8 @@
       const Document& document = layout_object.GetDocument();
       PaintBorder(*box_fragment_.GetLayoutObject(), document, generating_node,
                   paint_info, paint_rect, style,
-                  box_decoration_data.bleed_avoidance, border_edges_.line_left,
-                  border_edges_.line_right);
+                  box_decoration_data.bleed_avoidance, border_edges.line_left,
+                  border_edges.line_right);
     }
   }
 
@@ -801,11 +815,11 @@
   }
 }
 
-void NGBoxFragmentPainter::PaintTextChild(const NGPaintFragment& text_fragment,
+void NGBoxFragmentPainter::PaintTextChild(const NGPaintFragment& paint_fragment,
                                           const PaintInfo& paint_info,
                                           const LayoutPoint& paint_offset) {
   // Inline blocks should be painted by PaintAtomicInlineChild.
-  DCHECK(!text_fragment.PhysicalFragment().IsAtomicInline());
+  DCHECK(!paint_fragment.PhysicalFragment().IsAtomicInline());
 
   // Only paint during the foreground/selection phases.
   if (paint_info.phase != PaintPhase::kForeground &&
@@ -817,9 +831,12 @@
   // Note: To paint selection for <br>, we don't check intersection with
   // fragment paint rect and cull rect since computing selection rect is
   // expensive.
+  const NGPhysicalTextFragment& text_fragment =
+      ToNGPhysicalTextFragment(paint_fragment.PhysicalFragment());
   if (!text_fragment.Size().IsEmpty()) {
-    LayoutRect physical_visual_overflow = text_fragment.SelfInkOverflow();
-    physical_visual_overflow.MoveBy(text_fragment.Offset().ToLayoutPoint());
+    LayoutRect physical_visual_overflow =
+        text_fragment.SelfInkOverflow().ToLayoutRect();
+    physical_visual_overflow.MoveBy(paint_fragment.Offset().ToLayoutPoint());
     physical_visual_overflow.MoveBy(paint_offset);
     if (!paint_info.GetCullRect().Intersects(physical_visual_overflow))
       return;
@@ -831,7 +848,7 @@
       node_holder = ToLayoutText(node->GetLayoutObject())->EnsureNodeHolder();
   }
 
-  NGTextFragmentPainter text_painter(text_fragment);
+  NGTextFragmentPainter text_painter(paint_fragment);
   text_painter.Paint(paint_info, paint_offset, node_holder);
 }
 
@@ -876,7 +893,7 @@
     const ScopedPaintState& paint_state) const {
   // TODO(layout-dev): Add support for scrolling, see BlockPainter::ShouldPaint.
   return paint_state.LocalRectIntersectsCullRect(
-      box_fragment_.SelfInkOverflow());
+      PhysicalFragment().InkOverflow().ToLayoutRect());
 }
 
 void NGBoxFragmentPainter::PaintTextClipMask(GraphicsContext& context,
@@ -943,10 +960,11 @@
     const Color& color,
     const FillLayer& bg_layer,
     BackgroundBleedAvoidance bleed_avoidance) const {
+  const NGBorderEdges& border_edges = BorderEdges();
   return BoxPainterBase::FillLayerInfo(
       box_fragment_.GetLayoutObject()->GetDocument(), box_fragment_.Style(),
       box_fragment_.HasOverflowClip(), color, bg_layer, bleed_avoidance,
-      border_edges_.line_left, border_edges_.line_right);
+      border_edges.line_left, border_edges.line_right);
 }
 
 bool NGBoxFragmentPainter::IsInSelfHitTestingPhase(HitTestAction action) const {
@@ -1066,7 +1084,7 @@
   LayoutRect rect = LayoutRect(PixelSnappedIntRect(border_rect));
   if (UNLIKELY(result.GetHitTestRequest().GetType() &
                HitTestRequest::kHitTestVisualOverflow)) {
-    rect = text_paint_fragment.SelfInkOverflow();
+    rect = text_fragment.SelfInkOverflow().ToLayoutRect();
     rect.MoveBy(border_rect.Location());
   }
 
@@ -1108,7 +1126,8 @@
     return false;
 
   const LayoutPoint overflow_location =
-      fragment.SelfInkOverflow().Location() + physical_offset;
+      fragment.PhysicalFragment().SelfInkOverflow().offset.ToLayoutPoint() +
+      physical_offset;
   if (HitTestClippedOutByBorder(location_in_container, overflow_location))
     return false;
 
@@ -1242,13 +1261,9 @@
   LayoutRect rect =
       LayoutRect(LayoutPoint(), PhysicalFragment().Size().ToLayoutSize());
   rect.MoveBy(border_box_location);
+  const NGBorderEdges& border_edges = BorderEdges();
   return !location_in_container.Intersects(style.GetRoundedBorderFor(
-      rect, border_edges_.line_left, border_edges_.line_right));
-}
-
-const NGPhysicalBoxFragment& NGBoxFragmentPainter::PhysicalFragment() const {
-  return static_cast<const NGPhysicalBoxFragment&>(
-      box_fragment_.PhysicalFragment());
+      rect, border_edges.line_left, border_edges.line_right));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
index 9e7eb63..834a89b 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
@@ -166,9 +166,10 @@
       const LayoutPoint& offset);
 
   const NGPhysicalBoxFragment& PhysicalFragment() const;
+  const NGBorderEdges& BorderEdges() const;
 
   const NGPaintFragment& box_fragment_;
-  NGBorderEdges border_edges_;
+  mutable base::Optional<NGBorderEdges> border_edges_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index 38ff7981..96e6edba 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -363,14 +363,6 @@
          ToNGPhysicalBoxFragment(*physical_fragment_).ShouldClipOverflow();
 }
 
-LayoutRect NGPaintFragment::SelfInkOverflow() const {
-  return physical_fragment_->InkOverflow().ToLayoutRect();
-}
-
-LayoutRect NGPaintFragment::ChildrenInkOverflow() const {
-  return physical_fragment_->InkOverflow(false).ToLayoutRect();
-}
-
 // Populate descendants from NGPhysicalFragment tree.
 void NGPaintFragment::PopulateDescendants(
     const NGPhysicalOffset inline_offset_to_container_box,
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
index 8a2e2a6..169aa0a 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -159,12 +159,6 @@
   LayoutRect VisualRect() const override;
   LayoutRect PartialInvalidationVisualRect() const override;
 
-  // CSS ink overflow https://www.w3.org/TR/css-overflow-3/#ink
-  // Encloses all pixels painted by self + children.
-  LayoutRect SelfInkOverflow() const;
-  // Union of children's ink overflows.
-  LayoutRect ChildrenInkOverflow() const;
-
   NGPhysicalOffsetRect ComputeLocalSelectionRectForText(
       const LayoutSelectionStatus&) const;
   NGPhysicalOffsetRect ComputeLocalSelectionRectForReplaced() const;
diff --git a/third_party/blink/renderer/core/paint/object_paint_properties.h b/third_party/blink/renderer/core/paint/object_paint_properties.h
index ecbcb70..344c4e50 100644
--- a/third_party/blink/renderer/core/paint/object_paint_properties.h
+++ b/third_party/blink/renderer/core/paint/object_paint_properties.h
@@ -262,13 +262,7 @@
     if (field) {
       auto changed = field->Update(parent, std::move(state));
 #if DCHECK_IS_ON()
-      DCHECK(!is_immutable_ || changed == PaintPropertyChangeType::kUnchanged ||
-             // TODO(crbug.com/937929): kChangedOnlyCompositedAnimationStatus is
-             // to workaround the situation that composited animation status
-             // changes without LayoutObject::SetStyle() being able to detect.
-             // Note that this may cause some false-negatives.
-             changed ==
-                 PaintPropertyChangeType::kChangedOnlyCompositedAnimationStatus)
+      DCHECK(!is_immutable_ || changed == PaintPropertyChangeType::kUnchanged)
           << "Value changed while immutable. New state:\n"
           << *field;
 #endif
diff --git a/third_party/blink/renderer/devtools/BUILD.gn b/third_party/blink/renderer/devtools/BUILD.gn
index 98860d8..1b7f2fe 100644
--- a/third_party/blink/renderer/devtools/BUILD.gn
+++ b/third_party/blink/renderer/devtools/BUILD.gn
@@ -466,7 +466,6 @@
   "front_end/perf_ui/FlameChart.js",
   "front_end/perf_ui/GCActionDelegate.js",
   "front_end/perf_ui/LineLevelProfile.js",
-  "front_end/perf_ui/LiveHeapProfile.js",
   "front_end/perf_ui/NetworkPriorities.js",
   "front_end/perf_ui/OverviewGrid.js",
   "front_end/perf_ui/PieChart.js",
diff --git a/third_party/blink/renderer/devtools/front_end/help/Help.js b/third_party/blink/renderer/devtools/front_end/help/Help.js
index b4846e71..38e2ca0 100644
--- a/third_party/blink/renderer/devtools/front_end/help/Help.js
+++ b/third_party/blink/renderer/devtools/front_end/help/Help.js
@@ -60,8 +60,7 @@
    * @override
    */
   run() {
-    if (!Host.isUnderTest())
-      Help._showReleaseNoteIfNeeded();
+    Help._showReleaseNoteIfNeeded();
   }
 };
 
diff --git a/third_party/blink/renderer/devtools/front_end/main/Main.js b/third_party/blink/renderer/devtools/front_end/main/Main.js
index 53e24c0a..3d3214e 100644
--- a/third_party/blink/renderer/devtools/front_end/main/Main.js
+++ b/third_party/blink/renderer/devtools/front_end/main/Main.js
@@ -106,16 +106,15 @@
   _initializeExperiments() {
     // Keep this sorted alphabetically: both keys and values.
     Runtime.experiments.register('applyCustomStylesheet', 'Allow custom UI themes');
-    Runtime.experiments.register('sourcesPrettyPrint', 'Automatically pretty print in the Sources Panel');
     Runtime.experiments.register('backgroundServices', 'Background web platform feature events', true);
     Runtime.experiments.register('blackboxJSFramesOnTimeline', 'Blackbox JavaScript frames on Timeline', true);
     Runtime.experiments.register('emptySourceMapAutoStepping', 'Empty sourcemap auto-stepping');
     Runtime.experiments.register('inputEventsOnTimelineOverview', 'Input events on Timeline overview', true);
-    Runtime.experiments.register('liveHeapProfile', 'Live heap profile', true);
     Runtime.experiments.register('nativeHeapProfiler', 'Native memory sampling heap profiler', true);
     Runtime.experiments.register('protocolMonitor', 'Protocol Monitor');
     Runtime.experiments.register('samplingHeapProfilerTimeline', 'Sampling heap profiler timeline', true);
     Runtime.experiments.register('sourceDiff', 'Source diff');
+    Runtime.experiments.register('sourcesPrettyPrint', 'Automatically pretty print in the Sources Panel');
     Runtime.experiments.register('splitInDrawer', 'Split in drawer', true);
     Runtime.experiments.register('terminalInDrawer', 'Terminal in drawer', true);
 
@@ -129,9 +128,6 @@
 
     Runtime.experiments.cleanUpStaleExperiments();
     Runtime.experiments.setDefaultExperiments([]);
-
-    if (Host.isUnderTest() && Runtime.queryParam('test').includes('live-line-level-heap-profile.js'))
-      Runtime.experiments.enableForTest('liveHeapProfile');
   }
 
   /**
@@ -265,8 +261,10 @@
     Main.Main.time('Main._lateInitialization');
     this._registerShortcuts();
     Extensions.extensionServer.initializeExtensions();
-    for (const extension of self.runtime.extensions('late-initialization'))
-      extension.instance().then(instance => (/** @type {!Common.Runnable} */ (instance)).run());
+    if (!Host.isUnderTest()) {
+      for (const extension of self.runtime.extensions('late-initialization'))
+        extension.instance().then(instance => (/** @type {!Common.Runnable} */ (instance)).run());
+    }
     Main.Main.timeEnd('Main._lateInitialization');
   }
 
diff --git a/third_party/blink/renderer/devtools/front_end/perf_ui/LineLevelProfile.js b/third_party/blink/renderer/devtools/front_end/perf_ui/LineLevelProfile.js
index c4ef519..4541b619 100644
--- a/third_party/blink/renderer/devtools/front_end/perf_ui/LineLevelProfile.js
+++ b/third_party/blink/renderer/devtools/front_end/perf_ui/LineLevelProfile.js
@@ -254,7 +254,7 @@
   _createElement(type, value) {
     const element = createElementWithClass('div', 'text-editor-line-marker-text');
     if (type === 'performance') {
-      const intensity = Number.constrain(Math.log10(1 + 10 * value) / 5, 0.02, 1);
+      const intensity = Number.constrain(Math.log10(1 + 2 * value) / 5, 0.02, 1);
       element.textContent = Common.UIString('%.1f', value);
       element.style.backgroundColor = `hsla(44, 100%, 50%, ${intensity.toFixed(3)})`;
       element.createChild('span', 'line-marker-units').textContent = ls`ms`;
diff --git a/third_party/blink/renderer/devtools/front_end/perf_ui/LiveHeapProfile.js b/third_party/blink/renderer/devtools/front_end/perf_ui/LiveHeapProfile.js
deleted file mode 100644
index fc275a8..0000000
--- a/third_party/blink/renderer/devtools/front_end/perf_ui/LiveHeapProfile.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @implements {Common.Runnable}
- * @implements {SDK.SDKModelObserver<!SDK.HeapProfilerModel>}
- */
-PerfUI.LiveHeapProfile = class {
-  /**
-   * @override
-   */
-  run() {
-    SDK.targetManager.observeModels(SDK.HeapProfilerModel, this);
-    requestIdleCallback(() => this.onUpdateProfiles());
-    PerfUI.LiveHeapProfile.hasStartedForTest(true);
-  }
-
-  /**
-   * @param {boolean=} started
-   * @return {!Promise}
-   */
-  static hasStartedForTest(started) {
-    if (!PerfUI.LiveHeapProfile._startedPromise)
-      PerfUI.LiveHeapProfile._startedPromise = new Promise(r => PerfUI.LiveHeapProfile._startedCallback = r);
-    if (started)
-      PerfUI.LiveHeapProfile._startedCallback();
-    return PerfUI.LiveHeapProfile._startedPromise;
-  }
-
-  /**
-   * @override
-   * @param {!SDK.HeapProfilerModel} model
-   */
-  modelAdded(model) {
-    model.startSampling(1024);
-  }
-
-  /**
-   * @override
-   * @param {!SDK.HeapProfilerModel} model
-   */
-  modelRemoved(model) {
-    model.stopSampling();
-  }
-
-  async onUpdateProfiles() {
-    const models = SDK.targetManager.models(SDK.HeapProfilerModel);
-    const profiles = await Promise.all(models.map(model => model.getSamplingProfile()));
-    const lineLevelProfile = PerfUI.LineLevelProfile.Memory.instance();
-    lineLevelProfile.reset();
-    for (let i = 0; i < profiles.length; ++i) {
-      if (profiles[i])
-        lineLevelProfile.appendHeapProfile(profiles[i], models[i].target());
-    }
-    const updateInterval = Host.isUnderTest() ? 10 : 5000;
-    setTimeout(() => requestIdleCallback(() => this.onUpdateProfiles()), updateInterval);
-  }
-};
diff --git a/third_party/blink/renderer/devtools/front_end/perf_ui/module.json b/third_party/blink/renderer/devtools/front_end/perf_ui/module.json
index 476922e1..ce8d46c9 100644
--- a/third_party/blink/renderer/devtools/front_end/perf_ui/module.json
+++ b/third_party/blink/renderer/devtools/front_end/perf_ui/module.json
@@ -1,11 +1,6 @@
 {
     "extensions": [
         {
-            "type": "late-initialization",
-            "className": "PerfUI.LiveHeapProfile",
-            "experiment": "liveHeapProfile"
-        },
-        {
             "type": "@SourceFrame.LineDecorator",
             "className": "PerfUI.LineLevelProfile.LineDecorator",
             "decoratorType": "performance"
@@ -56,7 +51,6 @@
         "FlameChart.js",
         "GCActionDelegate.js",
         "LineLevelProfile.js",
-        "LiveHeapProfile.js",
         "NetworkPriorities.js",
         "OverviewGrid.js",
         "PieChart.js",
diff --git a/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js b/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js
index 32cb07e..8848d38a 100644
--- a/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js
+++ b/third_party/blink/renderer/devtools/front_end/test_runner/TestRunner.js
@@ -1210,7 +1210,6 @@
  */
 TestRunner.loadedModules = function() {
   return self.runtime._modules.filter(module => module._loadedForTest)
-      .filter(module => module.name() !== 'help')
       .filter(module => module.name().indexOf('test_runner') === -1);
 };
 
diff --git a/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css b/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css
index 22df9a2c9..b68d407 100644
--- a/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css
+++ b/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css
@@ -9,7 +9,12 @@
     overflow: visible !important;
 }
 
-.CodeMirror-gutter-performance,
+.CodeMirror-gutter-performance {
+    width: 60px;
+    background-color: white;
+    margin-left: 3px;
+}
+
 .CodeMirror-gutter-memory {
     width: 60px;
     background-color: white;
@@ -432,8 +437,7 @@
 }
 
 .CodeMirror .text-editor-line-marker-text span.line-marker-units {
-    color: #555;
-    font-size: 75%;
+    color: #999;
     margin-left: 3px;
 }
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index ca99704..ab266b21 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -730,9 +730,7 @@
     ChildrenChanged(element->parentNode());
   } else {
     // Refresh the focusable state on the exposed object.
-    // TODO(accessibility) find out why using MarkAXObjectDirty(obj, false)
-    // regresses Slack performance, see https://crbug.com/936944.
-    PostNotification(obj, ax::mojom::Event::kValueChanged);
+    MarkAXObjectDirty(obj, false);
   }
 }
 
@@ -971,9 +969,6 @@
 
 void AXObjectCacheImpl::ImageLoaded(LayoutObject* layout_object) {
   AXObject* obj = Get(layout_object);
-  if (!obj)
-    return;
-
   MarkAXObjectDirty(obj, false);
 }
 
@@ -1128,7 +1123,7 @@
   else if (attr_name == kTabindexAttr)
     FocusableChanged(element);
   else if (attr_name == kDisabledAttr)
-    MarkAXObjectDirty(Get(element), false);
+    MarkElementDirty(element, false);
 
   if (!attr_name.LocalName().StartsWith("aria-"))
     return;
@@ -1350,7 +1345,7 @@
 }
 
 void AXObjectCacheImpl::MarkAXObjectDirty(AXObject* obj, bool subtree) {
-  if (!document_ || !document_->View() ||
+  if (!obj || !document_ || !document_->View() ||
       !document_->View()->GetFrame().GetPage())
     return;
 
@@ -1361,8 +1356,9 @@
 }
 
 void AXObjectCacheImpl::MarkElementDirty(const Element* element, bool subtree) {
-  if (AXObject* obj = Get(element))
-    MarkAXObjectDirty(obj, subtree);
+  // Warning, if no AXObject exists for element, nothing is marked dirty,
+  // including descendant objects when subtree == true.
+  MarkAXObjectDirty(Get(element), subtree);
 }
 
 void AXObjectCacheImpl::HandleFocusedUIElementChanged(Node* old_focused_node,
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_test.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_test.cc
index 1fc3b46..1089348 100644
--- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_test.cc
+++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client_test.cc
@@ -11,6 +11,7 @@
 #include "base/test/test_simple_task_runner.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
 #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
 #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
@@ -60,26 +61,6 @@
     waitable_event->Signal();
   }
 
-  // Returns false when a script evaluation error happens.
-  bool EvaluateScriptModule(AnimationWorkletGlobalScope* global_scope,
-                            const String& source_code) {
-    ScriptState* script_state =
-        global_scope->ScriptController()->GetScriptState();
-    EXPECT_TRUE(script_state);
-    ScriptState::Scope scope(script_state);
-
-    const KURL js_url("https://example.com/worklet.js");
-    ScriptModule module = ScriptModule::Compile(
-        script_state->GetIsolate(), source_code, js_url, js_url,
-        ScriptFetchOptions(), TextPosition::MinimumPosition(),
-        ASSERT_NO_EXCEPTION);
-    EXPECT_FALSE(module.IsNull());
-    ScriptValue exception = module.Instantiate(script_state);
-    EXPECT_TRUE(exception.IsEmpty());
-    ScriptValue value = module.Evaluate(script_state);
-    return value.IsEmpty();
-  }
-
   using TestCallback =
       void (AnimationWorkletProxyClientTest::*)(WorkerThread*,
                                                 AnimationWorkletProxyClient*,
@@ -124,7 +105,8 @@
       )JS";
 
     auto* global_scope = To<AnimationWorkletGlobalScope>(thread->GlobalScope());
-    ASSERT_TRUE(EvaluateScriptModule(global_scope, source_code));
+    ASSERT_TRUE(global_scope->ScriptController()->Evaluate(
+        ScriptSourceCode(source_code), SanitizeScriptErrors::kDoNotSanitize));
 
     std::unique_ptr<AnimationWorkletInput> state =
         std::make_unique<AnimationWorkletInput>();
diff --git a/third_party/blink/renderer/modules/cache_storage/BUILD.gn b/third_party/blink/renderer/modules/cache_storage/BUILD.gn
index 2096bc91..b221c15 100644
--- a/third_party/blink/renderer/modules/cache_storage/BUILD.gn
+++ b/third_party/blink/renderer/modules/cache_storage/BUILD.gn
@@ -12,6 +12,8 @@
     "cache_storage.h",
     "cache_storage_error.cc",
     "cache_storage_error.h",
+    "cache_storage_trace_utils.cc",
+    "cache_storage_trace_utils.h",
     "global_cache_storage.cc",
     "global_cache_storage.h",
     "inspector_cache_storage_agent.cc",
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc
index ea66a8f4..880dc05 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -33,11 +33,14 @@
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/modules/cache_storage/cache_storage.h"
 #include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h"
+#include "third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h"
 #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 #include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
 #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
 #include "third_party/blink/renderer/platform/network/http_names.h"
 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
@@ -116,9 +119,10 @@
       Cache* cache,
       const String& method_name,
       const HeapVector<Member<Request>>& requests,
-      const ExceptionState& exception_state) {
+      const ExceptionState& exception_state,
+      int64_t trace_id) {
     FetchResolvedForAdd* self = MakeGarbageCollected<FetchResolvedForAdd>(
-        script_state, cache, method_name, requests, exception_state);
+        script_state, cache, method_name, requests, exception_state, trace_id);
     return self->BindToV8Function();
   }
 
@@ -126,16 +130,23 @@
                       Cache* cache,
                       const String& method_name,
                       const HeapVector<Member<Request>>& requests,
-                      const ExceptionState& exception_state)
+                      const ExceptionState& exception_state,
+                      int64_t trace_id)
       : ScriptFunction(script_state),
         cache_(cache),
         method_name_(method_name),
         requests_(requests),
         context_type_(exception_state.Context()),
         property_name_(exception_state.PropertyName()),
-        interface_name_(exception_state.InterfaceName()) {}
+        interface_name_(exception_state.InterfaceName()),
+        trace_id_(trace_id) {}
 
   ScriptValue Call(ScriptValue value) override {
+    TRACE_EVENT_WITH_FLOW0(
+        "CacheStorage", "Cache::FetchResolverForAdd::Call",
+        TRACE_ID_GLOBAL(trace_id_),
+        TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
     ExceptionState exception_state(GetScriptState()->GetIsolate(),
                                    context_type_, property_name_,
                                    interface_name_);
@@ -168,8 +179,9 @@
     for (const auto& response : responses)
       RecordResponseTypeForAdd(response);
 
-    ScriptPromise put_promise = cache_->PutImpl(
-        GetScriptState(), method_name_, requests_, responses, exception_state);
+    ScriptPromise put_promise =
+        cache_->PutImpl(GetScriptState(), method_name_, requests_, responses,
+                        exception_state, trace_id_);
     return ScriptValue(GetScriptState(), put_promise.V8Value());
   }
 
@@ -186,6 +198,7 @@
   ExceptionState::ContextType context_type_;
   const char* property_name_;
   const char* interface_name_;
+  const int64_t trace_id_;
 };
 
 class Cache::BarrierCallbackForPut final
@@ -194,11 +207,13 @@
   BarrierCallbackForPut(wtf_size_t number_of_operations,
                         Cache* cache,
                         const String& method_name,
-                        ScriptPromiseResolver* resolver)
+                        ScriptPromiseResolver* resolver,
+                        int64_t trace_id)
       : number_of_remaining_operations_(number_of_operations),
         cache_(cache),
         method_name_(method_name),
-        resolver_(resolver) {
+        resolver_(resolver),
+        trace_id_(trace_id) {
     DCHECK_LT(0, number_of_remaining_operations_);
     batch_operations_.resize(number_of_operations);
   }
@@ -206,6 +221,11 @@
   void OnSuccess(wtf_size_t index,
                  mojom::blink::BatchOperationPtr batch_operation) {
     DCHECK_LT(index, batch_operations_.size());
+    TRACE_EVENT_WITH_FLOW1(
+        "CacheStorage", "Cache::BarrierCallbackForPut::OnSuccess",
+        TRACE_ID_GLOBAL(trace_id_),
+        TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "batch_operation",
+        CacheStorageTracedValue(batch_operation));
     if (!StillActive())
       return;
     batch_operations_[index] = std::move(batch_operation);
@@ -220,11 +240,18 @@
     cache_->cache_ptr_->Batch(
         std::move(batch_operations_),
         RuntimeEnabledFeatures::CacheStorageAddAllRejectsDuplicatesEnabled(),
+        trace_id_,
         WTF::Bind(
             [](const String& method_name, ScriptPromiseResolver* resolver,
-               base::TimeTicks start_time, int operation_count, Cache* _,
+               base::TimeTicks start_time, int operation_count,
+               int64_t trace_id, Cache* _,
                mojom::blink::CacheStorageVerboseErrorPtr error) {
               base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage",
+                  "Cache::BarrierCallbackForPut::OnSuccess::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                  CacheStorageTracedValue(error->value));
               if (operation_count > 1) {
                 UMA_HISTOGRAM_LONG_TIMES(
                     "ServiceWorkerCache.Cache.Renderer.PutMany", elapsed);
@@ -270,7 +297,7 @@
               }
             },
             method_name_, WrapPersistent(resolver_.Get()),
-            base::TimeTicks::Now(), operation_count,
+            base::TimeTicks::Now(), operation_count, trace_id_,
             WrapPersistent(cache_.Get())));
   }
 
@@ -342,6 +369,7 @@
   const String method_name_;
   Member<ScriptPromiseResolver> resolver_;
   Vector<mojom::blink::BatchOperationPtr> batch_operations_;
+  const int64_t trace_id_;
 };
 
 class Cache::BlobHandleCallbackForPut final
@@ -402,13 +430,15 @@
                                 BarrierCallbackForPut* barrier_callback,
                                 Request* request,
                                 Response* response,
-                                CodeCacheGenerateTiming timing)
+                                CodeCacheGenerateTiming timing,
+                                int64_t trace_id)
       : script_state_(script_state),
         cache_(cache),
         index_(index),
         barrier_callback_(barrier_callback),
         mime_type_(response->InternalMIMEType()),
-        timing_(timing) {
+        timing_(timing),
+        trace_id_(trace_id) {
     fetch_api_request_ = request->CreateFetchAPIRequest();
     fetch_api_response_ = response->PopulateFetchAPIResponse();
     url_ = fetch_api_request_->url;
@@ -420,6 +450,12 @@
   ~CodeCacheHandleCallbackForPut() override = default;
 
   void DidFetchDataLoadedArrayBuffer(DOMArrayBuffer* array_buffer) override {
+    TRACE_EVENT_WITH_FLOW1(
+        "CacheStorage",
+        "Cache::CodeCacheHandleCallbackForPut::DidFetchDataLoadedArrayBuffer",
+        TRACE_ID_GLOBAL(trace_id_),
+        TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "url",
+        CacheStorageTracedValue(url_.GetString()));
     base::Time response_time = fetch_api_response_->response_time;
     mojom::blink::BatchOperationPtr batch_operation =
         mojom::blink::BatchOperation::New();
@@ -493,6 +529,10 @@
 
   scoped_refptr<CachedMetadata> GenerateFullCodeCache(
       DOMArrayBuffer* array_buffer) {
+    TRACE_EVENT1("CacheStorage",
+                 "Cache::CodeCacheHandleCallbackForPut::GenerateFullCodeCache",
+                 "url", CacheStorageTracedValue(url_.GetString()));
+
     // Currently we only support UTF8 encoding.
     // TODO(horo): Use the charset in Content-type header of the response.
     // See crbug.com/743311.
@@ -511,6 +551,13 @@
                                    DOMArrayBuffer* array_buffer,
                                    base::Time response_time,
                                    base::TimeTicks) {
+    TRACE_EVENT_WITH_FLOW1(
+        "CacheStorage",
+        "Cache::CodeCacheHandleCallbackForPut::GenerateCodeCacheOnIdleTask",
+        TRACE_ID_GLOBAL(trace_id_),
+        TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "url",
+        CacheStorageTracedValue(url_.GetString()));
+
     ServiceWorkerGlobalScope* global_scope = GetServiceWorkerGlobalScope();
     if (!global_scope)
       return;
@@ -522,7 +569,7 @@
       return;
     }
     cache_->cache_ptr_->SetSideData(
-        url_, response_time, cached_metadata->SerializedData(),
+        url_, response_time, cached_metadata->SerializedData(), trace_id_,
         WTF::Bind(
             [](ServiceWorkerGlobalScope* global_scope, int task_id,
                mojom::blink::CacheStorageError error) {
@@ -539,6 +586,7 @@
   KURL url_;
   V8CodeCache::OpaqueMode opaque_mode_;
   CodeCacheGenerateTiming timing_;
+  const int64_t trace_id_;
 
   mojom::blink::FetchAPIRequestPtr fetch_api_request_;
   mojom::blink::FetchAPIResponsePtr fetch_api_response_;
@@ -641,18 +689,22 @@
                          Response* response,
                          ExceptionState& exception_state) {
   DCHECK(!request.IsNull());
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "Cache::put",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
   if (request.IsRequest()) {
     return PutImpl(script_state, "Cache.put()",
                    HeapVector<Member<Request>>(1, request.GetAsRequest()),
-                   HeapVector<Member<Response>>(1, response), exception_state);
+                   HeapVector<Member<Response>>(1, response), exception_state,
+                   trace_id);
   }
   Request* new_request =
       Request::Create(script_state, request.GetAsUSVString(), exception_state);
   if (exception_state.HadException())
     return ScriptPromise();
-  return PutImpl(script_state, "Cache.put()",
-                 HeapVector<Member<Request>>(1, new_request),
-                 HeapVector<Member<Response>>(1, response), exception_state);
+  return PutImpl(
+      script_state, "Cache.put()", HeapVector<Member<Request>>(1, new_request),
+      HeapVector<Member<Response>>(1, response), exception_state, trace_id);
 }
 
 ScriptPromise Cache::keys(ScriptState* script_state, ExceptionState&) {
@@ -690,6 +742,17 @@
 ScriptPromise Cache::MatchImpl(ScriptState* script_state,
                                const Request* request,
                                const CacheQueryOptions* options) {
+  mojom::blink::FetchAPIRequestPtr mojo_request =
+      request->CreateFetchAPIRequest();
+  mojom::blink::CacheQueryOptionsPtr mojo_options =
+      mojom::blink::CacheQueryOptions::From(options);
+
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW2("CacheStorage", "Cache::MatchImpl",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
+                         "request", CacheStorageTracedValue(mojo_request),
+                         "options", CacheStorageTracedValue(mojo_options));
+
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   const ScriptPromise promise = resolver->Promise();
   if (request->method() != http_names::kGET && !options->ignoreMethod()) {
@@ -701,11 +764,10 @@
   // alive during the operation.  Otherwise GC might prevent the callback
   // from ever being executed.
   cache_ptr_->Match(
-      request->CreateFetchAPIRequest(),
-      mojom::blink::CacheQueryOptions::From(options),
+      std::move(mojo_request), std::move(mojo_options), trace_id,
       WTF::Bind(
           [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
-             const CacheQueryOptions* options, Cache* _,
+             const CacheQueryOptions* options, int64_t trace_id, Cache* _,
              mojom::blink::MatchResultPtr result) {
             base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
             UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Renderer.Match",
@@ -719,6 +781,10 @@
                 resolver->GetExecutionContext()->IsContextDestroyed())
               return;
             if (result->is_status()) {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "Cache::MatchImpl::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                  CacheStorageTracedValue(result->get_status()));
               switch (result->get_status()) {
                 case mojom::CacheStorageError::kErrorNotFound:
                   UMA_HISTOGRAM_LONG_TIMES(
@@ -731,6 +797,10 @@
                   break;
               }
             } else {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "Cache::MatchImpl::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN,
+                  "response", CacheStorageTracedValue(result->get_response()));
               UMA_HISTOGRAM_LONG_TIMES(
                   "ServiceWorkerCache.Cache.Renderer.Match.Hit", elapsed);
               ScriptState::Scope scope(resolver->GetScriptState());
@@ -739,7 +809,7 @@
             }
           },
           WrapPersistent(resolver), base::TimeTicks::Now(),
-          WrapPersistent(options), WrapPersistent(this)));
+          WrapPersistent(options), trace_id, WrapPersistent(this)));
 
   return promise;
 }
@@ -747,28 +817,36 @@
 ScriptPromise Cache::MatchAllImpl(ScriptState* script_state,
                                   const Request* request,
                                   const CacheQueryOptions* options) {
-  mojom::blink::FetchAPIRequestPtr fetch_api_request;
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   const ScriptPromise promise = resolver->Promise();
 
+  mojom::blink::CacheQueryOptionsPtr mojo_options =
+      mojom::blink::CacheQueryOptions::From(options);
+  mojom::blink::FetchAPIRequestPtr fetch_api_request;
   if (request) {
     fetch_api_request = request->CreateFetchAPIRequest();
+  }
 
-    if (request->method() != http_names::kGET && !options->ignoreMethod()) {
-      resolver->Resolve(HeapVector<Member<Response>>());
-      return promise;
-    }
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW2("CacheStorage", "Cache::MatchAllImpl",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
+                         "request", CacheStorageTracedValue(fetch_api_request),
+                         "options", CacheStorageTracedValue(mojo_options));
+
+  if (request && request->method() != http_names::kGET &&
+      !options->ignoreMethod()) {
+    resolver->Resolve(HeapVector<Member<Response>>());
+    return promise;
   }
 
   // Make sure to bind the Cache object to keep the mojo interface pointer
   // alive during the operation.  Otherwise GC might prevent the callback
   // from ever being executed.
   cache_ptr_->MatchAll(
-      std::move(fetch_api_request),
-      mojom::blink::CacheQueryOptions::From(options),
+      std::move(fetch_api_request), std::move(mojo_options), trace_id,
       WTF::Bind(
           [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
-             const CacheQueryOptions* options, Cache* _,
+             const CacheQueryOptions* options, int64_t trace_id, Cache* _,
              mojom::blink::MatchAllResultPtr result) {
             UMA_HISTOGRAM_LONG_TIMES(
                 "ServiceWorkerCache.Cache.Renderer.MatchAll",
@@ -777,9 +855,18 @@
                 resolver->GetExecutionContext()->IsContextDestroyed())
               return;
             if (result->is_status()) {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "Cache::MatchAllImpl::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                  CacheStorageTracedValue(result->get_status()));
               resolver->Reject(
                   CacheStorageError::CreateException(result->get_status()));
             } else {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "Cache::MatchAllImpl::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN,
+                  "response_list",
+                  CacheStorageTracedValue(result->get_responses()));
               ScriptState::Scope scope(resolver->GetScriptState());
               HeapVector<Member<Response>> responses;
               responses.ReserveInitialCapacity(result->get_responses().size());
@@ -791,7 +878,7 @@
             }
           },
           WrapPersistent(resolver), base::TimeTicks::Now(),
-          WrapPersistent(options), WrapPersistent(this)));
+          WrapPersistent(options), trace_id, WrapPersistent(this)));
   return promise;
 }
 
@@ -799,6 +886,10 @@
                                 const String& method_name,
                                 const HeapVector<Member<Request>>& requests,
                                 ExceptionState& exception_state) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "Cache::AddAllImpl",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   if (requests.IsEmpty())
     return ScriptPromise::CastUndefined(script_state);
 
@@ -829,7 +920,7 @@
 
   return ScriptPromise::All(script_state, promises)
       .Then(FetchResolvedForAdd::Create(script_state, this, method_name,
-                                        requests, exception_state));
+                                        requests, exception_state, trace_id));
 }
 
 ScriptPromise Cache::DeleteImpl(ScriptState* script_state,
@@ -837,10 +928,6 @@
                                 const CacheQueryOptions* options) {
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   const ScriptPromise promise = resolver->Promise();
-  if (request->method() != http_names::kGET && !options->ignoreMethod()) {
-    resolver->Resolve(false);
-    return promise;
-  }
 
   Vector<mojom::blink::BatchOperationPtr> batch_operations;
   batch_operations.push_back(mojom::blink::BatchOperation::New());
@@ -849,19 +936,36 @@
   operation->request = request->CreateFetchAPIRequest();
   operation->match_options = mojom::blink::CacheQueryOptions::From(options);
 
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW2("CacheStorage", "Cache::DeleteImpl",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
+                         "request", CacheStorageTracedValue(operation->request),
+                         "options",
+                         CacheStorageTracedValue(operation->match_options));
+
+  if (request->method() != http_names::kGET && !options->ignoreMethod()) {
+    resolver->Resolve(false);
+    return promise;
+  }
+
   // Make sure to bind the Cache object to keep the mojo interface pointer
   // alive during the operation.  Otherwise GC might prevent the callback
   // from ever being executed.
   cache_ptr_->Batch(
       std::move(batch_operations),
       RuntimeEnabledFeatures::CacheStorageAddAllRejectsDuplicatesEnabled(),
+      trace_id,
       WTF::Bind(
           [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
-             const CacheQueryOptions* options, Cache* _,
+             const CacheQueryOptions* options, int64_t trace_id, Cache* _,
              mojom::blink::CacheStorageVerboseErrorPtr error) {
             UMA_HISTOGRAM_LONG_TIMES(
                 "ServiceWorkerCache.Cache.Renderer.DeleteOne",
                 base::TimeTicks::Now() - start_time);
+            TRACE_EVENT_WITH_FLOW1(
+                "CacheStorage", "Cache::DeleteImpl::Callback",
+                TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                CacheStorageTracedValue(error->value));
             ExecutionContext* context = resolver->GetExecutionContext();
             if (!context || context->IsContextDestroyed())
               return;
@@ -893,7 +997,7 @@
             }
           },
           WrapPersistent(resolver), base::TimeTicks::Now(),
-          WrapPersistent(options), WrapPersistent(this)));
+          WrapPersistent(options), trace_id, WrapPersistent(this)));
   return promise;
 }
 
@@ -901,12 +1005,16 @@
                              const String& method_name,
                              const HeapVector<Member<Request>>& requests,
                              const HeapVector<Member<Response>>& responses,
-                             ExceptionState& exception_state) {
+                             ExceptionState& exception_state,
+                             int64_t trace_id) {
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "Cache::PutImpl",
+                         TRACE_ID_GLOBAL(trace_id),
+                         TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   const ScriptPromise promise = resolver->Promise();
   BarrierCallbackForPut* barrier_callback =
-      MakeGarbageCollected<BarrierCallbackForPut>(requests.size(), this,
-                                                  method_name, resolver);
+      MakeGarbageCollected<BarrierCallbackForPut>(
+          requests.size(), this, method_name, resolver, trace_id);
 
   for (wtf_size_t i = 0; i < requests.size(); ++i) {
     KURL url(NullURL(), requests[i]->url());
@@ -954,7 +1062,7 @@
           loader,
           MakeGarbageCollected<CodeCacheHandleCallbackForPut>(
               script_state, this, i, barrier_callback, requests[i],
-              responses[i], cache_generate_timing),
+              responses[i], cache_generate_timing, trace_id),
           exception_state);
       if (exception_state.HadException()) {
         barrier_callback->OnError("Could not inspect response body state");
@@ -993,28 +1101,36 @@
 ScriptPromise Cache::KeysImpl(ScriptState* script_state,
                               const Request* request,
                               const CacheQueryOptions* options) {
-  mojom::blink::FetchAPIRequestPtr fetch_api_request;
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   const ScriptPromise promise = resolver->Promise();
 
+  mojom::blink::CacheQueryOptionsPtr mojo_options =
+      mojom::blink::CacheQueryOptions::From(options);
+  mojom::blink::FetchAPIRequestPtr fetch_api_request;
   if (request) {
     fetch_api_request = request->CreateFetchAPIRequest();
+  }
 
-    if (request->method() != http_names::kGET && !options->ignoreMethod()) {
-      resolver->Resolve(HeapVector<Member<Response>>());
-      return promise;
-    }
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW2("CacheStorage", "Cache::DeleteImpl",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
+                         "request", CacheStorageTracedValue(fetch_api_request),
+                         "options", CacheStorageTracedValue(mojo_options));
+
+  if (request && request->method() != http_names::kGET &&
+      !options->ignoreMethod()) {
+    resolver->Resolve(HeapVector<Member<Response>>());
+    return promise;
   }
 
   // Make sure to bind the Cache object to keep the mojo interface pointer
   // alive during the operation.  Otherwise GC might prevent the callback
   // from ever being executed.
   cache_ptr_->Keys(
-      std::move(fetch_api_request),
-      mojom::blink::CacheQueryOptions::From(options),
+      std::move(fetch_api_request), std::move(mojo_options), trace_id,
       WTF::Bind(
           [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
-             const CacheQueryOptions* options, Cache* _,
+             const CacheQueryOptions* options, int64_t trace_id, Cache* _,
              mojom::blink::CacheKeysResultPtr result) {
             UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Renderer.Keys",
                                      base::TimeTicks::Now() - start_time);
@@ -1022,9 +1138,17 @@
                 resolver->GetExecutionContext()->IsContextDestroyed())
               return;
             if (result->is_status()) {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "Cache::KeysImpl::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                  CacheStorageTracedValue(result->get_status()));
               resolver->Reject(
                   CacheStorageError::CreateException(result->get_status()));
             } else {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "Cache::KeysImpl::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                  CacheStorageTracedValue(result->get_keys()));
               ScriptState::Scope scope(resolver->GetScriptState());
               HeapVector<Member<Request>> requests;
               requests.ReserveInitialCapacity(result->get_keys().size());
@@ -1036,7 +1160,7 @@
             }
           },
           WrapPersistent(resolver), base::TimeTicks::Now(),
-          WrapPersistent(options), WrapPersistent(this)));
+          WrapPersistent(options), trace_id, WrapPersistent(this)));
   return promise;
 }
 
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.h b/third_party/blink/renderer/modules/cache_storage/cache.h
index 78c8aeb..5b07b1c 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache.h
+++ b/third_party/blink/renderer/modules/cache_storage/cache.h
@@ -114,7 +114,8 @@
                         const String& method_name,
                         const HeapVector<Member<Request>>&,
                         const HeapVector<Member<Response>>&,
-                        ExceptionState&);
+                        ExceptionState&,
+                        int64_t trace_id);
   ScriptPromise KeysImpl(ScriptState*,
                          const Request*,
                          const CacheQueryOptions*);
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
index c8a4e5c..e810c2e2 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
@@ -10,6 +10,8 @@
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
+#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -17,8 +19,11 @@
 #include "third_party/blink/renderer/core/fetch/response.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h"
+#include "third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h"
 #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
 #include "third_party/blink/renderer/platform/network/http_names.h"
 
 namespace mojo {
@@ -56,17 +61,23 @@
 
 ScriptPromise CacheStorage::open(ScriptState* script_state,
                                  const String& cache_name) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW1("CacheStorage", "CacheStorage::Open",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
+                         "name", CacheStorageTracedValue(cache_name));
+
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
 
   // Make sure to bind the CacheStorage object to keep the mojo interface
   // pointer alive during the operation.  Otherwise GC might prevent the
   // callback from ever being executed.
   cache_storage_ptr_->Open(
-      cache_name,
+      cache_name, trace_id,
       WTF::Bind(
           [](ScriptPromiseResolver* resolver,
              GlobalFetch::ScopedFetcher* fetcher, base::TimeTicks start_time,
-             CacheStorage* cache_storage, mojom::blink::OpenResultPtr result) {
+             int64_t trace_id, CacheStorage* cache_storage,
+             mojom::blink::OpenResultPtr result) {
             UMA_HISTOGRAM_TIMES("ServiceWorkerCache.CacheStorage.Renderer.Open",
                                 base::TimeTicks::Now() - start_time);
             if (!resolver->GetExecutionContext() ||
@@ -74,6 +85,10 @@
               return;
             }
             if (result->is_status()) {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "CacheStorage::Open::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                  CacheStorageTracedValue(result->get_status()));
               switch (result->get_status()) {
                 case mojom::blink::CacheStorageError::kErrorNotFound:
                 case mojom::blink::CacheStorageError::kErrorStorage:
@@ -85,6 +100,10 @@
                   break;
               }
             } else {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "CacheStorage::Open::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                  "success");
               // See https://bit.ly/2S0zRAS for task types.
               resolver->Resolve(Cache::Create(
                   fetcher, cache_storage, std::move(result->get_cache()),
@@ -93,25 +112,35 @@
             }
           },
           WrapPersistent(resolver), WrapPersistent(scoped_fetcher_.Get()),
-          TimeTicks::Now(), WrapPersistent(this)));
+          TimeTicks::Now(), trace_id, WrapPersistent(this)));
 
   return resolver->Promise();
 }
 
 ScriptPromise CacheStorage::has(ScriptState* script_state,
                                 const String& cache_name) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW1("CacheStorage", "CacheStorage::Has",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
+                         "name", CacheStorageTracedValue(cache_name));
+
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
 
   // Make sure to bind the CacheStorage object to keep the mojo interface
   // pointer alive during the operation.  Otherwise GC might prevent the
   // callback from ever being executed.
   cache_storage_ptr_->Has(
-      cache_name,
+      cache_name, trace_id,
       WTF::Bind(
           [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
-             CacheStorage* _, mojom::blink::CacheStorageError result) {
+             int64_t trace_id, CacheStorage* _,
+             mojom::blink::CacheStorageError result) {
             UMA_HISTOGRAM_TIMES("ServiceWorkerCache.CacheStorage.Renderer.Has",
                                 base::TimeTicks::Now() - start_time);
+            TRACE_EVENT_WITH_FLOW1(
+                "CacheStorage", "CacheStorage::Has::Callback",
+                TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                CacheStorageTracedValue(result));
             if (!resolver->GetExecutionContext() ||
                 resolver->GetExecutionContext()->IsContextDestroyed())
               return;
@@ -127,26 +156,37 @@
                 break;
             }
           },
-          WrapPersistent(resolver), TimeTicks::Now(), WrapPersistent(this)));
+          WrapPersistent(resolver), TimeTicks::Now(), trace_id,
+          WrapPersistent(this)));
 
   return resolver->Promise();
 }
 
 ScriptPromise CacheStorage::Delete(ScriptState* script_state,
                                    const String& cache_name) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW1("CacheStorage", "CacheStorage::Delete",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
+                         "name", CacheStorageTracedValue(cache_name));
+
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
 
   // Make sure to bind the CacheStorage object to keep the mojo interface
   // pointer alive during the operation.  Otherwise GC might prevent the
   // callback from ever being executed.
   cache_storage_ptr_->Delete(
-      cache_name,
+      cache_name, trace_id,
       WTF::Bind(
           [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
-             CacheStorage* _, mojom::blink::CacheStorageError result) {
+             int64_t trace_id, CacheStorage* _,
+             mojom::blink::CacheStorageError result) {
             UMA_HISTOGRAM_TIMES(
                 "ServiceWorkerCache.CacheStorage.Renderer.Delete",
                 base::TimeTicks::Now() - start_time);
+            TRACE_EVENT_WITH_FLOW1(
+                "CacheStorage", "CacheStorage::Delete::Callback",
+                TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                CacheStorageTracedValue(result));
             if (!resolver->GetExecutionContext() ||
                 resolver->GetExecutionContext()->IsContextDestroyed())
               return;
@@ -163,28 +203,40 @@
                 break;
             }
           },
-          WrapPersistent(resolver), TimeTicks::Now(), WrapPersistent(this)));
+          WrapPersistent(resolver), TimeTicks::Now(), trace_id,
+          WrapPersistent(this)));
 
   return resolver->Promise();
 }
 
 ScriptPromise CacheStorage::keys(ScriptState* script_state) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage", "CacheStorage::Keys",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
 
   // Make sure to bind the CacheStorage object to keep the mojo interface
   // pointer alive during the operation.  Otherwise GC might prevent the
   // callback from ever being executed.
-  cache_storage_ptr_->Keys(WTF::Bind(
-      [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
-         CacheStorage* _, const Vector<String>& keys) {
-        UMA_HISTOGRAM_TIMES("ServiceWorkerCache.CacheStorage.Renderer.Keys",
-                            base::TimeTicks::Now() - start_time);
-        if (!resolver->GetExecutionContext() ||
-            resolver->GetExecutionContext()->IsContextDestroyed())
-          return;
-        resolver->Resolve(keys);
-      },
-      WrapPersistent(resolver), TimeTicks::Now(), WrapPersistent(this)));
+  cache_storage_ptr_->Keys(
+      trace_id,
+      WTF::Bind(
+          [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
+             int64_t trace_id, CacheStorage* _, const Vector<String>& keys) {
+            UMA_HISTOGRAM_TIMES("ServiceWorkerCache.CacheStorage.Renderer.Keys",
+                                base::TimeTicks::Now() - start_time);
+            TRACE_EVENT_WITH_FLOW1(
+                "CacheStorage", "CacheStorage::Keys::Callback",
+                TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "key_list",
+                CacheStorageTracedValue(keys));
+            if (!resolver->GetExecutionContext() ||
+                resolver->GetExecutionContext()->IsContextDestroyed())
+              return;
+            resolver->Resolve(keys);
+          },
+          WrapPersistent(resolver), TimeTicks::Now(), trace_id,
+          WrapPersistent(this)));
 
   return resolver->Promise();
 }
@@ -207,6 +259,16 @@
 ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state,
                                       const Request* request,
                                       const MultiCacheQueryOptions* options) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  mojom::blink::FetchAPIRequestPtr mojo_request =
+      request->CreateFetchAPIRequest();
+  mojom::blink::MultiCacheQueryOptionsPtr mojo_options =
+      mojom::blink::MultiCacheQueryOptions::From(options);
+  TRACE_EVENT_WITH_FLOW2("CacheStorage", "CacheStorage::MatchImpl",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT,
+                         "request", CacheStorageTracedValue(mojo_request),
+                         "options", CacheStorageTracedValue(mojo_options));
+
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   const ScriptPromise promise = resolver->Promise();
 
@@ -219,12 +281,11 @@
   // pointer alive during the operation.  Otherwise GC might prevent the
   // callback from ever being executed.
   cache_storage_ptr_->Match(
-      request->CreateFetchAPIRequest(),
-      mojom::blink::MultiCacheQueryOptions::From(options),
+      std::move(mojo_request), std::move(mojo_options), trace_id,
       WTF::Bind(
           [](ScriptPromiseResolver* resolver, base::TimeTicks start_time,
-             const MultiCacheQueryOptions* options, CacheStorage* _,
-             mojom::blink::MatchResultPtr result) {
+             const MultiCacheQueryOptions* options, int64_t trace_id,
+             CacheStorage* _, mojom::blink::MatchResultPtr result) {
             base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
             if (!options->hasCacheName() || options->cacheName().IsEmpty()) {
               UMA_HISTOGRAM_LONG_TIMES(
@@ -239,6 +300,10 @@
                 resolver->GetExecutionContext()->IsContextDestroyed())
               return;
             if (result->is_status()) {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "CacheStorage::MatchImpl::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
+                  CacheStorageTracedValue(result->get_status()));
               switch (result->get_status()) {
                 case mojom::CacheStorageError::kErrorNotFound:
                 case mojom::CacheStorageError::kErrorStorage:
@@ -251,13 +316,17 @@
                   break;
               }
             } else {
+              TRACE_EVENT_WITH_FLOW1(
+                  "CacheStorage", "CacheStorage::MatchImpl::Callback",
+                  TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN,
+                  "response", CacheStorageTracedValue(result->get_response()));
               ScriptState::Scope scope(resolver->GetScriptState());
               resolver->Resolve(Response::Create(resolver->GetScriptState(),
                                                  *result->get_response()));
             }
           },
           WrapPersistent(resolver), TimeTicks::Now(), WrapPersistent(options),
-          WrapPersistent(this)));
+          trace_id, WrapPersistent(this)));
 
   return promise;
 }
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.cc b/third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.cc
new file mode 100644
index 0000000..ae45457
--- /dev/null
+++ b/third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.cc
@@ -0,0 +1,126 @@
+// 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 "third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h"
+
+#include <memory>
+
+#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
+
+namespace blink {
+
+namespace {
+
+template <typename T>
+std::string MojoEnumToString(T value) {
+  std::ostringstream oss;
+  oss << value;
+  return oss.str();
+}
+
+}  // namespace
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(const String& string) {
+  std::unique_ptr<TracedValue> value = TracedValue::Create();
+  value->SetString("string", string);
+  return value;
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::FetchAPIRequestPtr& request) {
+  std::unique_ptr<TracedValue> value = TracedValue::Create();
+  if (request) {
+    value->SetString("url", request->url.GetString());
+    value->SetString("method",
+                     String(MojoEnumToString(request->method).data()));
+    value->SetString("mode", String(MojoEnumToString(request->mode).data()));
+  }
+  return value;
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const WTF::Vector<mojom::blink::FetchAPIRequestPtr>& requests) {
+  std::unique_ptr<TracedValue> value = TracedValue::Create();
+  value->SetInteger("count", requests.size());
+  if (!requests.IsEmpty()) {
+    value->SetValue("first", CacheStorageTracedValue(requests.front()).get());
+  }
+  return value;
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::CacheQueryOptionsPtr& options) {
+  std::unique_ptr<TracedValue> value = TracedValue::Create();
+  if (options) {
+    value->SetBoolean("ignore_method", options->ignore_method);
+    value->SetBoolean("ignore_search", options->ignore_search);
+    value->SetBoolean("ignore_vary", options->ignore_vary);
+  }
+  return value;
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::MultiCacheQueryOptionsPtr& options) {
+  if (!options)
+    return TracedValue::Create();
+  std::unique_ptr<TracedValue> value =
+      CacheStorageTracedValue(options->query_options);
+  if (!options->cache_name.IsNull()) {
+    value->SetString("cache_name", options->cache_name);
+  }
+  return value;
+}
+
+std::string CacheStorageTracedValue(mojom::blink::CacheStorageError error) {
+  return MojoEnumToString(error);
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::FetchAPIResponsePtr& response) {
+  std::unique_ptr<TracedValue> value = TracedValue::Create();
+  if (response) {
+    if (!response->url_list.IsEmpty()) {
+      value->SetString("url", response->url_list.back().GetString());
+    }
+    value->SetString("type",
+                     String(MojoEnumToString(response->response_type).data()));
+  }
+  return value;
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const WTF::Vector<mojom::blink::FetchAPIResponsePtr>& responses) {
+  std::unique_ptr<TracedValue> value = TracedValue::Create();
+  value->SetInteger("count", responses.size());
+  if (!responses.IsEmpty()) {
+    value->SetValue("first", CacheStorageTracedValue(responses.front()).get());
+  }
+  return value;
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::BatchOperationPtr& op) {
+  std::unique_ptr<TracedValue> value = TracedValue::Create();
+  if (op) {
+    value->SetValue("request", CacheStorageTracedValue(op->request).get());
+    value->SetValue("response", CacheStorageTracedValue(op->response).get());
+    value->SetValue("options",
+                    CacheStorageTracedValue(op->match_options).get());
+  }
+  return value;
+}
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const WTF::Vector<String>& string_list) {
+  std::unique_ptr<TracedValue> value = TracedValue::Create();
+  value->SetInteger("count", string_list.size());
+  if (!string_list.IsEmpty()) {
+    value->SetString("first", string_list.front());
+  }
+  return value;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h b/third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h
new file mode 100644
index 0000000..e2d67e4
--- /dev/null
+++ b/third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h
@@ -0,0 +1,57 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_STORAGE_TRACE_UTILS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_STORAGE_TRACE_UTILS_H_
+
+#include <memory>
+
+#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-blink-forward.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+
+namespace blink {
+
+class TracedValue;
+
+// The following are a set of helper functions to convert a cache_storage
+// related value into something that can be passed to the TRACE_EVENT*
+// macros.
+//
+// Note, these are designed to use WTF::String, blink mojo types, and
+// blink::TracedValue.  Unforfortunately these types are not usable in
+// content, so these routines must be duplicated there as well.
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(const String& string);
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::FetchAPIRequestPtr& request);
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const WTF::Vector<mojom::blink::FetchAPIRequestPtr>& requests);
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::CacheQueryOptionsPtr& options);
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::MultiCacheQueryOptionsPtr& options);
+
+std::string CacheStorageTracedValue(mojom::blink::CacheStorageError error);
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::FetchAPIResponsePtr& response);
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const WTF::Vector<mojom::blink::FetchAPIResponsePtr>& responses);
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const mojom::blink::BatchOperationPtr& op);
+
+std::unique_ptr<TracedValue> CacheStorageTracedValue(
+    const WTF::Vector<String>& string_list);
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_STORAGE_TRACE_UTILS_H_
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
index e5d9be8..6f428f8 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_test.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -143,6 +143,7 @@
 
   void Match(mojom::blink::FetchAPIRequestPtr fetch_api_request,
              mojom::blink::CacheQueryOptionsPtr query_options,
+             int64_t trace_id,
              MatchCallback callback) override {
     last_error_web_cache_method_called_ = "dispatchMatch";
     CheckUrlIfProvided(fetch_api_request->url);
@@ -153,6 +154,7 @@
   }
   void MatchAll(mojom::blink::FetchAPIRequestPtr fetch_api_request,
                 mojom::blink::CacheQueryOptionsPtr query_options,
+                int64_t trace_id,
                 MatchAllCallback callback) override {
     last_error_web_cache_method_called_ = "dispatchMatchAll";
     if (fetch_api_request)
@@ -165,6 +167,7 @@
   }
   void Keys(mojom::blink::FetchAPIRequestPtr fetch_api_request,
             mojom::blink::CacheQueryOptionsPtr query_options,
+            int64_t trace_id,
             KeysCallback callback) override {
     last_error_web_cache_method_called_ = "dispatchKeys";
     if (fetch_api_request && !fetch_api_request->url.IsEmpty()) {
@@ -178,6 +181,7 @@
   }
   void Batch(Vector<mojom::blink::BatchOperationPtr> batch_operations,
              bool fail_on_duplicates,
+             int64_t trace_id,
              BatchCallback callback) override {
     last_error_web_cache_method_called_ = "dispatchBatch";
     CheckBatchOperationsIfProvided(batch_operations);
@@ -186,6 +190,7 @@
   void SetSideData(const KURL& url,
                    base::Time response_time,
                    const Vector<uint8_t>& side_data,
+                   int64_t trace_id,
                    SetSideDataCallback callback) override {
     std::move(callback).Run(
         blink::mojom::CacheStorageError::kErrorNotImplemented);
@@ -589,6 +594,7 @@
   // From WebServiceWorkerCache:
   void Match(mojom::blink::FetchAPIRequestPtr fetch_api_request,
              mojom::blink::CacheQueryOptionsPtr query_options,
+             int64_t trace_id,
              MatchCallback callback) override {
     mojom::blink::MatchResultPtr result = mojom::blink::MatchResult::New();
     result->set_response(std::move(response_));
@@ -634,6 +640,7 @@
 
   void Keys(mojom::blink::FetchAPIRequestPtr fetch_api_request,
             mojom::blink::CacheQueryOptionsPtr query_options,
+            int64_t trace_id,
             KeysCallback callback) override {
     mojom::blink::CacheKeysResultPtr result =
         mojom::blink::CacheKeysResult::New();
@@ -690,6 +697,7 @@
 
   void MatchAll(mojom::blink::FetchAPIRequestPtr fetch_api_request,
                 mojom::blink::CacheQueryOptionsPtr query_options,
+                int64_t trace_id,
                 MatchAllCallback callback) override {
     mojom::blink::MatchAllResultPtr result =
         mojom::blink::MatchAllResult::New();
@@ -698,6 +706,7 @@
   }
   void Batch(Vector<mojom::blink::BatchOperationPtr> batch_operations,
              bool fail_on_duplicates,
+             int64_t trace_id,
              BatchCallback callback) override {
     std::move(callback).Run(CacheStorageVerboseError::New(
         mojom::blink::CacheStorageError::kSuccess, String()));
diff --git a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
index e4ff216..eb70afd 100644
--- a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
+++ b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
@@ -11,6 +11,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "services/network/public/mojom/fetch_api.mojom-blink.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
@@ -221,6 +222,11 @@
         callback_(std::move(callback)) {}
 
   void Dispatch(Vector<mojom::blink::FetchAPIRequestPtr> old_requests) {
+    int64_t trace_id = blink::cache_storage::CreateTraceId();
+    TRACE_EVENT_WITH_FLOW0("CacheStorage", "ResponsesAccumulator::Dispatch",
+                           TRACE_ID_GLOBAL(trace_id),
+                           TRACE_EVENT_FLAG_FLOW_OUT);
+
     Vector<mojom::blink::FetchAPIRequestPtr> requests;
     if (params_.path_filter.IsEmpty()) {
       requests = std::move(old_requests);
@@ -255,7 +261,7 @@
           request->fetch_window_id, request->keepalive, request->is_reload,
           request->is_history_navigation);
       cache_ptr_->Match(std::move(request),
-                        mojom::blink::CacheQueryOptions::New(),
+                        mojom::blink::CacheQueryOptions::New(), trace_id,
                         WTF::Bind(
                             [](scoped_refptr<ResponsesAccumulator> accumulator,
                                mojom::blink::FetchAPIRequestPtr request,
@@ -372,8 +378,12 @@
   }
 
   void Dispatch(std::unique_ptr<GetCacheKeysForRequestData> self) {
+    int64_t trace_id = blink::cache_storage::CreateTraceId();
+    TRACE_EVENT_WITH_FLOW0(
+        "CacheStorage", "GetCacheKeysForRequestData::Dispatch",
+        TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
     cache_ptr_->Keys(
-        nullptr /* request */, mojom::blink::CacheQueryOptions::New(),
+        nullptr /* request */, mojom::blink::CacheQueryOptions::New(), trace_id,
         WTF::Bind(
             [](DataRequestParams params,
                std::unique_ptr<GetCacheKeysForRequestData> self,
@@ -482,6 +492,11 @@
 void InspectorCacheStorageAgent::requestCacheNames(
     const String& security_origin,
     std::unique_ptr<RequestCacheNamesCallback> callback) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "InspectorCacheStorageAgent::requestCacheNames",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   scoped_refptr<const SecurityOrigin> sec_origin =
       SecurityOrigin::CreateFromString(security_origin);
 
@@ -502,22 +517,24 @@
     return;
   }
 
-  cache_storage->Keys(WTF::Bind(
-      [](String security_origin,
-         std::unique_ptr<RequestCacheNamesCallback> callback,
-         const Vector<String>& caches) {
-        std::unique_ptr<Array<ProtocolCache>> array =
-            Array<ProtocolCache>::create();
-        for (auto& cache : caches) {
-          array->addItem(ProtocolCache::create()
-                             .setSecurityOrigin(security_origin)
-                             .setCacheName(cache)
-                             .setCacheId(BuildCacheId(security_origin, cache))
-                             .build());
-        }
-        callback->sendSuccess(std::move(array));
-      },
-      security_origin, std::move(callback)));
+  cache_storage->Keys(
+      trace_id, WTF::Bind(
+                    [](String security_origin,
+                       std::unique_ptr<RequestCacheNamesCallback> callback,
+                       const Vector<String>& caches) {
+                      std::unique_ptr<Array<ProtocolCache>> array =
+                          Array<ProtocolCache>::create();
+                      for (auto& cache : caches) {
+                        array->addItem(ProtocolCache::create()
+                                           .setSecurityOrigin(security_origin)
+                                           .setCacheName(cache)
+                                           .setCacheId(BuildCacheId(
+                                               security_origin, cache))
+                                           .build());
+                      }
+                      callback->sendSuccess(std::move(array));
+                    },
+                    security_origin, std::move(callback)));
 }
 
 void InspectorCacheStorageAgent::requestEntries(
@@ -526,6 +543,11 @@
     int page_size,
     protocol::Maybe<String> path_filter,
     std::unique_ptr<RequestEntriesCallback> callback) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "InspectorCacheStorageAgent::requestEntries",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   String cache_name;
   mojom::blink::CacheStorage* cache_storage = nullptr;
   ProtocolResponse response = AssertCacheStorageAndNameForId(
@@ -541,7 +563,7 @@
   params.path_filter = path_filter.fromMaybe("");
 
   cache_storage->Open(
-      cache_name,
+      cache_name, trace_id,
       WTF::Bind(
           [](DataRequestParams params,
              std::unique_ptr<RequestEntriesCallback> callback,
@@ -564,6 +586,11 @@
 void InspectorCacheStorageAgent::deleteCache(
     const String& cache_id,
     std::unique_ptr<DeleteCacheCallback> callback) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "InspectorCacheStorageAgent::deleteCache",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   String cache_name;
   mojom::blink::CacheStorage* cache_storage = nullptr;
   ProtocolResponse response = AssertCacheStorageAndNameForId(
@@ -573,7 +600,7 @@
     return;
   }
   cache_storage->Delete(
-      cache_name,
+      cache_name, trace_id,
       WTF::Bind(
           [](std::unique_ptr<DeleteCacheCallback> callback,
              mojom::blink::CacheStorageError error) {
@@ -592,6 +619,11 @@
     const String& cache_id,
     const String& request,
     std::unique_ptr<DeleteEntryCallback> callback) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "InspectorCacheStorageAgent::deleteEntry",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   String cache_name;
   mojom::blink::CacheStorage* cache_storage = nullptr;
   ProtocolResponse response = AssertCacheStorageAndNameForId(
@@ -601,9 +633,9 @@
     return;
   }
   cache_storage->Open(
-      cache_name,
+      cache_name, trace_id,
       WTF::Bind(
-          [](String cache_name, String request,
+          [](String cache_name, String request, int64_t trace_id,
              std::unique_ptr<DeleteEntryCallback> callback,
              mojom::blink::OpenResultPtr result) {
             if (result->is_status()) {
@@ -624,6 +656,7 @@
               auto* cache = cache_ptr.get();
               cache->Batch(
                   std::move(batch_operations), true /* fail_on_duplicates */,
+                  trace_id,
                   WTF::Bind(
                       [](mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr,
                          std::unique_ptr<DeleteEntryCallback> callback,
@@ -642,7 +675,7 @@
                       std::move(cache_ptr), std::move(callback)));
             }
           },
-          cache_name, request, std::move(callback)));
+          cache_name, request, trace_id, std::move(callback)));
 }
 
 void InspectorCacheStorageAgent::requestCachedResponse(
@@ -651,6 +684,11 @@
     const std::unique_ptr<protocol::Array<protocol::CacheStorage::Header>>
         request_headers,
     std::unique_ptr<RequestCachedResponseCallback> callback) {
+  int64_t trace_id = blink::cache_storage::CreateTraceId();
+  TRACE_EVENT_WITH_FLOW0("CacheStorage",
+                         "InspectorCacheStorageAgent::requestCachedResponse",
+                         TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT);
+
   String cache_name;
   mojom::blink::CacheStorage* cache_storage = nullptr;
   ProtocolResponse response = AssertCacheStorageAndNameForId(
@@ -672,7 +710,7 @@
   multi_query_options->cache_name = cache_name;
 
   cache_storage->Match(
-      std::move(request), std::move(multi_query_options),
+      std::move(request), std::move(multi_query_options), trace_id,
       WTF::Bind(
           [](std::unique_ptr<RequestCachedResponseCallback> callback,
              mojom::blink::MatchResultPtr result) {
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
index 45bf4c0..14ed7d3 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -938,9 +938,7 @@
 
   UpdatePlayState();
 
-  UpdateCurrentTimeDisplay();
-
-  timeline_->SetPosition(MediaElement().currentTime());
+  UpdateTimeIndicators();
 
   OnVolumeChange();
   OnTextTracksAddedOrRemoved();
@@ -955,6 +953,11 @@
   OnControlsListUpdated();
 }
 
+void MediaControlsImpl::UpdateTimeIndicators() {
+  timeline_->SetPosition(MediaElement().currentTime());
+  UpdateCurrentTimeDisplay();
+}
+
 void MediaControlsImpl::OnControlsListUpdated() {
   BatchedControlUpdate batch(this);
 
@@ -1125,6 +1128,9 @@
   if (panel_->KeepDisplayedForAccessibility())
     return false;
 
+  if (MediaElement().seeking())
+    return false;
+
   return true;
 }
 
@@ -1620,8 +1626,7 @@
       is_mouse_over_controls_ = true;
       if (!MediaElement().paused()) {
         MakeOpaqueFromPointerEvent();
-        if (ShouldHideMediaControls())
-          StartHideMediaControlsTimer();
+        StartHideMediaControlsIfNecessary();
       }
     }
   } else if (event->type() == event_type_names::kPointerout) {
@@ -1804,6 +1809,11 @@
   overlay_cast_button_->SetIsWanted(false);
 }
 
+void MediaControlsImpl::StartHideMediaControlsIfNecessary() {
+  if (ShouldHideMediaControls())
+    StartHideMediaControlsTimer();
+}
+
 void MediaControlsImpl::StartHideMediaControlsTimer() {
   hide_media_controls_timer_.StartOneShot(
       GetTimeWithoutMouseMovementBeforeHidingMediaControls(), FROM_HERE);
@@ -1877,8 +1887,7 @@
 }
 
 void MediaControlsImpl::OnTimeUpdate() {
-  timeline_->SetPosition(MediaElement().currentTime());
-  UpdateCurrentTimeDisplay();
+  UpdateTimeIndicators();
 
   // 'timeupdate' might be called in a paused state. The controls should not
   // become transparent in that case.
@@ -1920,8 +1929,7 @@
 
 void MediaControlsImpl::OnPlay() {
   UpdatePlayState();
-  timeline_->SetPosition(MediaElement().currentTime());
-  UpdateCurrentTimeDisplay();
+  UpdateTimeIndicators();
   UpdateCSSClassFromState();
 }
 
@@ -1934,8 +1942,7 @@
 
 void MediaControlsImpl::OnPause() {
   UpdatePlayState();
-  timeline_->SetPosition(MediaElement().currentTime());
-  UpdateCurrentTimeDisplay();
+  UpdateTimeIndicators();
   MakeOpaque();
 
   StopHideMediaControlsTimer();
@@ -1943,6 +1950,32 @@
   UpdateCSSClassFromState();
 }
 
+void MediaControlsImpl::OnSeeking() {
+  UpdateTimeIndicators();
+  if (!is_scrubbing_) {
+    is_scrubbing_ = true;
+    UpdateCSSClassFromState();
+  }
+
+  // Don't try to show the controls if the seek was caused by the video being
+  // looped.
+  if (MediaElement().Loop() && MediaElement().currentTime() == 0)
+    return;
+
+  if (!MediaElement().ShouldShowControls())
+    return;
+
+  MaybeShow();
+  StopHideMediaControlsTimer();
+}
+
+void MediaControlsImpl::OnSeeked() {
+  StartHideMediaControlsIfNecessary();
+
+  is_scrubbing_ = false;
+  UpdateCSSClassFromState();
+}
+
 void MediaControlsImpl::OnTextTracksAddedOrRemoved() {
   toggle_closed_captions_button_->UpdateDisplayType();
   toggle_closed_captions_button_->SetIsWanted(
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.h b/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
index d3017292..6766552 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.h
@@ -282,6 +282,9 @@
 
   void ElementSizeChangedTimerFired(TimerBase*);
 
+  // Update any visible indicators of the current time.
+  void UpdateTimeIndicators();
+
   // Hide elements that don't fit, and show those things that we want which
   // do fit.  This requires that m_effectiveWidth and m_effectiveHeight are
   // current.
@@ -338,6 +341,8 @@
   void OnPlay();
   void OnPlaying();
   void OnPause();
+  void OnSeeking();
+  void OnSeeked();
   void OnTextTracksAddedOrRemoved();
   void OnTextTracksChanged();
   void OnError();
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index 0b92a45..3b97ac8 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -222,6 +222,9 @@
 
   void SimulateLoadedMetadata() { media_controls_->OnLoadedMetadata(); }
 
+  void SimulateOnSeeking() { media_controls_->OnSeeking(); }
+  void SimulateOnSeeked() { media_controls_->OnSeeked(); }
+
   MediaControlsImpl& MediaControls() { return *media_controls_; }
   MediaControlVolumeSliderElement* VolumeSliderElement() const {
     return media_controls_->volume_slider_;
@@ -624,6 +627,32 @@
   EXPECT_EQ(duration / 2, current_time_display->CurrentValue());
 }
 
+TEST_F(MediaControlsImplTest, TimeIndicatorsUpdatedOnSeeking) {
+  EnsureSizing();
+
+  MediaControlCurrentTimeDisplayElement* current_time_display =
+      GetCurrentTimeDisplayElement();
+  MediaControlTimelineElement* timeline = TimelineElement();
+  double duration = 1000;
+  LoadMediaWithDuration(duration);
+
+  EXPECT_EQ(0, current_time_display->CurrentValue());
+  EXPECT_EQ(0, timeline->valueAsNumber());
+
+  MediaControls().MediaElement().setCurrentTime(duration / 4);
+
+  // Time indicators are not yet updated.
+  EXPECT_EQ(0, current_time_display->CurrentValue());
+  EXPECT_EQ(0, timeline->valueAsNumber());
+
+  SimulateOnSeeking();
+
+  // The time indicators should be updated immediately when the 'seeking' event
+  // is fired.
+  EXPECT_EQ(duration / 4, current_time_display->CurrentValue());
+  EXPECT_EQ(duration / 4, timeline->valueAsNumber());
+}
+
 TEST_F(MediaControlsImplTest, TimelineMetricsWidth) {
   MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
   test::RunPendingTasks();
@@ -863,6 +892,45 @@
 
 }  // namespace
 
+TEST_F(MediaControlsImplTestWithMockScheduler, SeekingShowsControls) {
+  Element* panel = GetElementByShadowPseudoId(MediaControls(),
+                                              "-webkit-media-controls-panel");
+  ASSERT_NE(nullptr, panel);
+
+  MediaControls().MediaElement().SetSrc("http://example.com");
+  MediaControls().MediaElement().Play();
+
+  // Hide the controls to start.
+  MediaControls().Hide();
+  EXPECT_FALSE(IsElementVisible(*panel));
+
+  // Seeking should cause the controls to become visible.
+  SimulateOnSeeking();
+  EXPECT_TRUE(IsElementVisible(*panel));
+}
+
+TEST_F(MediaControlsImplTestWithMockScheduler,
+       SeekingDoesNotShowControlsWhenNoControlsAttr) {
+  Element* panel = GetElementByShadowPseudoId(MediaControls(),
+                                              "-webkit-media-controls-panel");
+  ASSERT_NE(nullptr, panel);
+
+  MediaControls().MediaElement().SetBooleanAttribute(html_names::kControlsAttr,
+                                                     false);
+
+  MediaControls().MediaElement().SetSrc("http://example.com");
+  MediaControls().MediaElement().Play();
+
+  // Hide the controls to start.
+  MediaControls().Hide();
+  EXPECT_FALSE(IsElementVisible(*panel));
+
+  // Seeking should not cause the controls to become visible because the
+  // controls attribute is not set.
+  SimulateOnSeeking();
+  EXPECT_FALSE(IsElementVisible(*panel));
+}
+
 TEST_F(MediaControlsImplTestWithMockScheduler,
        ControlsRemainVisibleDuringKeyboardInteraction) {
   EnsureSizing();
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
index 3581220..0fe65f1f 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
@@ -36,6 +36,8 @@
   GetMediaElement().addEventListener(event_type_names::kPause, this, false);
   GetMediaElement().addEventListener(event_type_names::kDurationchange, this,
                                      false);
+  GetMediaElement().addEventListener(event_type_names::kSeeking, this, false);
+  GetMediaElement().addEventListener(event_type_names::kSeeked, this, false);
   GetMediaElement().addEventListener(event_type_names::kError, this, false);
   GetMediaElement().addEventListener(event_type_names::kLoadedmetadata, this,
                                      false);
@@ -177,6 +179,14 @@
     media_controls_->OnPause();
     return;
   }
+  if (event->type() == event_type_names::kSeeking) {
+    media_controls_->OnSeeking();
+    return;
+  }
+  if (event->type() == event_type_names::kSeeked) {
+    media_controls_->OnSeeked();
+    return;
+  }
   if (event->type() == event_type_names::kError) {
     media_controls_->OnError();
     return;
diff --git a/third_party/blink/renderer/modules/mediastream/BUILD.gn b/third_party/blink/renderer/modules/mediastream/BUILD.gn
index 418f198..225a04a 100644
--- a/third_party/blink/renderer/modules/mediastream/BUILD.gn
+++ b/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -21,6 +21,9 @@
     "media_error_state.h",
     "media_stream.cc",
     "media_stream.h",
+    "media_stream_constraints_util.cc",
+    "media_stream_constraints_util_sets.cc",
+    "media_stream_constraints_util_video_device.cc",
     "media_stream_event.cc",
     "media_stream_event.h",
     "media_stream_track.cc",
@@ -28,6 +31,8 @@
     "media_stream_track_content_hint.h",
     "media_stream_track_event.cc",
     "media_stream_track_event.h",
+    "media_stream_video_source.cc",
+    "media_stream_video_track.cc",
     "navigator_media_stream.cc",
     "navigator_media_stream.h",
     "navigator_user_media.cc",
@@ -40,5 +45,6 @@
     "user_media_controller.h",
     "user_media_request.cc",
     "user_media_request.h",
+    "video_track_adapter.cc",
   ]
 }
diff --git a/third_party/blink/renderer/modules/mediastream/DEPS b/third_party/blink/renderer/modules/mediastream/DEPS
index d7193fff..716c658 100644
--- a/third_party/blink/renderer/modules/mediastream/DEPS
+++ b/third_party/blink/renderer/modules/mediastream/DEPS
@@ -1,5 +1,16 @@
 include_rules = [
+    # TODO(crbug.com/923394): Remove these dependencies once std types are
+    # migrated to WTF types in mediastream.
+    "+base/strings/utf_string_conversions.h",
+    "+base/strings/string_number_conversions.h",
+    "+base/containers/flat_map.h",
+
+    "+base/threading/sequenced_task_runner_handle.h",
+    "+base/threading/thread_task_runner_handle.h",
+    "+base/trace_event/trace_event.h",
     "+media/base",
+    "+media/capture",
+    "+media/mojo/interfaces",
     "+mojo/public/cpp/bindings/binding.h",
     "-third_party/blink/renderer/modules",
     "+third_party/blink/renderer/modules/event_modules.h",
diff --git a/content/renderer/media/stream/media_stream_constraints_util.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc
similarity index 82%
rename from content/renderer/media/stream/media_stream_constraints_util.cc
rename to third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc
index 37ec2aa..8e15d03 100644
--- a/content/renderer/media/stream/media_stream_constraints_util.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.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 "content/renderer/media/stream/media_stream_constraints_util.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 
 #include <algorithm>
 #include <limits>
@@ -10,17 +10,17 @@
 
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_video_device.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h"
 
-namespace content {
+namespace blink {
 
 namespace {
 
 template <typename P, typename T>
-bool ScanConstraintsForExactValue(const blink::WebMediaConstraints& constraints,
+bool ScanConstraintsForExactValue(const WebMediaConstraints& constraints,
                                   P picker,
                                   T* value) {
   if (constraints.IsNull())
@@ -42,7 +42,7 @@
 }
 
 template <typename P, typename T>
-bool ScanConstraintsForMaxValue(const blink::WebMediaConstraints& constraints,
+bool ScanConstraintsForMaxValue(const WebMediaConstraints& constraints,
                                 P picker,
                                 T* value) {
   if (constraints.IsNull())
@@ -71,7 +71,7 @@
 }
 
 template <typename P, typename T>
-bool ScanConstraintsForMinValue(const blink::WebMediaConstraints& constraints,
+bool ScanConstraintsForMinValue(const WebMediaConstraints& constraints,
                                 P picker,
                                 T* value) {
   if (constraints.IsNull())
@@ -172,59 +172,59 @@
     AudioCaptureSettings&& other) = default;
 
 bool GetConstraintValueAsBoolean(
-    const blink::WebMediaConstraints& constraints,
-    const blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*picker,
+    const WebMediaConstraints& constraints,
+    const BooleanConstraint WebMediaTrackConstraintSet::*picker,
     bool* value) {
   return ScanConstraintsForExactValue(constraints, picker, value);
 }
 
 bool GetConstraintValueAsInteger(
-    const blink::WebMediaConstraints& constraints,
-    const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
+    const WebMediaConstraints& constraints,
+    const LongConstraint WebMediaTrackConstraintSet::*picker,
     int* value) {
   return ScanConstraintsForExactValue(constraints, picker, value);
 }
 
 bool GetConstraintMinAsInteger(
-    const blink::WebMediaConstraints& constraints,
-    const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
+    const WebMediaConstraints& constraints,
+    const LongConstraint WebMediaTrackConstraintSet::*picker,
     int* value) {
   return ScanConstraintsForMinValue(constraints, picker, value);
 }
 
 bool GetConstraintMaxAsInteger(
-    const blink::WebMediaConstraints& constraints,
-    const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
+    const WebMediaConstraints& constraints,
+    const LongConstraint WebMediaTrackConstraintSet::*picker,
     int* value) {
   return ScanConstraintsForMaxValue(constraints, picker, value);
 }
 
 bool GetConstraintValueAsDouble(
-    const blink::WebMediaConstraints& constraints,
-    const blink::DoubleConstraint blink::WebMediaTrackConstraintSet::*picker,
+    const WebMediaConstraints& constraints,
+    const DoubleConstraint WebMediaTrackConstraintSet::*picker,
     double* value) {
   return ScanConstraintsForExactValue(constraints, picker, value);
 }
 
 bool GetConstraintMinAsDouble(
-    const blink::WebMediaConstraints& constraints,
-    const blink::DoubleConstraint blink::WebMediaTrackConstraintSet::*picker,
+    const WebMediaConstraints& constraints,
+    const DoubleConstraint WebMediaTrackConstraintSet::*picker,
     double* value) {
   return ScanConstraintsForMinValue(constraints, picker, value);
 }
 
 bool GetConstraintMaxAsDouble(
-    const blink::WebMediaConstraints& constraints,
-    const blink::DoubleConstraint blink::WebMediaTrackConstraintSet::*picker,
+    const WebMediaConstraints& constraints,
+    const DoubleConstraint WebMediaTrackConstraintSet::*picker,
     double* value) {
   return ScanConstraintsForMaxValue(constraints, picker, value);
 }
 
 bool GetConstraintValueAsString(
-    const blink::WebMediaConstraints& constraints,
-    const blink::StringConstraint blink::WebMediaTrackConstraintSet::*picker,
+    const WebMediaConstraints& constraints,
+    const StringConstraint WebMediaTrackConstraintSet::*picker,
     std::string* value) {
-  blink::WebVector<blink::WebString> return_value;
+  WebVector<WebString> return_value;
   if (ScanConstraintsForExactValue(constraints, picker, &return_value)) {
     *value = return_value[0].Utf8();
     return true;
@@ -232,8 +232,7 @@
   return false;
 }
 
-std::string GetMediaStreamSource(
-    const blink::WebMediaConstraints& constraints) {
+std::string GetMediaStreamSource(const WebMediaConstraints& constraints) {
   std::string source;
   if (constraints.Basic().media_stream_source.HasIdeal() &&
       constraints.Basic().media_stream_source.Ideal().size() > 0) {
@@ -247,12 +246,12 @@
   return source;
 }
 
-bool IsDeviceCapture(const blink::WebMediaConstraints& constraints) {
+bool IsDeviceCapture(const WebMediaConstraints& constraints) {
   return GetMediaStreamSource(constraints).empty();
 }
 
 VideoTrackAdapterSettings SelectVideoTrackAdapterSettings(
-    const blink::WebMediaTrackConstraintSet& basic_constraint_set,
+    const WebMediaTrackConstraintSet& basic_constraint_set,
     const media_constraints::ResolutionSet& resolution_set,
     const media_constraints::NumericRangeSet<double>& frame_rate_set,
     const media::VideoCaptureFormat& source_format,
@@ -297,16 +296,15 @@
 }
 
 double NumericConstraintFitnessDistance(double value1, double value2) {
-  if (std::fabs(value1 - value2) <= blink::DoubleConstraint::kConstraintEpsilon)
+  if (std::fabs(value1 - value2) <= DoubleConstraint::kConstraintEpsilon)
     return 0.0;
 
   return std::fabs(value1 - value2) /
          std::max(std::fabs(value1), std::fabs(value2));
 }
 
-double StringConstraintFitnessDistance(
-    const blink::WebString& value,
-    const blink::StringConstraint& constraint) {
+double StringConstraintFitnessDistance(const WebString& value,
+                                       const StringConstraint& constraint) {
   if (!constraint.HasIdeal())
     return 0.0;
 
@@ -318,18 +316,18 @@
   return 1.0;
 }
 
-blink::WebMediaStreamSource::Capabilities ComputeCapabilitiesForVideoSource(
-    const blink::WebString& device_id,
+WebMediaStreamSource::Capabilities ComputeCapabilitiesForVideoSource(
+    const WebString& device_id,
     const media::VideoCaptureFormats& formats,
     media::VideoFacingMode facing_mode,
     bool is_device_capture,
     const base::Optional<std::string>& group_id) {
-  blink::WebMediaStreamSource::Capabilities capabilities;
+  WebMediaStreamSource::Capabilities capabilities;
   capabilities.device_id = std::move(device_id);
   if (is_device_capture) {
     capabilities.facing_mode = ToWebFacingMode(facing_mode);
     if (group_id)
-      capabilities.group_id = blink::WebString::FromUTF8(*group_id);
+      capabilities.group_id = WebString::FromUTF8(*group_id);
   }
   if (!formats.empty()) {
     int max_width = 1;
@@ -351,4 +349,4 @@
   return capabilities;
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/media/stream/media_stream_constraints_util_sets.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
similarity index 93%
rename from content/renderer/media/stream/media_stream_constraints_util_sets.cc
rename to third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
index 27cafc4..25b8b2a 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_sets.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h"
 
 #include <cmath>
 
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 
-namespace content {
+namespace blink {
 namespace media_constraints {
 
 using Point = ResolutionSet::Point;
@@ -52,14 +52,14 @@
   return static_cast<int>(dimension);
 }
 
-int MinDimensionFromConstraint(const blink::LongConstraint& constraint) {
+int MinDimensionFromConstraint(const LongConstraint& constraint) {
   if (!ConstraintHasMin(constraint))
     return 0;
 
   return ToValidDimension(ConstraintMin(constraint));
 }
 
-int MaxDimensionFromConstraint(const blink::LongConstraint& constraint) {
+int MaxDimensionFromConstraint(const LongConstraint& constraint) {
   if (!ConstraintHasMax(constraint))
     return ResolutionSet::kMaxDimension;
 
@@ -70,14 +70,14 @@
   return aspect_ratio < 0.0 ? 0.0 : aspect_ratio;
 }
 
-double MinAspectRatioFromConstraint(const blink::DoubleConstraint& constraint) {
+double MinAspectRatioFromConstraint(const DoubleConstraint& constraint) {
   if (!ConstraintHasMin(constraint))
     return 0.0;
 
   return ToValidAspectRatio(ConstraintMin(constraint));
 }
 
-double MaxAspectRatioFromConstraint(const blink::DoubleConstraint& constraint) {
+double MaxAspectRatioFromConstraint(const DoubleConstraint& constraint) {
   if (!ConstraintHasMax(constraint))
     return HUGE_VAL;
 
@@ -181,7 +181,7 @@
   double m = Dot(s2_trans, p_trans) / Dot(s2_trans, s2_trans);
   if (m < 0)
     return s1;
-  else if (m > 1)
+  if (m > 1)
     return s2;
 
   // Return the projection in the original coordinate system.
@@ -269,7 +269,7 @@
 }
 
 Point ResolutionSet::SelectClosestPointToIdeal(
-    const blink::WebMediaTrackConstraintSet& constraint_set,
+    const WebMediaTrackConstraintSet& constraint_set,
     int default_height,
     int default_width) const {
   DCHECK_GE(default_height, 1);
@@ -314,7 +314,8 @@
         Point ideal_point(closest_vertices[0].height(),
                           closest_vertices[0].height() * default_aspect_ratio);
         return GetClosestPointToVertexOrSide(closest_vertices, ideal_point);
-      } else if (constraint_set.width.HasIdeal()) {
+      }
+      if (constraint_set.width.HasIdeal()) {
         int ideal_width = ToValidDimension(constraint_set.width.Ideal());
         ResolutionSet ideal_line = ResolutionSet::FromExactWidth(ideal_width);
         ResolutionSet intersection = Intersection(ideal_line);
@@ -327,7 +328,8 @@
         Point ideal_point(closest_vertices[0].width() / default_aspect_ratio,
                           closest_vertices[0].width());
         return GetClosestPointToVertexOrSide(closest_vertices, ideal_point);
-      } else {
+      }
+      {
         DCHECK(constraint_set.aspect_ratio.HasIdeal());
         double ideal_aspect_ratio =
             ToValidAspectRatio(constraint_set.aspect_ratio.Ideal());
@@ -494,9 +496,10 @@
     TryAddVertex(&vertices,
                  Point(max_height_, max_height_ * min_aspect_ratio_));
   }
-  if (IsPositiveFiniteAspectRatio(max_aspect_ratio_))
+  if (IsPositiveFiniteAspectRatio(max_aspect_ratio_)) {
     TryAddVertex(&vertices,
                  Point(max_height_, max_height_ * max_aspect_ratio_));
+  }
   TryAddVertex(&vertices, Point(max_height_, max_width_));
   // Continue along max_width.
   if (IsPositiveFiniteAspectRatio(min_aspect_ratio_))
@@ -533,7 +536,7 @@
 }
 
 ResolutionSet ResolutionSet::FromConstraintSet(
-    const blink::WebMediaTrackConstraintSet& constraint_set) {
+    const WebMediaTrackConstraintSet& constraint_set) {
   return ResolutionSet(
       MinDimensionFromConstraint(constraint_set.height),
       MaxDimensionFromConstraint(constraint_set.height),
@@ -544,7 +547,7 @@
 }
 
 DiscreteSet<std::string> StringSetFromConstraint(
-    const blink::StringConstraint& constraint) {
+    const StringConstraint& constraint) {
   if (!constraint.HasExact())
     return DiscreteSet<std::string>::UniversalSet();
 
@@ -555,8 +558,7 @@
   return DiscreteSet<std::string>(std::move(elements));
 }
 
-DiscreteSet<bool> BoolSetFromConstraint(
-    const blink::BooleanConstraint& constraint) {
+DiscreteSet<bool> BoolSetFromConstraint(const BooleanConstraint& constraint) {
   if (!constraint.HasExact())
     return DiscreteSet<bool>::UniversalSet();
 
@@ -564,14 +566,13 @@
 }
 
 DiscreteSet<bool> RescaleSetFromConstraint(
-    const blink::StringConstraint& resize_mode_constraint) {
+    const StringConstraint& resize_mode_constraint) {
   DCHECK_EQ(resize_mode_constraint.GetName(),
-            blink::WebMediaTrackConstraintSet().resize_mode.GetName());
+            WebMediaTrackConstraintSet().resize_mode.GetName());
   bool contains_none = resize_mode_constraint.Matches(
-      blink::WebString::FromASCII(blink::WebMediaStreamTrack::kResizeModeNone));
-  bool contains_rescale =
-      resize_mode_constraint.Matches(blink::WebString::FromASCII(
-          blink::WebMediaStreamTrack::kResizeModeRescale));
+      WebString::FromASCII(WebMediaStreamTrack::kResizeModeNone));
+  bool contains_rescale = resize_mode_constraint.Matches(
+      WebString::FromASCII(WebMediaStreamTrack::kResizeModeRescale));
   if (resize_mode_constraint.Exact().empty() ||
       (contains_none && contains_rescale)) {
     return DiscreteSet<bool>::UniversalSet();
@@ -587,4 +588,4 @@
 }
 
 }  // namespace media_constraints
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_device.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc
similarity index 84%
rename from content/renderer/media/stream/media_stream_constraints_util_video_device.cc
rename to third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc
index 750083e..f1ad9c9 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_video_device.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.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 "content/renderer/media/stream/media_stream_constraints_util_video_device.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h"
 
 #include <algorithm>
 #include <cmath>
@@ -11,15 +11,15 @@
 #include <vector>
 
 #include "base/stl_util.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
 #include "media/base/limits.h"
-#include "media/mojo/interfaces/display_media_information.mojom.h"
+#include "media/mojo/interfaces/display_media_information.mojom-blink.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
-namespace content {
+namespace blink {
 
 namespace {
 
@@ -41,14 +41,14 @@
 const char kVideoKindColor[] = "color";
 const char kVideoKindDepth[] = "depth";
 
-blink::WebString ToWebString(media::VideoFacingMode facing_mode) {
+WebString ToWebString(media::VideoFacingMode facing_mode) {
   switch (facing_mode) {
     case media::MEDIA_VIDEO_FACING_USER:
-      return blink::WebString::FromASCII("user");
+      return WebString::FromASCII("user");
     case media::MEDIA_VIDEO_FACING_ENVIRONMENT:
-      return blink::WebString::FromASCII("environment");
+      return WebString::FromASCII("environment");
     default:
-      return blink::WebString();
+      return WebString();
   }
 }
 
@@ -91,7 +91,7 @@
 // an optional boolean |value|.
 // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
 double OptionalBoolFitness(const base::Optional<bool>& value,
-                           const blink::BooleanConstraint& constraint) {
+                           const BooleanConstraint& constraint) {
   if (!constraint.HasIdeal())
     return 0.0;
 
@@ -100,7 +100,7 @@
 
 // If |failed_constraint_name| is not null, this function updates it with the
 // name of |constraint|.
-void UpdateFailedConstraintName(const blink::BaseConstraint& constraint,
+void UpdateFailedConstraintName(const BaseConstraint& constraint,
                                 const char** failed_constraint_name) {
   if (failed_constraint_name)
     *failed_constraint_name = constraint.GetName();
@@ -179,16 +179,15 @@
   }
 
   // Convenience accessor for video kind using Blink type.
-  blink::WebString VideoKind() const { return GetVideoKindForFormat(format_); }
+  WebString VideoKind() const { return GetVideoKindForFormat(format_); }
 
   // This function tries to apply |constraint_set| to this candidate format
   // and returns true if successful. If |constraint_set| cannot be satisfied,
   // false is returned, and the name of one of the constraints that
   // could not be satisfied is returned in |failed_constraint_name| if
   // |failed_constraint_name| is not null.
-  bool ApplyConstraintSet(
-      const blink::WebMediaTrackConstraintSet& constraint_set,
-      const char** failed_constraint_name = nullptr) {
+  bool ApplyConstraintSet(const WebMediaTrackConstraintSet& constraint_set,
+                          const char** failed_constraint_name = nullptr) {
     auto rescale_intersection =
         rescale_set_.Intersection(media_constraints::RescaleSetFromConstraint(
             constraint_set.resize_mode));
@@ -254,7 +253,7 @@
   // The track settings that correspond to this fitness are returned on the
   // |track_settings| output parameter. The fitness function is based on
   // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
-  double Fitness(const blink::WebMediaTrackConstraintSet& basic_constraint_set,
+  double Fitness(const WebMediaTrackConstraintSet& basic_constraint_set,
                  VideoTrackAdapterSettings* track_settings) const {
     DCHECK(!rescale_set_.IsEmpty());
     double track_fitness_with_rescale = HUGE_VAL;
@@ -311,12 +310,11 @@
 
     if (basic_constraint_set.resize_mode.HasIdeal()) {
       if (!base::ContainsValue(basic_constraint_set.resize_mode.Ideal(),
-                               blink::WebMediaStreamTrack::kResizeModeNone)) {
+                               WebMediaStreamTrack::kResizeModeNone)) {
         track_fitness_without_rescale += 1.0;
       }
-      if (!base::ContainsValue(
-              basic_constraint_set.resize_mode.Ideal(),
-              blink::WebMediaStreamTrack::kResizeModeRescale)) {
+      if (!base::ContainsValue(basic_constraint_set.resize_mode.Ideal(),
+                               WebMediaStreamTrack::kResizeModeRescale)) {
         track_fitness_with_rescale += 1.0;
       }
     }
@@ -340,8 +338,7 @@
   // the corresponding width, height and frameRate properties.
   // This distance is intended to be used to break ties among candidates that
   // are equally good according to the standard fitness distance.
-  double NativeFitness(
-      const blink::WebMediaTrackConstraintSet& constraint_set) const {
+  double NativeFitness(const WebMediaTrackConstraintSet& constraint_set) const {
     return NumericRangeNativeFitness(constraint_set.width, MinWidth(),
                                      MaxWidth(), NativeWidth()) +
            NumericRangeNativeFitness(constraint_set.height, MinHeight(),
@@ -351,7 +348,7 @@
   }
 
  private:
-  bool SatisfiesFrameRateConstraint(const blink::DoubleConstraint& constraint) {
+  bool SatisfiesFrameRateConstraint(const DoubleConstraint& constraint) {
     double constraint_min =
         ConstraintHasMin(constraint) ? ConstraintMin(constraint) : -1.0;
     double constraint_max = ConstraintHasMax(constraint)
@@ -361,11 +358,11 @@
         ((constraint_min > NativeFrameRate()) ||
          (constraint_min > MaxFrameRateConstraint().value_or(
                                media::limits::kMaxFramesPerSecond) +
-                               blink::DoubleConstraint::kConstraintEpsilon));
+                               DoubleConstraint::kConstraintEpsilon));
     bool constraint_max_out_of_range =
         ((constraint_max < kMinDeviceCaptureFrameRate) ||
          (constraint_max < MinFrameRateConstraint().value_or(0.0) -
-                               blink::DoubleConstraint::kConstraintEpsilon));
+                               DoubleConstraint::kConstraintEpsilon));
     bool constraint_self_contradicts = constraint_min > constraint_max;
 
     return !constraint_min_out_of_range && !constraint_max_out_of_range &&
@@ -395,44 +392,42 @@
 // Returns true if the facing mode |value| satisfies |constraints|, false
 // otherwise.
 bool FacingModeSatisfiesConstraint(media::VideoFacingMode value,
-                                   const blink::StringConstraint& constraint) {
-  blink::WebString string_value = ToWebString(value);
+                                   const StringConstraint& constraint) {
+  WebString string_value = ToWebString(value);
   if (string_value.IsNull())
     return constraint.Exact().empty();
 
   return constraint.Matches(string_value);
+}
+
+// Returns true if |constraint_set| can be satisfied by |device|. Otherwise,
+// returns false and, if |failed_constraint_name| is not null, updates
+// |failed_constraint_name| with the name of a constraint that could not be
+// satisfied.
+bool DeviceSatisfiesConstraintSet(
+    const DeviceInfo& device,
+    const WebMediaTrackConstraintSet& constraint_set,
+    const char** failed_constraint_name = nullptr) {
+  if (!constraint_set.device_id.Matches(
+          WebString::FromUTF8(device.device_id))) {
+    UpdateFailedConstraintName(constraint_set.device_id,
+                               failed_constraint_name);
+    return false;
   }
 
-  // Returns true if |constraint_set| can be satisfied by |device|. Otherwise,
-  // returns false and, if |failed_constraint_name| is not null, updates
-  // |failed_constraint_name| with the name of a constraint that could not be
-  // satisfied.
-  bool DeviceSatisfiesConstraintSet(
-      const DeviceInfo& device,
-      const blink::WebMediaTrackConstraintSet& constraint_set,
-      const char** failed_constraint_name = nullptr) {
-    if (!constraint_set.device_id.Matches(
-            blink::WebString::FromUTF8(device.device_id))) {
-      UpdateFailedConstraintName(constraint_set.device_id,
-                                 failed_constraint_name);
-      return false;
-    }
+  if (!constraint_set.group_id.Matches(WebString::FromUTF8(device.group_id))) {
+    UpdateFailedConstraintName(constraint_set.group_id, failed_constraint_name);
+    return false;
+  }
 
-    if (!constraint_set.group_id.Matches(
-            blink::WebString::FromUTF8(device.group_id))) {
-      UpdateFailedConstraintName(constraint_set.group_id,
-                                 failed_constraint_name);
-      return false;
-    }
+  if (!FacingModeSatisfiesConstraint(device.facing_mode,
+                                     constraint_set.facing_mode)) {
+    UpdateFailedConstraintName(constraint_set.facing_mode,
+                               failed_constraint_name);
+    return false;
+  }
 
-    if (!FacingModeSatisfiesConstraint(device.facing_mode,
-                                       constraint_set.facing_mode)) {
-      UpdateFailedConstraintName(constraint_set.facing_mode,
-                                 failed_constraint_name);
-      return false;
-    }
-
-    return true;
+  return true;
 }
 
 // Returns true if |value| satisfies the given |constraint|, false otherwise.
@@ -440,7 +435,7 @@
 // |failed_constraint_name| is set to |constraints|'s name.
 bool OptionalBoolSatisfiesConstraint(
     const base::Optional<bool>& value,
-    const blink::BooleanConstraint& constraint,
+    const BooleanConstraint& constraint,
     const char** failed_constraint_name = nullptr) {
   if (!constraint.HasExact())
     return true;
@@ -453,13 +448,11 @@
 }
 
 double DeviceFitness(const DeviceInfo& device,
-                     const blink::WebMediaTrackConstraintSet& constraint_set) {
-  return StringConstraintFitnessDistance(
-             blink::WebString::FromUTF8(device.device_id),
-             constraint_set.device_id) +
-         StringConstraintFitnessDistance(
-             blink::WebString::FromUTF8(device.group_id),
-             constraint_set.group_id) +
+                     const WebMediaTrackConstraintSet& constraint_set) {
+  return StringConstraintFitnessDistance(WebString::FromUTF8(device.device_id),
+                                         constraint_set.device_id) +
+         StringConstraintFitnessDistance(WebString::FromUTF8(device.group_id),
+                                         constraint_set.group_id) +
          StringConstraintFitnessDistance(ToWebString(device.facing_mode),
                                          constraint_set.facing_mode);
 }
@@ -472,7 +465,7 @@
 double CandidateFitness(const DeviceInfo& device,
                         const CandidateFormat& candidate_format,
                         const base::Optional<bool>& noise_reduction,
-                        const blink::WebMediaTrackConstraintSet& constraint_set,
+                        const WebMediaTrackConstraintSet& constraint_set,
                         VideoTrackAdapterSettings* track_settings) {
   return DeviceFitness(device, constraint_set) +
          candidate_format.Fitness(constraint_set, track_settings) +
@@ -542,51 +535,49 @@
 
 VideoInputDeviceCapabilities::~VideoInputDeviceCapabilities() = default;
 
-blink::WebString GetVideoKindForFormat(
-    const media::VideoCaptureFormat& format) {
+WebString GetVideoKindForFormat(const media::VideoCaptureFormat& format) {
   return (format.pixel_format == media::PIXEL_FORMAT_Y16)
-             ? blink::WebString::FromASCII(kVideoKindDepth)
-             : blink::WebString::FromASCII(kVideoKindColor);
+             ? WebString::FromASCII(kVideoKindDepth)
+             : WebString::FromASCII(kVideoKindColor);
 }
 
-blink::WebMediaStreamTrack::FacingMode ToWebFacingMode(
+WebMediaStreamTrack::FacingMode ToWebFacingMode(
     media::VideoFacingMode video_facing) {
   switch (video_facing) {
     case media::MEDIA_VIDEO_FACING_NONE:
-      return blink::WebMediaStreamTrack::FacingMode::kNone;
+      return WebMediaStreamTrack::FacingMode::kNone;
     case media::MEDIA_VIDEO_FACING_USER:
-      return blink::WebMediaStreamTrack::FacingMode::kUser;
+      return WebMediaStreamTrack::FacingMode::kUser;
     case media::MEDIA_VIDEO_FACING_ENVIRONMENT:
-      return blink::WebMediaStreamTrack::FacingMode::kEnvironment;
+      return WebMediaStreamTrack::FacingMode::kEnvironment;
     default:
-      return blink::WebMediaStreamTrack::FacingMode::kNone;
+      return WebMediaStreamTrack::FacingMode::kNone;
   }
 }
 
-blink::WebMediaStreamTrack::DisplayCaptureSurfaceType ToWebDisplaySurface(
+WebMediaStreamTrack::DisplayCaptureSurfaceType ToWebDisplaySurface(
     media::mojom::DisplayCaptureSurfaceType display_surface) {
   switch (display_surface) {
     case media::mojom::DisplayCaptureSurfaceType::MONITOR:
-      return blink::WebMediaStreamTrack::DisplayCaptureSurfaceType::kMonitor;
+      return WebMediaStreamTrack::DisplayCaptureSurfaceType::kMonitor;
     case media::mojom::DisplayCaptureSurfaceType::WINDOW:
-      return blink::WebMediaStreamTrack::DisplayCaptureSurfaceType::kWindow;
+      return WebMediaStreamTrack::DisplayCaptureSurfaceType::kWindow;
     case media::mojom::DisplayCaptureSurfaceType::APPLICATION:
-      return blink::WebMediaStreamTrack::DisplayCaptureSurfaceType::
-          kApplication;
+      return WebMediaStreamTrack::DisplayCaptureSurfaceType::kApplication;
     case media::mojom::DisplayCaptureSurfaceType::BROWSER:
-      return blink::WebMediaStreamTrack::DisplayCaptureSurfaceType::kBrowser;
+      return WebMediaStreamTrack::DisplayCaptureSurfaceType::kBrowser;
   }
 }
 
-blink::WebMediaStreamTrack::CursorCaptureType ToWebCursorCaptureType(
+WebMediaStreamTrack::CursorCaptureType ToWebCursorCaptureType(
     media::mojom::CursorCaptureType cursor) {
   switch (cursor) {
     case media::mojom::CursorCaptureType::NEVER:
-      return blink::WebMediaStreamTrack::CursorCaptureType::kNever;
+      return WebMediaStreamTrack::CursorCaptureType::kNever;
     case media::mojom::CursorCaptureType::ALWAYS:
-      return blink::WebMediaStreamTrack::CursorCaptureType::kAlways;
+      return WebMediaStreamTrack::CursorCaptureType::kAlways;
     case media::mojom::CursorCaptureType::MOTION:
-      return blink::WebMediaStreamTrack::CursorCaptureType::kMotion;
+      return WebMediaStreamTrack::CursorCaptureType::kMotion;
   }
 }
 
@@ -599,7 +590,7 @@
 
 VideoCaptureSettings SelectSettingsVideoDeviceCapture(
     const VideoDeviceCaptureCapabilities& capabilities,
-    const blink::WebMediaConstraints& constraints,
+    const WebMediaConstraints& constraints,
     int default_width,
     int default_height,
     double default_frame_rate) {
@@ -705,4 +696,4 @@
   return result;
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/media/stream/media_stream_video_source.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
similarity index 88%
rename from content/renderer/media/stream/media_stream_video_source.cc
rename to third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
index 61f305b8..e0a5467f 100644
--- a/content/renderer/media/stream/media_stream_video_source.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_source.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 "content/renderer/media/stream/media_stream_video_source.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 
 #include <algorithm>
 #include <limits>
@@ -17,19 +17,17 @@
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/sequenced_task_runner_handle.h"
-#include "content/child/child_process.h"
-#include "content/public/common/content_features.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_video_device.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
-#include "content/renderer/media/stream/video_track_adapter.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 
-namespace content {
+namespace blink {
 
 // static
 MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource(
-    const blink::WebMediaStreamSource& source) {
-  if (source.IsNull() ||
-      source.GetType() != blink::WebMediaStreamSource::kTypeVideo) {
+    const WebMediaStreamSource& source) {
+  if (source.IsNull() || source.GetType() != WebMediaStreamSource::kTypeVideo) {
     return nullptr;
   }
   return static_cast<MediaStreamVideoSource*>(source.GetPlatformSource());
@@ -38,7 +36,7 @@
 MediaStreamVideoSource::MediaStreamVideoSource()
     : state_(NEW), weak_factory_(this) {
   track_adapter_ = base::MakeRefCounted<VideoTrackAdapter>(
-      ChildProcess::current()->io_task_runner(),
+      Platform::Current()->GetIOTaskRunner(),
       base::BindRepeating(&MediaStreamVideoSource::OnFrameDropped,
                           weak_factory_.GetWeakPtr()));
 }
@@ -50,9 +48,9 @@
 void MediaStreamVideoSource::AddTrack(
     MediaStreamVideoTrack* track,
     const VideoTrackAdapterSettings& track_adapter_settings,
-    const blink::VideoCaptureDeliverFrameCB& frame_callback,
-    const blink::VideoTrackSettingsCallback& settings_callback,
-    const blink::VideoTrackFormatCallback& format_callback,
+    const VideoCaptureDeliverFrameCB& frame_callback,
+    const VideoTrackSettingsCallback& settings_callback,
+    const VideoTrackFormatCallback& format_callback,
     const ConstraintsCallback& callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!base::ContainsValue(tracks_, track));
@@ -286,7 +284,8 @@
 }
 
 void MediaStreamVideoSource::UpdateCapturingLinkSecure(
-    MediaStreamVideoTrack* track, bool is_secure) {
+    MediaStreamVideoTrack* track,
+    bool is_secure) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   secure_tracker_.Update(track, is_secure);
   OnCapturingLinkSecured(secure_tracker_.is_capturing_secure());
@@ -315,7 +314,7 @@
 }
 
 void MediaStreamVideoSource::DoChangeSource(
-    const blink::MediaStreamDevice& new_device) {
+    const MediaStreamDevice& new_device) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(1) << "MediaStreamVideoSource::DoChangeSource: "
            << ", new device id = " << new_device.id
@@ -335,11 +334,10 @@
   track_adapter_->StopFrameMonitoring();
   StopSourceImpl();
   state_ = ENDED;
-  SetReadyState(blink::WebMediaStreamSource::kReadyStateEnded);
+  SetReadyState(WebMediaStreamSource::kReadyStateEnded);
 }
 
-void MediaStreamVideoSource::OnStartDone(
-    blink::MediaStreamRequestResult result) {
+void MediaStreamVideoSource::OnStartDone(MediaStreamRequestResult result) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DVLOG(3) << "OnStartDone({result =" << result << "})";
   if (state_ == ENDED) {
@@ -349,11 +347,11 @@
     return;
   }
 
-  if (result == blink::MEDIA_DEVICE_OK) {
+  if (result == MEDIA_DEVICE_OK) {
     DCHECK_EQ(STARTING, state_);
     OnLog("MediaStreamVideoSource changing state to STARTED");
     state_ = STARTED;
-    SetReadyState(blink::WebMediaStreamSource::kReadyStateLive);
+    SetReadyState(WebMediaStreamSource::kReadyStateLive);
     StartFrameMonitoring();
   } else {
     StopSource();
@@ -369,11 +367,11 @@
   std::vector<PendingTrackInfo> pending_track_descriptors;
   pending_track_descriptors.swap(pending_tracks_);
   for (const auto& track_info : pending_track_descriptors) {
-    blink::MediaStreamRequestResult result = blink::MEDIA_DEVICE_OK;
+    MediaStreamRequestResult result = MEDIA_DEVICE_OK;
     if (state_ != STARTED)
-      result = blink::MEDIA_DEVICE_TRACK_START_FAILURE_VIDEO;
+      result = MEDIA_DEVICE_TRACK_START_FAILURE_VIDEO;
 
-    if (result == blink::MEDIA_DEVICE_OK) {
+    if (result == MEDIA_DEVICE_OK) {
       track_adapter_->AddTrack(track_info.track, track_info.frame_callback,
                                track_info.settings_callback,
                                track_info.format_callback,
@@ -385,7 +383,7 @@
       OnLog(
           "MediaStreamVideoSource invoking callback indicating result of "
           "starting track.");
-      track_info.callback.Run(this, result, blink::WebString());
+      track_info.callback.Run(this, result, WebString());
     } else {
       OnLog(
           "MediaStreamVideoSource dropping event indicating result of starting "
@@ -407,7 +405,7 @@
 }
 
 void MediaStreamVideoSource::SetReadyState(
-    blink::WebMediaStreamSource::ReadyState state) {
+    WebMediaStreamSource::ReadyState state) {
   DVLOG(3) << "MediaStreamVideoSource::SetReadyState state " << state;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!Owner().IsNull())
@@ -420,9 +418,8 @@
   DVLOG(3) << "MediaStreamVideoSource::SetMutedState state=" << muted_state;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!Owner().IsNull()) {
-    Owner().SetReadyState(muted_state
-                              ? blink::WebMediaStreamSource::kReadyStateMuted
-                              : blink::WebMediaStreamSource::kReadyStateLive);
+    Owner().SetReadyState(muted_state ? WebMediaStreamSource::kReadyStateMuted
+                                      : WebMediaStreamSource::kReadyStateLive);
   }
 }
 
@@ -449,9 +446,9 @@
 
 MediaStreamVideoSource::PendingTrackInfo::PendingTrackInfo(
     MediaStreamVideoTrack* track,
-    const blink::VideoCaptureDeliverFrameCB& frame_callback,
-    const blink::VideoTrackSettingsCallback& settings_callback,
-    const blink::VideoTrackFormatCallback& format_callback,
+    const VideoCaptureDeliverFrameCB& frame_callback,
+    const VideoTrackSettingsCallback& settings_callback,
+    const VideoTrackFormatCallback& format_callback,
     std::unique_ptr<VideoTrackAdapterSettings> adapter_settings,
     const ConstraintsCallback& callback)
     : track(track),
@@ -469,4 +466,4 @@
 
 MediaStreamVideoSource::PendingTrackInfo::~PendingTrackInfo() {}
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/media/stream/media_stream_video_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
similarity index 86%
rename from content/renderer/media/stream/media_stream_video_track.cc
rename to third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
index 84c9319e..49ab7d3 100644
--- a/content/renderer/media/stream/media_stream_video_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.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 "content/renderer/media/stream/media_stream_video_track.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 
 #include <string>
 #include <utility>
@@ -14,16 +14,15 @@
 #include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
-#include "content/renderer/media/stream/media_stream_constraints_util_video_device.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/capture/video_capture_types.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_video_device.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 
-namespace content {
+namespace blink {
 
 namespace {
-void ResetCallback(
-    std::unique_ptr<blink::VideoCaptureDeliverFrameCB> callback) {
+void ResetCallback(std::unique_ptr<VideoCaptureDeliverFrameCB> callback) {
   // |callback| will be deleted when this exits.
 }
 
@@ -42,7 +41,7 @@
 class MediaStreamVideoTrack::FrameDeliverer
     : public base::RefCountedThreadSafe<FrameDeliverer> {
  public:
-  using VideoSinkId = blink::WebMediaStreamSink*;
+  using VideoSinkId = WebMediaStreamSink*;
 
   FrameDeliverer(
       scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
@@ -54,8 +53,7 @@
 
   // Add |callback| to receive video frames on the IO-thread.
   // Must be called on the main render thread.
-  void AddCallback(VideoSinkId id,
-                   const blink::VideoCaptureDeliverFrameCB& callback);
+  void AddCallback(VideoSinkId id, const VideoCaptureDeliverFrameCB& callback);
 
   // Removes |callback| associated with |id| from receiving video frames if |id|
   // has been added. It is ok to call RemoveCallback even if the |id| has not
@@ -72,7 +70,7 @@
   friend class base::RefCountedThreadSafe<FrameDeliverer>;
   virtual ~FrameDeliverer();
   void AddCallbackOnIO(VideoSinkId id,
-                       const blink::VideoCaptureDeliverFrameCB& callback);
+                       const VideoCaptureDeliverFrameCB& callback);
   void RemoveCallbackOnIO(
       VideoSinkId id,
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
@@ -99,7 +97,7 @@
   bool emit_frame_drop_events_;
 
   using VideoIdCallbackPair =
-      std::pair<VideoSinkId, blink::VideoCaptureDeliverFrameCB>;
+      std::pair<VideoSinkId, VideoCaptureDeliverFrameCB>;
   std::vector<VideoIdCallbackPair> callbacks_;
 
   DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
@@ -116,11 +114,10 @@
       emit_frame_drop_events_(true) {
   DCHECK(io_task_runner_.get());
 
-  blink::WebLocalFrame* web_frame =
-      blink::WebLocalFrame::FrameForCurrentContext();
+  WebLocalFrame* web_frame = WebLocalFrame::FrameForCurrentContext();
   if (web_frame) {
     main_render_task_runner_ =
-        web_frame->GetTaskRunner(blink::TaskType::kInternalMedia);
+        web_frame->GetTaskRunner(TaskType::kInternalMedia);
   }
 }
 
@@ -130,7 +127,7 @@
 
 void MediaStreamVideoTrack::FrameDeliverer::AddCallback(
     VideoSinkId id,
-    const blink::VideoCaptureDeliverFrameCB& callback) {
+    const VideoCaptureDeliverFrameCB& callback) {
   DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
   io_task_runner_->PostTask(
       FROM_HERE,
@@ -139,7 +136,7 @@
 
 void MediaStreamVideoTrack::FrameDeliverer::AddCallbackOnIO(
     VideoSinkId id,
-    const blink::VideoCaptureDeliverFrameCB& callback) {
+    const VideoCaptureDeliverFrameCB& callback) {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
   callbacks_.push_back(std::make_pair(id, callback));
 }
@@ -159,8 +156,8 @@
   for (; it != callbacks_.end(); ++it) {
     if (it->first == id) {
       // Callback is copied to heap and then deleted on the target thread.
-      std::unique_ptr<blink::VideoCaptureDeliverFrameCB> callback;
-      callback.reset(new blink::VideoCaptureDeliverFrameCB(it->second));
+      std::unique_ptr<VideoCaptureDeliverFrameCB> callback;
+      callback.reset(new VideoCaptureDeliverFrameCB(it->second));
       callbacks_.erase(it);
       task_runner->PostTask(
           FROM_HERE, base::BindOnce(&ResetCallback, std::move(callback)));
@@ -238,11 +235,11 @@
 }
 
 // static
-blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
+WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
     MediaStreamVideoSource* source,
     const MediaStreamVideoSource::ConstraintsCallback& callback,
     bool enabled) {
-  blink::WebMediaStreamTrack track;
+  WebMediaStreamTrack track;
   track.Initialize(source->Owner());
   track.SetPlatformTrack(
       std::make_unique<MediaStreamVideoTrack>(source, callback, enabled));
@@ -250,12 +247,12 @@
 }
 
 // static
-blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
-    const blink::WebString& id,
+WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
+    const WebString& id,
     MediaStreamVideoSource* source,
     const MediaStreamVideoSource::ConstraintsCallback& callback,
     bool enabled) {
-  blink::WebMediaStreamTrack track;
+  WebMediaStreamTrack track;
   track.Initialize(id, source->Owner());
   track.SetPlatformTrack(
       std::make_unique<MediaStreamVideoTrack>(source, callback, enabled));
@@ -263,7 +260,7 @@
 }
 
 // static
-blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
+WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
     MediaStreamVideoSource* source,
     const VideoTrackAdapterSettings& adapter_settings,
     const base::Optional<bool>& noise_reduction,
@@ -271,7 +268,7 @@
     const base::Optional<double>& min_frame_rate,
     const MediaStreamVideoSource::ConstraintsCallback& callback,
     bool enabled) {
-  blink::WebMediaStreamTrack track;
+  WebMediaStreamTrack track;
   track.Initialize(source->Owner());
   track.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
       source, adapter_settings, noise_reduction, is_screencast, min_frame_rate,
@@ -281,9 +278,9 @@
 
 // static
 MediaStreamVideoTrack* MediaStreamVideoTrack::GetVideoTrack(
-     const blink::WebMediaStreamTrack& track) {
+    const WebMediaStreamTrack& track) {
   if (track.IsNull() ||
-      track.Source().GetType() != blink::WebMediaStreamSource::kTypeVideo) {
+      track.Source().GetType() != WebMediaStreamSource::kTypeVideo) {
     return nullptr;
   }
   return static_cast<MediaStreamVideoTrack*>(track.GetPlatformTrack());
@@ -293,7 +290,7 @@
     MediaStreamVideoSource* source,
     const MediaStreamVideoSource::ConstraintsCallback& callback,
     bool enabled)
-    : blink::WebPlatformMediaStreamTrack(true),
+    : WebPlatformMediaStreamTrack(true),
       adapter_settings_(std::make_unique<VideoTrackAdapterSettings>(
           VideoTrackAdapterSettings())),
       is_screencast_(false),
@@ -326,7 +323,7 @@
     const base::Optional<double>& min_frame_rate,
     const MediaStreamVideoSource::ConstraintsCallback& callback,
     bool enabled)
-    : blink::WebPlatformMediaStreamTrack(true),
+    : WebPlatformMediaStreamTrack(true),
       adapter_settings_(
           std::make_unique<VideoTrackAdapterSettings>(adapter_settings)),
       noise_reduction_(noise_reduction),
@@ -360,10 +357,9 @@
   DVLOG(3) << "~MediaStreamVideoTrack()";
 }
 
-void MediaStreamVideoTrack::AddSink(
-    blink::WebMediaStreamSink* sink,
-    const blink::VideoCaptureDeliverFrameCB& callback,
-    bool is_sink_secure) {
+void MediaStreamVideoTrack::AddSink(WebMediaStreamSink* sink,
+                                    const VideoCaptureDeliverFrameCB& callback,
+                                    bool is_sink_secure) {
   DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
   DCHECK(!base::ContainsValue(sinks_, sink));
   sinks_.push_back(sink);
@@ -378,7 +374,7 @@
                                      secure_tracker_.is_capturing_secure());
 }
 
-void MediaStreamVideoTrack::RemoveSink(blink::WebMediaStreamSink* sink) {
+void MediaStreamVideoTrack::RemoveSink(WebMediaStreamSink* sink) {
   DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
   auto it = std::find(sinks_.begin(), sinks_.end(), sink);
   DCHECK(it != sinks_.end());
@@ -401,7 +397,7 @@
 }
 
 void MediaStreamVideoTrack::SetContentHint(
-    blink::WebMediaStreamTrack::ContentHintType content_hint) {
+    WebMediaStreamTrack::ContentHintType content_hint) {
   DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
   for (auto* sink : sinks_)
     sink->OnContentHintChanged(content_hint);
@@ -415,11 +411,11 @@
   } else if (callback) {
     std::move(callback).Run();
   }
-  OnReadyStateChanged(blink::WebMediaStreamSource::kReadyStateEnded);
+  OnReadyStateChanged(WebMediaStreamSource::kReadyStateEnded);
 }
 
 void MediaStreamVideoTrack::GetSettings(
-    blink::WebMediaStreamTrack::Settings& settings) {
+    WebMediaStreamTrack::Settings& settings) {
   DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
   if (!source_)
     return;
@@ -449,12 +445,11 @@
   }
 
   settings.facing_mode = ToWebFacingMode(source_->device().video_facing);
-  settings.resize_mode = blink::WebString::FromASCII(
-      std::string(adapter_settings().target_size()
-                      ? blink::WebMediaStreamTrack::kResizeModeRescale
-                      : blink::WebMediaStreamTrack::kResizeModeNone));
+  settings.resize_mode = WebString::FromASCII(std::string(
+      adapter_settings().target_size() ? WebMediaStreamTrack::kResizeModeRescale
+                                       : WebMediaStreamTrack::kResizeModeNone));
 
-  const base::Optional<blink::CameraCalibration> calibration =
+  const base::Optional<CameraCalibration> calibration =
       source_->device().camera_calibration;
   if (calibration) {
     settings.depth_near = calibration->depth_near;
@@ -471,7 +466,7 @@
 }
 
 void MediaStreamVideoTrack::OnReadyStateChanged(
-    blink::WebMediaStreamSource::ReadyState state) {
+    WebMediaStreamSource::ReadyState state) {
   DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
   for (auto* sink : sinks_)
     sink->OnReadyStateChanged(state);
@@ -495,4 +490,4 @@
   source_->OnFrameDropped(reason);
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/media/stream/video_track_adapter.cc b/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc
similarity index 92%
rename from content/renderer/media/stream/video_track_adapter.cc
rename to third_party/blink/renderer/modules/mediastream/video_track_adapter.cc
index 0280575c..6fe738e 100644
--- a/content/renderer/media/stream/video_track_adapter.cc
+++ b/third_party/blink/renderer/modules/mediastream/video_track_adapter.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 "content/renderer/media/stream/video_track_adapter.h"
+#include "third_party/blink/public/web/modules/mediastream/video_track_adapter.h"
 
 #include <algorithm>
 #include <cmath>
@@ -12,7 +12,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/command_line.h"
 #include "base/containers/flat_map.h"
 #include "base/location.h"
 #include "base/macros.h"
@@ -21,12 +20,13 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
-#include "content/public/common/content_switches.h"
 #include "media/base/bind_to_current_loop.h"
 #include "media/base/limits.h"
 #include "media/base/video_util.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
 
-namespace content {
+namespace blink {
 
 namespace {
 
@@ -119,12 +119,12 @@
 // the resolution adaptation and delivers frames to all registered tracks on the
 // IO-thread. All method calls must be on the IO-thread.
 class VideoTrackAdapter::VideoFrameResolutionAdapter
-    : public base::RefCountedThreadSafe<VideoFrameResolutionAdapter> {
+    : public WTF::ThreadSafeRefCounted<VideoFrameResolutionAdapter> {
  public:
   struct VideoTrackCallbacks {
-    blink::VideoCaptureDeliverFrameCB frame_callback;
-    blink::VideoTrackSettingsCallback settings_callback;
-    blink::VideoTrackFormatCallback format_callback;
+    VideoCaptureDeliverFrameCB frame_callback;
+    VideoTrackSettingsCallback settings_callback;
+    VideoTrackFormatCallback format_callback;
   };
   // Setting |max_frame_rate| to 0.0, means that no frame rate limitation
   // will be done.
@@ -138,9 +138,9 @@
   // |settings_callback| to set track settings on the main thread.
   // |frame_callback| will however be released on the main render thread.
   void AddCallbacks(const MediaStreamVideoTrack* track,
-                    blink::VideoCaptureDeliverFrameCB frame_callback,
-                    blink::VideoTrackSettingsCallback settings_callback,
-                    blink::VideoTrackFormatCallback format_callback);
+                    VideoCaptureDeliverFrameCB frame_callback,
+                    VideoTrackSettingsCallback settings_callback,
+                    VideoTrackFormatCallback format_callback);
 
   // Removes the callbacks associated with |track| if |track| has been added. It
   // is ok to call RemoveCallbacks() even if |track| has not been added.
@@ -166,7 +166,7 @@
 
  private:
   virtual ~VideoFrameResolutionAdapter();
-  friend class base::RefCountedThreadSafe<VideoFrameResolutionAdapter>;
+  friend class WTF::ThreadSafeRefCounted<VideoFrameResolutionAdapter>;
 
   void DoDeliverFrame(const scoped_refptr<media::VideoFrame>& frame,
                       const base::TimeTicks& estimated_capture_time);
@@ -181,7 +181,7 @@
   // Updates track settings if either frame width, height or frame rate have
   // changed since last update.
   void MaybeUpdateTrackSettings(
-      const blink::VideoTrackSettingsCallback& settings_callback,
+      const VideoTrackSettingsCallback& settings_callback,
       const scoped_refptr<media::VideoFrame>& frame);
 
   // Updates computed source format for all tracks if either frame width, height
@@ -194,7 +194,7 @@
   // Bound to the IO-thread.
   THREAD_CHECKER(io_thread_checker_);
 
-  // The task runner where we will release blink::VideoCaptureDeliverFrameCB
+  // The task runner where we will release VideoCaptureDeliverFrameCB
   // registered in AddCallbacks.
   const scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner_;
 
@@ -229,32 +229,25 @@
   DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
   CHECK_NE(0, settings_.max_aspect_ratio());
 
-  const std::string max_fps_str =
-      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-          switches::kWebRtcMaxCaptureFramerate);
-  if (!max_fps_str.empty()) {
-    double value;
-    if (base::StringToDouble(max_fps_str, &value) && value >= 0.0) {
-      DVLOG(1) << "Overriding max frame rate.  Was="
-               << settings_.max_frame_rate() << ", Now=" << value;
-      settings_.set_max_frame_rate(value);
-    } else {
-      DLOG(ERROR) << "Unable to set max fps to " << max_fps_str;
-    }
+  base::Optional<double> max_fps_override =
+      Platform::Current()->GetWebRtcMaxCaptureFrameRate();
+  if (max_fps_override) {
+    DVLOG(1) << "Overriding max frame rate.  Was=" << settings_.max_frame_rate()
+             << ", Now=" << *max_fps_override;
+    settings_.set_max_frame_rate(*max_fps_override);
   }
 }
 
-VideoTrackAdapter::
-VideoFrameResolutionAdapter::~VideoFrameResolutionAdapter() {
+VideoTrackAdapter::VideoFrameResolutionAdapter::~VideoFrameResolutionAdapter() {
   DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
   DCHECK(callbacks_.empty());
 }
 
 void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallbacks(
     const MediaStreamVideoTrack* track,
-    blink::VideoCaptureDeliverFrameCB frame_callback,
-    blink::VideoTrackSettingsCallback settings_callback,
-    blink::VideoTrackFormatCallback format_callback) {
+    VideoCaptureDeliverFrameCB frame_callback,
+    VideoTrackSettingsCallback settings_callback,
+    VideoTrackFormatCallback format_callback) {
   DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
   callbacks_.insert({track,
                      {std::move(frame_callback), std::move(settings_callback),
@@ -439,7 +432,7 @@
 }
 
 void VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeUpdateTrackSettings(
-    const blink::VideoTrackSettingsCallback& settings_callback,
+    const VideoTrackSettingsCallback& settings_callback,
     const scoped_refptr<media::VideoFrame>& frame) {
   DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
   ComputeFrameRate(frame->timestamp(), &track_settings_.frame_rate,
@@ -540,12 +533,11 @@
   DCHECK(adapters_.empty());
 }
 
-void VideoTrackAdapter::AddTrack(
-    const MediaStreamVideoTrack* track,
-    blink::VideoCaptureDeliverFrameCB frame_callback,
-    blink::VideoTrackSettingsCallback settings_callback,
-    blink::VideoTrackFormatCallback format_callback,
-    const VideoTrackAdapterSettings& settings) {
+void VideoTrackAdapter::AddTrack(const MediaStreamVideoTrack* track,
+                                 VideoCaptureDeliverFrameCB frame_callback,
+                                 VideoTrackSettingsCallback settings_callback,
+                                 VideoTrackFormatCallback format_callback,
+                                 const VideoTrackAdapterSettings& settings) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   io_task_runner_->PostTask(
@@ -557,9 +549,9 @@
 
 void VideoTrackAdapter::AddTrackOnIO(
     const MediaStreamVideoTrack* track,
-    blink::VideoCaptureDeliverFrameCB frame_callback,
-    blink::VideoTrackSettingsCallback settings_callback,
-    blink::VideoTrackFormatCallback format_callback,
+    VideoCaptureDeliverFrameCB frame_callback,
+    VideoTrackSettingsCallback settings_callback,
+    VideoTrackFormatCallback format_callback,
     const VideoTrackAdapterSettings& settings) {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
   scoped_refptr<VideoFrameResolutionAdapter> adapter;
@@ -570,8 +562,8 @@
     }
   }
   if (!adapter.get()) {
-    adapter = new VideoFrameResolutionAdapter(renderer_task_runner_, settings,
-                                              frame_dropped_cb_);
+    adapter = base::MakeRefCounted<VideoFrameResolutionAdapter>(
+        renderer_task_runner_, settings, frame_dropped_cb_);
     adapters_.push_back(adapter);
   }
 
@@ -700,7 +692,7 @@
     source_frame_rate = MediaStreamVideoSource::kDefaultFrameRate;
   source_frame_rate_ = source_frame_rate;
   DVLOG(1) << "Monitoring frame creation, first (large) delay: "
-      << (kFirstFrameTimeoutInFrameIntervals / source_frame_rate_) << "s";
+           << (kFirstFrameTimeoutInFrameIntervals / source_frame_rate_) << "s";
   io_task_runner_->PostDelayedTask(
       FROM_HERE,
       base::BindOnce(&VideoTrackAdapter::CheckFramesReceivedOnIO, this,
@@ -748,10 +740,11 @@
   }
 
   // If the track was found, re-add it with new settings.
-  if (!track_callbacks.frame_callback.is_null())
+  if (!track_callbacks.frame_callback.is_null()) {
     AddTrackOnIO(track, std::move(track_callbacks.frame_callback),
                  std::move(track_callbacks.settings_callback),
                  std::move(track_callbacks.format_callback), settings);
+  }
 }
 
 void VideoTrackAdapter::DeliverFrameOnIO(
@@ -809,4 +802,4 @@
                                     source_frame_rate_));
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc b/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
index d380eb2..47f5c1c8 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc
@@ -55,8 +55,7 @@
   if (candidate_init->hasSdpMid())
     sdp_mid = candidate_init->sdpMid();
 
-  // TODO(crbug.com/614958): Change default value to -1.
-  uint16_t sdp_m_line_index = 0;
+  base::Optional<uint16_t> sdp_m_line_index;
   if (candidate_init->hasSdpMLineIndex()) {
     sdp_m_line_index = candidate_init->sdpMLineIndex();
   } else {
@@ -65,7 +64,7 @@
   }
 
   return MakeGarbageCollected<RTCIceCandidate>(WebRTCICECandidate::Create(
-      candidate_init->candidate(), sdp_mid, sdp_m_line_index,
+      candidate_init->candidate(), sdp_mid, std::move(sdp_m_line_index),
       candidate_init->usernameFragment()));
 }
 
@@ -87,9 +86,8 @@
 }
 
 uint16_t RTCIceCandidate::sdpMLineIndex(bool& is_null) const {
-  // TODO(crbug.com/614958): Handle case when SdpMLineIndex has no value.
-  is_null = false;
-  return web_candidate_->SdpMLineIndex();
+  is_null = !web_candidate_->SdpMLineIndex().has_value();
+  return is_null ? 0 : *web_candidate_->SdpMLineIndex();
 }
 
 scoped_refptr<WebRTCICECandidate> RTCIceCandidate::WebCandidate() const {
@@ -147,7 +145,8 @@
   V8ObjectBuilder result(script_state);
   result.AddString("candidate", web_candidate_->Candidate());
   result.AddString("sdpMid", web_candidate_->SdpMid());
-  result.AddNumber("sdpMLineIndex", web_candidate_->SdpMLineIndex());
+  if (web_candidate_->SdpMLineIndex())
+    result.AddNumber("sdpMLineIndex", *web_candidate_->SdpMLineIndex());
   return result.GetScriptValue();
 }
 
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 77b4b56..37ebc7e 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -498,6 +498,7 @@
     "date_components.h",
     "exported/file_path_conversion.cc",
     "exported/interface_registry.cc",
+    "exported/mediastream/media_stream_audio_processor_options.cc",
     "exported/mediastream/media_stream_audio_source.cc",
     "exported/mediastream/media_stream_audio_track.cc",
     "exported/mediastream/web_platform_media_stream_source.cc",
diff --git a/third_party/blink/renderer/platform/audio/denormal_disabler.h b/third_party/blink/renderer/platform/audio/denormal_disabler.h
index c506a70c..e943584 100644
--- a/third_party/blink/renderer/platform/audio/denormal_disabler.h
+++ b/third_party/blink/renderer/platform/audio/denormal_disabler.h
@@ -133,6 +133,8 @@
 #else
 // FIXME: add implementations for other architectures and compilers
 class DenormalDisabler {
+  STACK_ALLOCATED();
+
  public:
   DenormalDisabler() {}
 
diff --git a/third_party/blink/renderer/platform/audio/hrtf_database_loader.h b/third_party/blink/renderer/platform/audio/hrtf_database_loader.h
index f7908dda..1a32714 100644
--- a/third_party/blink/renderer/platform/audio/hrtf_database_loader.h
+++ b/third_party/blink/renderer/platform/audio/hrtf_database_loader.h
@@ -33,6 +33,7 @@
 #include "base/synchronization/waitable_event.h"
 #include "third_party/blink/renderer/platform/audio/hrtf_database.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 #include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
@@ -45,6 +46,8 @@
 // thread.
 class PLATFORM_EXPORT HRTFDatabaseLoader final
     : public RefCounted<HRTFDatabaseLoader> {
+  USING_FAST_MALLOC(HRTFDatabaseLoader);
+
  public:
   // Lazily creates a HRTFDatabaseLoader (if not already created) for the given
   // sample-rate and starts loading asynchronously (when created the first
diff --git a/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc b/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
index 6acec5a93..427e3589 100644
--- a/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
+++ b/third_party/blink/renderer/platform/audio/push_pull_fifo_multithread_test.cc
@@ -15,6 +15,7 @@
 #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 
 namespace blink {
@@ -24,6 +25,8 @@
 // Base FIFOClient with an extra thread for looping and jitter control. The
 // child class must define a specific task to run on the thread.
 class FIFOClient {
+  USING_FAST_MALLOC(FIFOClient);
+
  public:
   FIFOClient(PushPullFIFO* fifo, size_t bus_length, size_t jitter_range_ms)
       : fifo_(fifo),
diff --git a/third_party/blink/renderer/platform/bindings/to_v8.h b/third_party/blink/renderer/platform/bindings/to_v8.h
index 0037001..f3126cf8a 100644
--- a/third_party/blink/renderer/platform/bindings/to_v8.h
+++ b/third_party/blink/renderer/platform/bindings/to_v8.h
@@ -126,37 +126,25 @@
   return v8::Number::New(isolate, value);
 }
 
-inline v8::Local<v8::Value> ToV8(int value,
+inline v8::Local<v8::Value> ToV8(int32_t value,
                                  v8::Local<v8::Object> creation_context,
                                  v8::Isolate* isolate) {
   return ToV8SignedIntegerInternal<sizeof value>(value, isolate);
 }
 
-inline v8::Local<v8::Value> ToV8(long value,
+inline v8::Local<v8::Value> ToV8(int64_t value,
                                  v8::Local<v8::Object> creation_context,
                                  v8::Isolate* isolate) {
   return ToV8SignedIntegerInternal<sizeof value>(value, isolate);
 }
 
-inline v8::Local<v8::Value> ToV8(long long value,
-                                 v8::Local<v8::Object> creation_context,
-                                 v8::Isolate* isolate) {
-  return ToV8SignedIntegerInternal<sizeof value>(value, isolate);
-}
-
-inline v8::Local<v8::Value> ToV8(unsigned value,
+inline v8::Local<v8::Value> ToV8(uint32_t value,
                                  v8::Local<v8::Object> creation_context,
                                  v8::Isolate* isolate) {
   return ToV8UnsignedIntegerInternal<sizeof value>(value, isolate);
 }
 
-inline v8::Local<v8::Value> ToV8(unsigned long value,
-                                 v8::Local<v8::Object> creation_context,
-                                 v8::Isolate* isolate) {
-  return ToV8UnsignedIntegerInternal<sizeof value>(value, isolate);
-}
-
-inline v8::Local<v8::Value> ToV8(unsigned long long value,
+inline v8::Local<v8::Value> ToV8(uint64_t value,
                                  v8::Local<v8::Object> creation_context,
                                  v8::Isolate* isolate) {
   return ToV8UnsignedIntegerInternal<sizeof value>(value, isolate);
diff --git a/third_party/blink/renderer/platform/exported/mediastream/DEPS b/third_party/blink/renderer/platform/exported/mediastream/DEPS
index 36f8289a..731f240 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/DEPS
+++ b/third_party/blink/renderer/platform/exported/mediastream/DEPS
@@ -1,4 +1,10 @@
 
 include_rules = [
-    "+media/base/audio_bus.h",
+    # TODO(crbug.com/923394): Remove these dependencies once std types are
+    # migrated to WTF types in mediastream.
+    "+base/strings/utf_string_conversions.h",
+    "+base/strings/string_number_conversions.h",
+    "+base/strings/string_split.h",
+
+    "+media/base",
 ]
diff --git a/content/renderer/media/stream/media_stream_audio_processor_options.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc
similarity index 96%
rename from content/renderer/media/stream/media_stream_audio_processor_options.cc
rename to third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.cc
index d8d88dd6..64cbfba9 100644
--- a/content/renderer/media/stream/media_stream_audio_processor_options.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_processor_options.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 "content/renderer/media/stream/media_stream_audio_processor_options.h"
+#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h"
 
 #include <stddef.h>
 #include <utility>
@@ -20,14 +20,13 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "content/public/common/content_features.h"
-#include "content/renderer/media/stream/media_stream_constraints_util.h"
 #include "media/base/audio_parameters.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 #include "third_party/webrtc/modules/audio_processing/aec_dump/aec_dump_factory.h"
 #include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
 #include "third_party/webrtc/modules/audio_processing/typing_detection.h"
 
-namespace content {
+namespace blink {
 namespace {
 
 base::Optional<double> GetGainControlCompressionGain(
@@ -212,4 +211,4 @@
   }
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc
index 722b146..ef0d32c 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc
@@ -55,16 +55,15 @@
 
 // static
 MediaStreamAudioSource* MediaStreamAudioSource::From(
-    const blink::WebMediaStreamSource& source) {
-  if (source.IsNull() ||
-      source.GetType() != blink::WebMediaStreamSource::kTypeAudio) {
+    const WebMediaStreamSource& source) {
+  if (source.IsNull() || source.GetType() != WebMediaStreamSource::kTypeAudio) {
     return nullptr;
   }
   return static_cast<MediaStreamAudioSource*>(source.GetPlatformSource());
 }
 
 bool MediaStreamAudioSource::ConnectToTrack(
-    const blink::WebMediaStreamTrack& blink_track) {
+    const WebMediaStreamTrack& blink_track) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!blink_track.IsNull());
 
@@ -86,7 +85,7 @@
 
   // Create and initialize a new MediaStreamAudioTrack and pass ownership of it
   // to the WebMediaStreamTrack.
-  blink::WebMediaStreamTrack mutable_blink_track = blink_track;
+  WebMediaStreamTrack mutable_blink_track = blink_track;
   mutable_blink_track.SetPlatformTrack(
       CreateMediaStreamAudioTrack(blink_track.Id().Utf8()));
 
@@ -121,7 +120,7 @@
 }
 
 void MediaStreamAudioSource::DoChangeSource(
-    const blink::MediaStreamDevice& new_device) {
+    const MediaStreamDevice& new_device) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (is_stopped_)
@@ -149,7 +148,7 @@
 }
 
 void MediaStreamAudioSource::ChangeSourceImpl(
-    const blink::MediaStreamDevice& new_device) {
+    const MediaStreamDevice& new_device) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   DVLOG(1) << "MediaStreamAudioSource@" << this << "::ChangeSourceImpl()";
   NOTIMPLEMENTED();
@@ -184,7 +183,7 @@
   // The W3C spec requires a source automatically stop when the last track is
   // stopped.
   if (!is_stopped_ && did_remove_last_track)
-    blink::WebPlatformMediaStreamSource::StopSource();
+    WebPlatformMediaStreamSource::StopSource();
 }
 
 void MediaStreamAudioSource::StopSourceOnError(const std::string& why) {
@@ -193,16 +192,14 @@
   // Stop source when error occurs.
   task_runner_->PostTask(
       FROM_HERE,
-      base::BindOnce(&blink::WebPlatformMediaStreamSource::StopSource,
-                     GetWeakPtr()));
+      base::BindOnce(&WebPlatformMediaStreamSource::StopSource, GetWeakPtr()));
 }
 
 void MediaStreamAudioSource::SetMutedState(bool muted_state) {
   DVLOG(3) << "MediaStreamAudioSource::SetMutedState state=" << muted_state;
   task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&blink::WebPlatformMediaStreamSource::SetSourceMuted,
-                     GetWeakPtr(), muted_state));
+      FROM_HERE, base::BindOnce(&WebPlatformMediaStreamSource::SetSourceMuted,
+                                GetWeakPtr(), muted_state));
 }
 
 base::SingleThreadTaskRunner* MediaStreamAudioSource::GetTaskRunner() const {
diff --git a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc
index a325cbc..b0ddd56a 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc
@@ -15,7 +15,7 @@
 namespace blink {
 
 MediaStreamAudioTrack::MediaStreamAudioTrack(bool is_local_track)
-    : blink::WebPlatformMediaStreamTrack(is_local_track),
+    : WebPlatformMediaStreamTrack(is_local_track),
       is_enabled_(1),
       weak_factory_(this) {
   DVLOG(1) << "MediaStreamAudioTrack@" << this << "::MediaStreamAudioTrack("
@@ -30,9 +30,9 @@
 
 // static
 MediaStreamAudioTrack* MediaStreamAudioTrack::From(
-    const blink::WebMediaStreamTrack& track) {
+    const WebMediaStreamTrack& track) {
   if (track.IsNull() ||
-      track.Source().GetType() != blink::WebMediaStreamSource::kTypeAudio) {
+      track.Source().GetType() != WebMediaStreamSource::kTypeAudio) {
     return nullptr;
   }
   return static_cast<MediaStreamAudioTrack*>(track.GetPlatformTrack());
@@ -47,7 +47,7 @@
   // If the track has already stopped, just notify the sink of this fact without
   // adding it.
   if (stop_callback_.is_null()) {
-    sink->OnReadyStateChanged(blink::WebMediaStreamSource::kReadyStateEnded);
+    sink->OnReadyStateChanged(WebMediaStreamSource::kReadyStateEnded);
     return;
   }
 
@@ -83,7 +83,7 @@
 }
 
 void MediaStreamAudioTrack::SetContentHint(
-    blink::WebMediaStreamTrack::ContentHintType content_hint) {
+    WebMediaStreamTrack::ContentHintType content_hint) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   std::vector<WebMediaStreamAudioSink*> sinks_to_notify;
@@ -115,7 +115,7 @@
   deliverer_.GetConsumerList(&sinks_to_end);
   for (WebMediaStreamAudioSink* sink : sinks_to_end) {
     deliverer_.RemoveConsumer(sink);
-    sink->OnReadyStateChanged(blink::WebMediaStreamSource::kReadyStateEnded);
+    sink->OnReadyStateChanged(WebMediaStreamSource::kReadyStateEnded);
   }
 
   if (callback)
diff --git a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
index 817da4ff..9d2aa7a1 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
@@ -33,22 +33,20 @@
   if (!stop_callback_.is_null())
     base::ResetAndReturn(&stop_callback_).Run(Owner());
   if (Owner())
-    Owner().SetReadyState(blink::WebMediaStreamSource::kReadyStateEnded);
+    Owner().SetReadyState(WebMediaStreamSource::kReadyStateEnded);
 }
 
 void WebPlatformMediaStreamSource::SetSourceMuted(bool is_muted) {
   // Although this change is valid only if the ready state isn't already Ended,
-  // there's code further along (like in blink::MediaStreamTrack) which filters
+  // there's code further along (like in MediaStreamTrack) which filters
   // that out already.
   if (!Owner())
     return;
-  Owner().SetReadyState(is_muted
-                            ? blink::WebMediaStreamSource::kReadyStateMuted
-                            : blink::WebMediaStreamSource::kReadyStateLive);
+  Owner().SetReadyState(is_muted ? WebMediaStreamSource::kReadyStateMuted
+                                 : WebMediaStreamSource::kReadyStateLive);
 }
 
-void WebPlatformMediaStreamSource::SetDevice(
-    const blink::MediaStreamDevice& device) {
+void WebPlatformMediaStreamSource::SetDevice(const MediaStreamDevice& device) {
   device_ = device;
 }
 
@@ -64,7 +62,7 @@
 }
 
 void WebPlatformMediaStreamSource::ChangeSource(
-    const blink::MediaStreamDevice& new_device) {
+    const MediaStreamDevice& new_device) {
   DoChangeSource(new_device);
 }
 
diff --git a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_track.cc b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_track.cc
index 8c8a25c..306ff31 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_track.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_track.cc
@@ -8,7 +8,7 @@
 
 // static
 WebPlatformMediaStreamTrack* WebPlatformMediaStreamTrack::GetTrack(
-    const blink::WebMediaStreamTrack& track) {
+    const WebMediaStreamTrack& track) {
   return track.IsNull() ? nullptr : track.GetPlatformTrack();
 }
 
diff --git a/third_party/blink/renderer/platform/exported/web_rtc_ice_candidate.cc b/third_party/blink/renderer/platform/exported/web_rtc_ice_candidate.cc
index 9de50dc3..e67ee46 100644
--- a/third_party/blink/renderer/platform/exported/web_rtc_ice_candidate.cc
+++ b/third_party/blink/renderer/platform/exported/web_rtc_ice_candidate.cc
@@ -43,38 +43,42 @@
 scoped_refptr<WebRTCICECandidate> WebRTCICECandidate::Create(
     WebString candidate,
     WebString sdp_mid,
-    uint16_t sdp_m_line_index,
+    base::Optional<uint16_t> sdp_m_line_index,
     WebString username_fragment) {
-  return base::AdoptRef(
-      new WebRTCICECandidate(std::move(candidate), std::move(sdp_mid),
-                             sdp_m_line_index, std::move(username_fragment)));
+  return base::AdoptRef(new WebRTCICECandidate(
+      std::move(candidate), std::move(sdp_mid), std::move(sdp_m_line_index),
+      std::move(username_fragment)));
 }
 
 scoped_refptr<WebRTCICECandidate> WebRTCICECandidate::Create(
     WebString candidate,
     WebString sdp_mid,
-    uint16_t sdp_m_line_index) {
+    int sdp_m_line_index) {
   return base::AdoptRef(new WebRTCICECandidate(
-      std::move(candidate), std::move(sdp_mid), sdp_m_line_index));
+      std::move(candidate), std::move(sdp_mid),
+      sdp_m_line_index < 0 ? base::Optional<uint16_t>()
+                           : base::Optional<uint16_t>(sdp_m_line_index)));
 }
 
-WebRTCICECandidate::WebRTCICECandidate(WebString candidate,
-                                       WebString sdp_mid,
-                                       uint16_t sdp_m_line_index,
-                                       WebString username_fragment)
+WebRTCICECandidate::WebRTCICECandidate(
+    WebString candidate,
+    WebString sdp_mid,
+    base::Optional<uint16_t> sdp_m_line_index,
+    WebString username_fragment)
     : candidate_(std::move(candidate)),
       sdp_mid_(std::move(sdp_mid)),
-      sdp_m_line_index_(sdp_m_line_index),
+      sdp_m_line_index_(std::move(sdp_m_line_index)),
       username_fragment_(std::move(username_fragment)) {
   PopulateFields(false);
 }
 
-WebRTCICECandidate::WebRTCICECandidate(WebString candidate,
-                                       WebString sdp_mid,
-                                       uint16_t sdp_m_line_index)
+WebRTCICECandidate::WebRTCICECandidate(
+    WebString candidate,
+    WebString sdp_mid,
+    base::Optional<uint16_t> sdp_m_line_index)
     : candidate_(std::move(candidate)),
       sdp_mid_(std::move(sdp_mid)),
-      sdp_m_line_index_(sdp_m_line_index) {
+      sdp_m_line_index_(std::move(sdp_m_line_index)) {
   PopulateFields(true);
 }
 
diff --git a/third_party/blink/renderer/platform/fonts/DEPS b/third_party/blink/renderer/platform/fonts/DEPS
index d859ec6..dbb11b1f 100644
--- a/third_party/blink/renderer/platform/fonts/DEPS
+++ b/third_party/blink/renderer/platform/fonts/DEPS
@@ -6,6 +6,9 @@
     "+third_party/blink/renderer/platform/fonts",
 
     # Dependencies.
+    "+base/mac/foundation_util.h",
+    "+base/mac/scoped_cftyperef.h",
+    "+base/mac/scoped_nsobject.h",
     "+cc",
     "+third_party/blink/renderer/platform/font_family_names.h",
     "+third_party/blink/renderer/platform/geometry",
diff --git a/third_party/blink/renderer/platform/fonts/font_platform_data.h b/third_party/blink/renderer/platform/fonts/font_platform_data.h
index e2e018f..e4c9de7 100644
--- a/third_party/blink/renderer/platform/fonts/font_platform_data.h
+++ b/third_party/blink/renderer/platform/fonts/font_platform_data.h
@@ -55,13 +55,6 @@
 typedef const struct __CTFont* CTFontRef;
 
 #include <objc/objc-auto.h>
-
-inline CTFontRef toCTFontRef(NSFont* nsFont) {
-  return reinterpret_cast<CTFontRef>(nsFont);
-}
-inline NSFont* toNSFont(CTFontRef ctFontRef) {
-  return const_cast<NSFont*>(reinterpret_cast<const NSFont*>(ctFontRef));
-}
 #endif  // defined(OS_MACOSX)
 
 class SkFont;
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
index 829170d..3db8f050 100644
--- a/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
+++ b/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
@@ -32,6 +32,7 @@
 #import <AppKit/AppKit.h>
 #include <memory>
 #include "base/location.h"
+#include "base/mac/foundation_util.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/font_family_names.h"
 #include "third_party/blink/renderer/platform/fonts/font_description.h"
@@ -131,7 +132,7 @@
 
   const FontPlatformData& platform_data =
       font_data_to_substitute->PlatformData();
-  NSFont* ns_font = toNSFont(platform_data.CtFont());
+  NSFont* ns_font = base::mac::CFToNSCast(platform_data.CtFont());
 
   NSString* string =
       [[NSString alloc] initWithCharactersNoCopy:code_units
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
index 8d71fc2..06708fc 100644
--- a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
+++ b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
@@ -32,11 +32,13 @@
 #import <AppKit/AppKit.h>
 #import <Foundation/Foundation.h>
 #import <math.h>
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_nsobject.h"
 #include "base/stl_util.h"
 #include "third_party/blink/renderer/platform/fonts/font_cache.h"
 #include "third_party/blink/renderer/platform/mac/version_util_mac.h"
 #import "third_party/blink/renderer/platform/wtf/hash_set.h"
-#import "third_party/blink/renderer/platform/wtf/retain_ptr.h"
 #import "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
 
 @interface NSFont (YosemiteAdditions)
@@ -130,38 +132,36 @@
 NSFont* MatchUniqueFont(const AtomicString& unique_font_name, float size) {
   // Testing with a large list of fonts available on Mac OS shows that matching
   // for kCTFontNameAttribute matches postscript name as well as full font name.
-  WTF::RetainPtr<CFMutableDictionaryRef> attributes(
-      CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL));
-  WTF::RetainPtr<NSString> desired_name(unique_font_name);
-  CFDictionarySetValue(attributes.Get(), kCTFontNameAttribute,
-                       desired_name.Get());
-  WTF::RetainPtr<CFNumberRef> font_size =
-      CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat32Type, &size);
-  CFDictionarySetValue(attributes.Get(), kCTFontSizeAttribute, font_size.Get());
-  WTF::RetainPtr<CTFontDescriptorRef> descriptor(
-      CTFontDescriptorCreateWithAttributes(attributes.Get()));
-  WTF::RetainPtr<CTFontRef> matched_font(
-      CTFontCreateWithFontDescriptor(descriptor.Get(), 0, nullptr));
+  NSString* desired_name = unique_font_name;
+  NSDictionary* attributes = @{
+    (NSString*)kCTFontNameAttribute : desired_name,
+    (NSString*)kCTFontSizeAttribute : @(size)
+  };
+  base::ScopedCFTypeRef<CTFontDescriptorRef> descriptor(
+      CTFontDescriptorCreateWithAttributes(base::mac::NSToCFCast(attributes)));
+
+  base::ScopedCFTypeRef<CTFontRef> matched_font(
+      CTFontCreateWithFontDescriptor(descriptor, 0, nullptr));
+
   // CoreText will usually give us *something* but not always an exactly
   // matched font.
-  DCHECK(matched_font.Get());
-  WTF::RetainPtr<CFStringRef> matched_font_ps_name(
-      CTFontCopyName(matched_font.Get(), kCTFontPostScriptNameKey));
-  WTF::RetainPtr<CFStringRef> matched_font_full_font_name(
-      CTFontCopyName(matched_font.Get(), kCTFontFullNameKey));
+  DCHECK(matched_font);
+  base::ScopedCFTypeRef<CFStringRef> matched_font_ps_name(
+      CTFontCopyName(matched_font, kCTFontPostScriptNameKey));
+  base::ScopedCFTypeRef<CFStringRef> matched_font_full_font_name(
+      CTFontCopyName(matched_font, kCTFontFullNameKey));
   // If the found font does not match in postscript name or full font name, it's
   // not the exact match that is required, so return nullptr.
-  if ((kCFCompareEqualTo !=
-       CFStringCompare(matched_font_ps_name.Get(),
-                       (__bridge CFStringRef)desired_name.Get(),
-                       kCFCompareCaseInsensitive)) &&
-      (kCFCompareEqualTo !=
-       CFStringCompare(matched_font_full_font_name.Get(),
-                       (__bridge CFStringRef)desired_name.Get(),
-                       kCFCompareCaseInsensitive))) {
+  if (kCFCompareEqualTo != CFStringCompare(matched_font_ps_name,
+                                           base::mac::NSToCFCast(desired_name),
+                                           kCFCompareCaseInsensitive) &&
+      kCFCompareEqualTo != CFStringCompare(matched_font_full_font_name,
+                                           base::mac::NSToCFCast(desired_name),
+                                           kCFCompareCaseInsensitive)) {
     return nullptr;
   }
-  return (__bridge NSFont*)matched_font.LeakRef();
+
+  return [base::mac::CFToNSCast(matched_font.release()) autorelease];
 }
 
 // Family name is somewhat of a misnomer here.  We first attempt to find an
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
index 1fcd34ea..303f9013 100644
--- a/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
+++ b/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
@@ -26,6 +26,9 @@
 #import <AppKit/NSFont.h>
 #import <AvailabilityMacros.h>
 
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_nsobject.h"
 #include "base/stl_util.h"
 #import "third_party/blink/public/platform/mac/web_sandbox_support.h"
 #import "third_party/blink/public/platform/platform.h"
@@ -33,7 +36,6 @@
 #import "third_party/blink/renderer/platform/fonts/opentype/font_settings.h"
 #import "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
 #import "third_party/blink/renderer/platform/web_test_support.h"
-#import "third_party/blink/renderer/platform/wtf/retain_ptr.h"
 #import "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #import "third_party/skia/include/core/SkFont.h"
 #import "third_party/skia/include/core/SkStream.h"
@@ -42,13 +44,12 @@
 namespace blink {
 
 static bool CanLoadInProcess(NSFont* ns_font) {
-  RetainPtr<CGFontRef> cg_font(kAdoptCF,
-                               CTFontCopyGraphicsFont(toCTFontRef(ns_font), 0));
+  base::ScopedCFTypeRef<CGFontRef> cg_font(
+      CTFontCopyGraphicsFont(base::mac::NSToCFCast(ns_font), 0));
   // Toll-free bridged types CFStringRef and NSString*.
-  RetainPtr<NSString> font_name(
-      kAdoptNS, const_cast<NSString*>(reinterpret_cast<const NSString*>(
-                    CGFontCopyPostScriptName(cg_font.Get()))));
-  return ![font_name.Get() isEqualToString:@"LastResort"];
+  base::scoped_nsobject<NSString> font_name(
+      base::mac::CFToNSCast(CGFontCopyPostScriptName(cg_font)));
+  return ![font_name isEqualToString:@"LastResort"];
 }
 
 static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
@@ -56,22 +57,20 @@
   if (descriptor)
     return descriptor;
 
-  RetainPtr<CTFontDescriptorRef> last_resort(
-      kAdoptCF, CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0));
-  const void* descriptors[] = {last_resort.Get()};
-  RetainPtr<CFArrayRef> values_array(
-      kAdoptCF, CFArrayCreate(kCFAllocatorDefault, descriptors,
-                              base::size(descriptors), &kCFTypeArrayCallBacks));
+  base::ScopedCFTypeRef<CTFontDescriptorRef> last_resort(
+      CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0));
+  const void* descriptors[] = {last_resort};
+  base::ScopedCFTypeRef<CFArrayRef> values_array(
+      CFArrayCreate(kCFAllocatorDefault, descriptors, base::size(descriptors),
+                    &kCFTypeArrayCallBacks));
 
   const void* keys[] = {kCTFontCascadeListAttribute};
-  const void* values[] = {values_array.Get()};
-  RetainPtr<CFDictionaryRef> attributes(
-      kAdoptCF,
-      CFDictionaryCreate(kCFAllocatorDefault, keys, values, base::size(keys),
-                         &kCFTypeDictionaryKeyCallBacks,
-                         &kCFTypeDictionaryValueCallBacks));
+  const void* values[] = {values_array};
+  base::ScopedCFTypeRef<CFDictionaryRef> attributes(CFDictionaryCreate(
+      kCFAllocatorDefault, keys, values, base::size(keys),
+      &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
 
-  descriptor = CTFontDescriptorCreateWithAttributes(attributes.Get());
+  descriptor = CTFontDescriptorCreateWithAttributes(attributes);
 
   return descriptor;
 }
@@ -90,21 +89,18 @@
 
   CGFontRef loaded_cg_font;
   uint32_t font_id;
-  if (!sandbox_support->LoadFont(toCTFontRef(ns_font), &loaded_cg_font,
-                                 &font_id)) {
+  if (!sandbox_support->LoadFont(base::mac::NSToCFCast(ns_font),
+                                 &loaded_cg_font, &font_id)) {
     // TODO crbug.com/461279: Make this appear in the inspector console?
     DLOG(ERROR)
         << "Loading user font \"" << [[ns_font familyName] UTF8String]
         << "\" from non system location failed. Corrupt or missing font file?";
     return nullptr;
   }
-  RetainPtr<CGFontRef> cg_font(kAdoptCF, loaded_cg_font);
-  RetainPtr<CTFontRef> ct_font(
-      kAdoptCF,
-      CTFontCreateWithGraphicsFont(cg_font.Get(), text_size, 0,
-                                   CascadeToLastResortFontDescriptor()));
-  sk_sp<SkTypeface> return_font(
-      SkCreateTypefaceFromCTFont(ct_font.Get(), cg_font.Get()));
+  base::ScopedCFTypeRef<CGFontRef> cg_font(loaded_cg_font);
+  base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithGraphicsFont(
+      cg_font, text_size, 0, CascadeToLastResortFontDescriptor()));
+  sk_sp<SkTypeface> return_font(SkCreateTypefaceFromCTFont(ct_font, cg_font));
 
   if (!return_font.get())
     // TODO crbug.com/461279: Make this appear in the inspector console?
@@ -185,7 +181,7 @@
   DCHECK(ns_font);
   sk_sp<SkTypeface> typeface;
   if (CanLoadInProcess(ns_font)) {
-    typeface.reset(SkCreateTypefaceFromCTFont(toCTFontRef(ns_font)));
+    typeface.reset(SkCreateTypefaceFromCTFont(base::mac::NSToCFCast(ns_font)));
   } else {
     // In process loading fails for cases where third party font manager
     // software registers fonts in non system locations such as /Library/Fonts
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
index 75467c6..a39860b 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -975,9 +975,9 @@
 }
 
 // Every effect is supposed to have render surface enabled for grouping, but we
-// can omit one if the effect is opacity-only, render surface is not forced,
-// and the effect has only one compositing child. This is both for optimization
-// and not introducing sub-pixel differences in web tests.
+// can omit one if the effect is opacity- or blend-mode-only, render surface is
+// not forced, and the effect has only one compositing child. This is both for
+// optimization and not introducing sub-pixel differences in web tests.
 // TODO(crbug.com/504464): There is ongoing work in cc to delay render surface
 // decision until later phase of the pipeline. Remove premature optimization
 // here once the work is ready.
@@ -994,7 +994,8 @@
          !effect->has_render_surface || !effect->backdrop_filters.IsEmpty();
          effect = effect_tree.Node(effect->parent_id)) {
       found_backdrop_filter |= !effect->backdrop_filters.IsEmpty();
-      if ((effect->opacity != 1.f || effect->has_potential_opacity_animation) &&
+      if ((effect->opacity != 1.f || effect->has_potential_opacity_animation ||
+           effect->blend_mode != SkBlendMode::kSrcOver) &&
           (!pending_render_surfaces.insert(effect->id).is_new_entry ||
            found_backdrop_filter)) {
         // The opacity-only effect is seen a second time, which means that it
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
index 134af9b..de80a353 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -2041,13 +2041,78 @@
   EXPECT_EQ(gfx::Size(100, 100), masking_layer->bounds());
   const cc::EffectNode* masking_group =
       GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
-  EXPECT_TRUE(masking_group->has_render_surface);
+  EXPECT_FALSE(masking_group->has_render_surface);
   EXPECT_EQ(masked_group->id, masking_group->parent_id);
   ASSERT_EQ(1u, masking_group->filters.size());
   EXPECT_EQ(cc::FilterOperation::REFERENCE,
             masking_group->filters.at(0).type());
 }
 
+TEST_P(PaintArtifactCompositorTest, CompositedLuminanceMaskTwoChildren) {
+  auto masked = CreateOpacityEffect(
+      e0(), 1.0, CompositingReason::kIsolateCompositedDescendants);
+  EffectPaintPropertyNode::State masking_state;
+  masking_state.local_transform_space = &t0();
+  masking_state.output_clip = &c0();
+  masking_state.color_filter = kColorFilterLuminanceToAlpha;
+  masking_state.blend_mode = SkBlendMode::kDstIn;
+  masking_state.direct_compositing_reasons =
+      CompositingReason::kSquashingDisallowed;
+  auto masking =
+      EffectPaintPropertyNode::Create(*masked, std::move(masking_state));
+
+  auto child_of_masked = CreateOpacityEffect(
+      *masking, 1.0, CompositingReason::kIsolateCompositedDescendants);
+
+  TestPaintArtifact artifact;
+  artifact.Chunk(t0(), c0(), *masked)
+      .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+  artifact.Chunk(t0(), c0(), *child_of_masked)
+      .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+  artifact.Chunk(t0(), c0(), *masking)
+      .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+  Update(artifact.Build());
+  ASSERT_EQ(3u, ContentLayerCount());
+
+  const cc::Layer* masking_layer = ContentLayerAt(2);
+  const cc::EffectNode* masking_group =
+      GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
+
+  // There is a render surface because there are two children.
+  EXPECT_TRUE(masking_group->has_render_surface);
+  ASSERT_EQ(1u, masking_group->filters.size());
+  EXPECT_EQ(cc::FilterOperation::REFERENCE,
+            masking_group->filters.at(0).type());
+}
+
+TEST_P(PaintArtifactCompositorTest, CompositedExoticBlendMode) {
+  auto masked = CreateOpacityEffect(
+      e0(), 1.0, CompositingReason::kIsolateCompositedDescendants);
+  EffectPaintPropertyNode::State masking_state;
+  masking_state.local_transform_space = &t0();
+  masking_state.output_clip = &c0();
+  masking_state.blend_mode = SkBlendMode::kXor;
+  masking_state.direct_compositing_reasons =
+      CompositingReason::kSquashingDisallowed;
+  auto masking =
+      EffectPaintPropertyNode::Create(*masked, std::move(masking_state));
+
+  TestPaintArtifact artifact;
+  artifact.Chunk(t0(), c0(), *masked)
+      .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+  artifact.Chunk(t0(), c0(), *masking)
+      .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+  Update(artifact.Build());
+  ASSERT_EQ(2u, ContentLayerCount());
+
+  const cc::Layer* masking_layer = ContentLayerAt(1);
+  const cc::EffectNode* masking_group =
+      GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
+
+  /// This requires a render surface.
+  EXPECT_TRUE(masking_group->has_render_surface);
+}
+
 TEST_P(PaintArtifactCompositorTest, UpdateProducesNewSequenceNumber) {
   // A 90 degree clockwise rotation about (100, 100).
   auto transform = CreateTransform(t0(), TransformationMatrix().Rotate(90),
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index e0ec83db..6695213 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -729,14 +729,16 @@
       next_effect.GetCompositorElementId().GetInternalValue();
   effect_node.clip_id = output_clip_id;
 
-  // An effect with filters, backdrop filters or non-kSrcOver blend mode needs
-  // a render surface. The render surface status of opacity-only effects will be
-  // updated in PaintArtifactCompositor::UpdateRenderSurfaceForEffects().
+  // An effect with filters or backdrop filters needs a render surface.
+  // Also, kDstIn and kSrcOver blend modes have fast paths if only one layer
+  // is under the blend mode. This value is adjusted in
+  // PAC::UpdateRenderSurfaceForEffects to account for more than one layer.
   if (!next_effect.Filter().IsEmpty() ||
       next_effect.IsRunningFilterAnimationOnCompositor() ||
       !next_effect.BackdropFilter().IsEmpty() ||
       next_effect.IsRunningBackdropFilterAnimationOnCompositor() ||
-      used_blend_mode != SkBlendMode::kSrcOver)
+      (used_blend_mode != SkBlendMode::kSrcOver &&
+       used_blend_mode != SkBlendMode::kDstIn))
     effect_node.has_render_surface = true;
 
   effect_node.opacity = next_effect.Opacity();
diff --git a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
index 8a222f5..624a72c4 100644
--- a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
@@ -65,6 +65,12 @@
           color_filter != other.color_filter ||
           backdrop_filter_bounds != other.backdrop_filter_bounds ||
           blend_mode != other.blend_mode ||
+          is_running_opacity_animation_on_compositor !=
+              other.is_running_opacity_animation_on_compositor ||
+          is_running_filter_animation_on_compositor !=
+              other.is_running_filter_animation_on_compositor ||
+          is_running_backdrop_filter_animation_on_compositor !=
+              other.is_running_backdrop_filter_animation_on_compositor ||
           direct_compositing_reasons != other.direct_compositing_reasons ||
           compositor_element_id != other.compositor_element_id ||
           filters_origin != other.filters_origin) {
@@ -83,14 +89,6 @@
           !is_running_backdrop_filter_animation_on_compositor) {
         return PaintPropertyChangeType::kChangedOnlyValues;
       }
-      if (is_running_opacity_animation_on_compositor !=
-              other.is_running_opacity_animation_on_compositor ||
-          is_running_filter_animation_on_compositor !=
-              other.is_running_filter_animation_on_compositor ||
-          is_running_backdrop_filter_animation_on_compositor !=
-              other.is_running_backdrop_filter_animation_on_compositor) {
-        return PaintPropertyChangeType::kChangedOnlyCompositedAnimationStatus;
-      }
       if (opacity_changed || filter_changed || backdrop_filter_changed) {
         return PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues;
       }
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
index a5df595..f26547b 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h
@@ -30,8 +30,6 @@
 enum class PaintPropertyChangeType {
   kUnchanged,
   kChangedOnlyCompositedAnimationValues,
-  // TODO(crbug.com/937929): See ObjectPaintProperties::Update().
-  kChangedOnlyCompositedAnimationStatus,
   kChangedOnlyValues,
   // A paint property node is added or removed. This value is used only in
   // renderer/core classes.
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
index 1c31dea..9a48168 100644
--- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -69,6 +69,8 @@
           flattens_inherited_transform != other.flattens_inherited_transform ||
           affected_by_outer_viewport_bounds_delta !=
               other.affected_by_outer_viewport_bounds_delta ||
+          is_running_animation_on_compositor !=
+              other.is_running_animation_on_compositor ||
           backface_visibility != other.backface_visibility ||
           rendering_context_id != other.rendering_context_id ||
           direct_compositing_reasons != other.direct_compositing_reasons ||
@@ -79,16 +81,11 @@
           !StickyConstraintEquals(other)) {
         return PaintPropertyChangeType::kChangedOnlyValues;
       }
-      bool matrix_changed = matrix != other.matrix;
-      if (!is_running_animation_on_compositor && matrix_changed) {
-        return PaintPropertyChangeType::kChangedOnlyValues;
-      }
-      if (is_running_animation_on_compositor !=
-          other.is_running_animation_on_compositor) {
-        return PaintPropertyChangeType::kChangedOnlyCompositedAnimationStatus;
-      }
-      if (matrix_changed) {
-        return PaintPropertyChangeType::kChangedOnlyCompositedAnimationValues;
+      if (matrix != other.matrix) {
+        return is_running_animation_on_compositor
+                   ? PaintPropertyChangeType::
+                         kChangedOnlyCompositedAnimationValues
+                   : PaintPropertyChangeType::kChangedOnlyValues;
       }
       return PaintPropertyChangeType::kUnchanged;
     }
diff --git a/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.cc b/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.cc
index dbc8c6f..969fb02a 100644
--- a/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.cc
+++ b/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.cc
@@ -49,6 +49,10 @@
   traced_value_.SetString(name, adaptor.AsStringPiece());
 }
 
+void TracedValue::SetValue(const char* name, TracedValue* value) {
+  traced_value_.SetValue(name, &value->traced_value_);
+}
+
 void TracedValue::SetStringWithCopiedName(const char* name,
                                           const String& value) {
   StringUTF8Adaptor adaptor(value);
diff --git a/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h b/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h
index 1efbf63..bbcf52c3 100644
--- a/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h
+++ b/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h
@@ -27,6 +27,7 @@
   void SetDouble(const char* name, double value);
   void SetBoolean(const char* name, bool value);
   void SetString(const char* name, const String& value);
+  void SetValue(const char* name, TracedValue* value);
   void BeginArray(const char* name);
   void BeginDictionary(const char* name);
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 733effae..1be0a51 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1403,6 +1403,10 @@
       status: "stable",
     },
     {
+      name: "UserActivationDelegation",
+      status: "experimental",
+    },
+    {
       name: "UserActivationSameOriginVisibility",
     },
     {
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 ceb6c930..6b5f276 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
@@ -395,6 +395,10 @@
         ],
     },
     {
+        'paths': ['third_party/blink/renderer/core/editing/web_substring_util.mm'],
+        'allowed': ['base::mac::CFToNSCast'],
+    },
+    {
         'paths': ['third_party/blink/renderer/core/fetch/data_consumer_handle_test_util.cc'],
         'allowed': [
             # The existing code already contains gin::IsolateHolder.
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
index 0ac82aea..ed23014 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=CompositeAfterPaint
@@ -436,3 +436,37 @@
 
 # Other:
 crbug.com/935728 fast/frames/transparent-scrollbar.html [ Failure ]
+
+Bug(none) external/wpt/css/css-masking/clip-path-svg-content/clip-path-recursion-001.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/clip-path-svg-content/mask-nested-clip-path-001.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/clip-path-svg-content/mask-nested-clip-path-002.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/clip-path-svg-content/mask-nested-clip-path-004.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/clip-path-svg-content/mask-nested-clip-path-007.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/clip-path-svg-content/mask-nested-clip-path-008.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/clip-path-svg-content/mask-nested-clip-path-010.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/clip-path-svg-content/mask-nested-clip-path-panning-001.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/mask-svg-content/mask-type-002.svg [ Failure ]
+Bug(none) external/wpt/css/css-masking/mask-svg-content/mask-type-003.svg [ Failure ]
+Bug(none) images/color-profile-mask-image-svg.html [ Failure ]
+Bug(none) svg/W3C-SVG-1.1/masking-intro-01-f.svg [ Failure ]
+Bug(none) svg/W3C-SVG-1.1/masking-mask-01-b.svg [ Failure ]
+Bug(none) svg/W3C-SVG-1.1/masking-path-04-b.svg [ Failure ]
+Bug(none) svg/batik/text/textEffect2.svg [ Failure ]
+Bug(none) svg/clip-path/clip-in-mask.svg [ Failure ]
+Bug(none) svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg [ Failure ]
+Bug(none) svg/clip-path/deep-nested-clip-in-mask-panning.svg [ Failure ]
+Bug(none) svg/clip-path/deep-nested-clip-in-mask.svg [ Failure ]
+Bug(none) svg/clip-path/nested-clip-in-mask-image-based-clipping.svg [ Failure ]
+Bug(none) svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg [ Failure ]
+Bug(none) svg/clip-path/nested-clip-in-mask-path-based-clipping.svg [ Failure ]
+Bug(none) svg/custom/clamped-masking-clipping.svg [ Failure ]
+Bug(none) svg/custom/circular-clip-path-references-crash.svg [ Failure ]
+Bug(none) svg/custom/grayscale-gradient-mask.svg [ Failure ]
+Bug(none) svg/custom/mask-changes.svg [ Failure ]
+Bug(none) svg/custom/mask-colorspace.svg [ Failure ]
+Bug(none) svg/custom/mask-with-default-value.svg [ Failure ]
+Bug(none) svg/custom/masking-clipping-hidpi.svg [ Failure ]
+Bug(none) svg/filters/filter-clip.svg [ Failure ]
+Bug(none) svg/masking/mask-type-luminance.svg [ Failure ]
+Bug(none) svg/masking/mask-type-not-set.svg [ Failure ]
+Bug(none) svg/zoom/page/zoom-mask-with-percentages.svg [ Failure ]
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
index 15ef93a..4d37e2ba 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -106,6 +106,7 @@
 crbug.com/591099 external/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.html?6001-7000 [ Pass ]
 crbug.com/591099 external/wpt/WebCryptoAPI/derive_bits_keys/pbkdf2.https.any.html?7001-8000 [ Pass ]
 crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/successes_RSA-OAEP.https.any.worker.html?121-130 [ Pass ]
+crbug.com/591099 external/wpt/acid/acid2/reftest.html [ Failure Pass ]
 crbug.com/591099 external/wpt/bluetooth/requestDevice/request-from-iframe.https.html [ Pass ]
 crbug.com/591099 external/wpt/bluetooth/server/disconnect/detach-gc.https.html [ Pass ]
 crbug.com/591099 external/wpt/bluetooth/server/disconnect/gc-detach.https.html [ Pass ]
@@ -118,6 +119,7 @@
 crbug.com/591099 external/wpt/bluetooth/service/getCharacteristics/gen-reconnect-during-with-uuid.https.html [ Pass ]
 crbug.com/591099 external/wpt/bluetooth/service/getCharacteristics/gen-reconnect-during.https.html [ Pass ]
 crbug.com/591099 external/wpt/content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html [ Timeout ]
+crbug.com/591099 external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html [ Pass ]
 crbug.com/591099 external/wpt/cookies/http-state/domain-tests.html [ Pass ]
 crbug.com/591099 external/wpt/cookies/samesite/window-open-reload.html [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/floats/float-nowrap-3.html [ Pass ]
@@ -132,7 +134,7 @@
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/block-in-inline-remove-006.xht [ Pass ]
 crbug.com/591099 external/wpt/css/CSS2/text/white-space-mixed-003.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-animations/Element-getAnimations-dynamic-changes.tentative.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-animations/Element-getAnimations.tentative.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-animations/Element-getAnimations.tentative.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-contain/contain-size-grid-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-contain/contain-size-multicol-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-contain/contain-style-counters-004.html [ Failure ]
@@ -345,10 +347,11 @@
 crbug.com/591099 external/wpt/fetch/http-cache/cc-request.html [ Pass ]
 crbug.com/591099 external/wpt/fullscreen/api/element-ready-check-containing-iframe-manual.html [ Pass ]
 crbug.com/591099 external/wpt/fullscreen/api/element-request-fullscreen-and-remove-manual.html [ Failure Pass ]
-crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ]
-crbug.com/591099 external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Pass ]
+crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ]
+crbug.com/591099 external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Crash Failure ]
 crbug.com/591099 external/wpt/html/browsers/the-window-object/window-open-noopener.html?_parent [ Pass ]
 crbug.com/591099 external/wpt/html/browsers/the-window-object/window-open-noopener.html?_top [ Pass ]
+crbug.com/591099 external/wpt/html/browsers/windows/embedded-opener-remove-frame.html [ Pass ]
 crbug.com/591099 external/wpt/html/rendering/non-replaced-elements/the-hr-element-0/width.html [ Failure ]
 crbug.com/591099 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-1i.html [ Failure ]
 crbug.com/591099 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cues-cuechange.html [ Pass ]
@@ -375,8 +378,8 @@
 crbug.com/591099 external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Pass ]
 crbug.com/591099 external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Pass ]
 crbug.com/591099 external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/same-origin-insecure.http.html [ Failure ]
+crbug.com/591099 external/wpt/screen-orientation/onchange-event.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/service-workers/service-worker/fetch-frame-resource.https.html [ Pass ]
-crbug.com/591099 external/wpt/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html [ Failure Pass ]
 crbug.com/591099 external/wpt/svg/text/reftests/text-inline-size-101.svg [ Failure ]
 crbug.com/591099 external/wpt/wasm/webapi/rejected-arg.any.serviceworker.html [ Timeout ]
 crbug.com/591099 external/wpt/webauthn/createcredential-extensions.https.html [ Pass ]
@@ -415,7 +418,7 @@
 crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ]
 crbug.com/591099 fast/canvas/OffscreenCanvas-copyImage.html [ Pass ]
 crbug.com/591099 fast/css-grid-layout/grid-baseline.html [ Failure ]
-crbug.com/591099 fast/css-intrinsic-dimensions/height-css-tables-collapsed.html [ Pass ]
+crbug.com/591099 fast/css-intrinsic-dimensions/height-css-tables-collapsed.html [ Failure Pass ]
 crbug.com/591099 fast/css-intrinsic-dimensions/height-positioned.html [ Pass ]
 crbug.com/591099 fast/css-intrinsic-dimensions/height-tables.html [ Failure Pass ]
 crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ]
@@ -433,7 +436,7 @@
 crbug.com/889721 fast/inline/outline-continuations.html [ Failure ]
 crbug.com/591099 fast/multicol/border-radius-clipped-layer.html [ Pass ]
 crbug.com/591099 fast/peerconnection/RTCPeerConnection-many.html [ Pass ]
-crbug.com/591099 fast/replaced/replaced-breaking.html [ Failure Pass ]
+crbug.com/591099 fast/replaced/replaced-breaking.html [ Failure ]
 crbug.com/591099 fast/text/descent-clip-in-scaled-page.html [ Failure ]
 crbug.com/899902 fast/text/ellipsis-with-self-painting-layer.html [ Pass ]
 crbug.com/591099 fast/text/emoji-vertical-origin-visual.html [ Failure ]
@@ -464,13 +467,13 @@
 crbug.com/591099 http/tests/fetch/window/thorough/cors-preflight2-base-https-other-https.html [ Pass ]
 crbug.com/591099 http/tests/fetch/workers/thorough/auth-base-https-other-https.html [ Pass ]
 crbug.com/591099 http/tests/fetch/workers/thorough/cookie-nocors-base-https-other-https.html [ Pass ]
-crbug.com/591099 http/tests/html/validation-bubble-oopif-clip.html [ Failure Pass ]
+crbug.com/591099 http/tests/html/validation-bubble-oopif-clip.html [ Pass ]
 crbug.com/591099 http/tests/images/feature-policy-unoptimized-images-cached-image.html [ Failure Pass ]
 crbug.com/591099 http/tests/images/image-decode-in-frame.html [ Pass ]
-crbug.com/591099 http/tests/images/restyle-decode-error.html [ Failure ]
+crbug.com/591099 http/tests/images/restyle-decode-error.html [ Failure Pass ]
 crbug.com/591099 http/tests/inspector-protocol/fetch/fetch-renderer.js [ Pass Timeout ]
 crbug.com/591099 http/tests/inspector-protocol/network/navigation-blocking-xorigin-iframe.js [ Failure Pass ]
-crbug.com/591099 http/tests/media/autoplay/document-user-activation-cross-origin-feature-policy-disabled.html [ Failure ]
+crbug.com/591099 http/tests/media/autoplay/document-user-activation-cross-origin-feature-policy-disabled.html [ Failure Pass ]
 crbug.com/591099 http/tests/media/video-load-metadata-decode-error.html [ Pass ]
 crbug.com/591099 http/tests/multipart/multipart-main-resource.html [ Pass ]
 crbug.com/591099 http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure ]
@@ -521,14 +524,11 @@
 crbug.com/591099 virtual/display-lock/display-lock/lock-before-append/measure-forced-layout.html [ Failure ]
 crbug.com/591099 virtual/display-lock/display-lock/lock-before-append/measure-updated-layout.html [ Failure ]
 crbug.com/591099 virtual/exotic-color-space/ [ Skip ]
-crbug.com/591099 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-in-http-header-control.html [ Failure Pass ]
-crbug.com/591099 virtual/feature-policy-for-sandbox/http/tests/security/mixedContent/insecure-plugin-in-iframe.html [ Failure Pass ]
-crbug.com/591099 virtual/feature-policy-for-sandbox/http/tests/security/sandbox-iframe-blocks-modals.php [ Failure Pass ]
 crbug.com/591099 virtual/feature-policy-for-sandbox/http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ]
 crbug.com/591099 virtual/fractional_scrolling/fast/scrolling/fractional-scroll-offset-fixed-position-non-composited.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ Pass ]
 crbug.com/591099 virtual/gpu-rasterization/images/image-page-injected-script-crash.html [ Pass ]
-crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-copyImage.html [ Failure Pass ]
+crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-copyImage.html [ Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/OffscreenCanvas-filter.html [ Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-arc-circumference-fill.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-blend-image.html [ Pass ]
@@ -567,7 +567,7 @@
 crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects-continuation.html [ Failure ]
 crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Failure ]
 crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
-crbug.com/591099 virtual/user-activation-v2/fullscreen/model/fully-exit-fullscreen-nested-iframe.html [ Pass Timeout ]
+crbug.com/591099 virtual/user-activation-v2/fullscreen/model/fully-exit-fullscreen-nested-iframe.html [ Pass ]
 crbug.com/591099 virtual/video-surface-layer/media/W3C/video/networkState/networkState_during_progress.html [ Pass ]
 crbug.com/591099 virtual/video-surface-layer/media/autoplay-when-visible.html [ Pass ]
 crbug.com/591099 virtual/video-surface-layer/media/color-profile-video-seek-filter.html [ Pass ]
@@ -576,5 +576,5 @@
 crbug.com/591099 virtual/video-surface-layer/media/video-controls-hide-on-move-outside-controls.html [ Pass ]
 crbug.com/591099 virtual/video-surface-layer/media/video-played-ranges-1.html [ Pass ]
 crbug.com/591099 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCIceTransport-extension.https.html [ Failure Pass ]
-crbug.com/591099 vr/getFrameData_oneframeupdate.html [ Pass ]
+crbug.com/591099 vr/getFrameData_oneframeupdate.html [ Failure Pass ]
 crbug.com/591099 webexposed/global-interface-listing-shared-worker.html [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index b3df8d3..9cd289f 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -6027,7 +6027,6 @@
 
 # Sheriff 2019-03-05
 crbug.com/938200 http/tests/devtools/network/network-blocked-reason.js [ Timeout Pass ]
-crbug.com/938780 [ Mac ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html [ Failure ]
 
 # Sheriff 2019-03-06
 crbug.com/938591 [ Linux ] fast/events/middleClickAutoscroll-nested-divs-forbidden.html [ Failure Pass ]
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 eacba0e..6ccf6bea 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
@@ -127,6 +127,12 @@
      {}
     ]
    ],
+   "clipboard-apis/async-write-blobs-read-blobs-manual.https.html": [
+    [
+     "/clipboard-apis/async-write-blobs-read-blobs-manual.https.html",
+     {}
+    ]
+   ],
    "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [
     [
      "/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html",
@@ -139,6 +145,12 @@
      {}
     ]
    ],
+   "clipboard-apis/async-write-duplicate-mime-type-manual.https.html": [
+    [
+     "/clipboard-apis/async-write-duplicate-mime-type-manual.https.html",
+     {}
+    ]
+   ],
    "clipboard-apis/async-write-image-read-image-manual.https.html": [
     [
      "/clipboard-apis/async-write-image-read-image-manual.https.html",
@@ -187346,11 +187358,6 @@
      {}
     ]
    ],
-   "shape-detection/idlharness.any.worker-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "signed-exchange/META.yml": [
     [
      {}
@@ -197541,11 +197548,6 @@
      {}
     ]
    ],
-   "webrtc/RTCIceCandidate-constructor-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "webrtc/RTCIceTransport-expected.txt": [
     [
      {}
@@ -207626,9 +207628,21 @@
      {}
     ]
    ],
-   "IndexedDB/bindings-inject-key.html": [
+   "IndexedDB/bindings-inject-keys-bypass-setters.html": [
     [
-     "/IndexedDB/bindings-inject-key.html",
+     "/IndexedDB/bindings-inject-keys-bypass-setters.html",
+     {}
+    ]
+   ],
+   "IndexedDB/bindings-inject-values-bypass-chain.html": [
+    [
+     "/IndexedDB/bindings-inject-values-bypass-chain.html",
+     {}
+    ]
+   ],
+   "IndexedDB/bindings-inject-values-bypass-setters.html": [
+    [
+     "/IndexedDB/bindings-inject-values-bypass-setters.html",
      {}
     ]
    ],
@@ -315133,8 +315147,16 @@
    "589eeabe6c6e6798406759e2d40fd28be2645473",
    "testharness"
   ],
-  "IndexedDB/bindings-inject-key.html": [
-   "2fbe95ec8fc41878babd2ce1705787c8c4f4aa5f",
+  "IndexedDB/bindings-inject-keys-bypass-setters.html": [
+   "91d586bde35dcfc89da49068b1a3b63295552bb1",
+   "testharness"
+  ],
+  "IndexedDB/bindings-inject-values-bypass-chain.html": [
+   "02fdb8a64ca1774ee8b3a2db40650141149dc684",
+   "testharness"
+  ],
+  "IndexedDB/bindings-inject-values-bypass-setters.html": [
+   "c16c0a4e010f9805796cd93f9cbd1f141e6c91e5",
    "testharness"
   ],
   "IndexedDB/clone-before-keypath-eval.html": [
@@ -318322,11 +318344,11 @@
    "testharness"
   ],
   "animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html": [
-   "9841c575d1d76f9601f8c229c9c527618083fd21",
+   "6f981854d38877d42b1c7b63afdb9ec989a32d42",
    "reftest"
   ],
   "animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden-ref.html": [
-   "2004e6df905177a6165c66647e271938f6255685",
+   "c6d7314e396e85225f245905f5afa17fb848b469",
    "support"
   ],
   "animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden.https.html": [
@@ -318334,11 +318356,11 @@
    "reftest"
   ],
   "animation-worklet/worklet-animation-with-scroll-timeline-ref.html": [
-   "f30c861fb9a49b5c2691be0aa2f82297be17de41",
+   "fe92232d9afa24f78e9cc7cc3bae341ba2a471bc",
    "support"
   ],
   "animation-worklet/worklet-animation-with-scroll-timeline-root-scroller-ref.html": [
-   "3b527dced72ee63fba3d5538d679b517ed583a26",
+   "5810e1738c1d5927223037e97a7a14a52c405a5e",
    "support"
   ],
   "animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html": [
@@ -319690,23 +319712,31 @@
    "testharness"
   ],
   "clipboard-apis/async-navigator-clipboard-basics.https.html": [
-   "3c1a0af76c2674960a871f82c908b9044240f967",
+   "2d2ebf6c6c2667e1e2e465baa3dd78b657b97a7c",
    "testharness"
   ],
+  "clipboard-apis/async-write-blobs-read-blobs-manual.https.html": [
+   "e616b5ed794bfd38dbd2199685c622e7ee01ec15",
+   "manual"
+  ],
   "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [
-   "ea6e9369517976642cf158d3273a56f321249813",
+   "bc8511efa72c6c7db097f2a35d1b864d92359039",
    "manual"
   ],
   "clipboard-apis/async-write-blobtext-read-text-manual.https.html": [
-   "ecb744a65704a2ff449391f84d6c20e1474a52d5",
+   "b1b85de65e8b3bdef5a462152946617082041d79",
+   "manual"
+  ],
+  "clipboard-apis/async-write-duplicate-mime-type-manual.https.html": [
+   "8e249fc993a810ff1bec41c4ecbccdac8c2982c4",
    "manual"
   ],
   "clipboard-apis/async-write-image-read-image-manual.https.html": [
-   "a8e2956b7e14784d917a2dcf3f5b7e571b81c042",
+   "76d3d872c980447d46da093800dff8e1116b215d",
    "manual"
   ],
   "clipboard-apis/async-write-text-read-blobtext-manual.https.html": [
-   "7e682f1dbdd4f02de5a00addf9be1fbdcc4ca8f0",
+   "b54fa609b655d08083bfddd382cd76bb6447392f",
    "manual"
   ],
   "clipboard-apis/async-write-text-read-text-manual.https.html": [
@@ -461442,17 +461472,13 @@
    "support"
   ],
   "shape-detection/idlharness.any-expected.txt": [
-   "4f812297ec172211a0e46238f26e33bfa8b95d44",
+   "a2c26dcade6fe6ec10970115f2ce39faf5a7afa2",
    "support"
   ],
   "shape-detection/idlharness.any.js": [
    "ea7726891052c54b3afd3e0a7a2399dfb44e7509",
    "testharness"
   ],
-  "shape-detection/idlharness.any.worker-expected.txt": [
-   "6d71cf9dec89b3032cd1729b48ae5f1219e40cb1",
-   "support"
-  ],
   "signed-exchange/META.yml": [
    "f56fbab13ecc0256f23133a1086e8925729121f9",
    "support"
@@ -474873,10 +474899,6 @@
    "4d0726093c19c2828e59e7f61d2f65954c8075fc",
    "testharness"
   ],
-  "webrtc/RTCIceCandidate-constructor-expected.txt": [
-   "e5457312c5a221ec18a8bbf372af533cff270080",
-   "support"
-  ],
   "webrtc/RTCIceCandidate-constructor.html": [
    "344007ded2b4d4496171402896d738817cdde12e",
    "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCIceCandidate-constructor-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCIceCandidate-constructor-expected.txt
deleted file mode 100644
index e545731..0000000
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCIceCandidate-constructor-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a testharness.js-based test.
-PASS new RTCIceCandidate()
-PASS new RTCIceCandidate({})
-PASS new RTCIceCandidate({ ... }) with manually filled default values
-PASS new RTCIceCandidate({ sdpMid: null, sdpMLineIndex: null })
-PASS new RTCIceCandidate({ candidate: '' })
-PASS new RTCIceCandidate({ candidate: null })
-PASS new RTCIceCandidate({ ... }) with valid candidate string only
-FAIL new RTCIceCandidate({ sdpMid: 'audio' }) assert_equals: sdpMLineIndex expected (object) null but got (number) 0
-PASS new RTCIceCandidate({ sdpMLineIndex: 0 })
-PASS new RTCIceCandidate({ sdpMid: 'audio', sdpMLineIndex: 0 })
-FAIL new RTCIceCandidate({ candidate: '', sdpMid: 'audio' } assert_equals: sdpMLineIndex expected (object) null but got (number) 0
-PASS new RTCIceCandidate({ candidate: '', sdpMLineIndex: 0 }
-FAIL new RTCIceCandidate({ ... }) with valid candidate string and sdpMid assert_equals: sdpMLineIndex expected (object) null but got (number) 0
-FAIL new RTCIceCandidate({ ... }) with invalid candidate string and sdpMid assert_equals: sdpMLineIndex expected (object) null but got (number) 0
-PASS new RTCIceCandidate({ ... }) with nondefault values for all fields
-PASS new RTCIceCandidate({ ... }) with nondefault values for all fields, tcp candidate
-FAIL new RTCIceCandidate({ ... }) with invalid sdpMid assert_equals: sdpMLineIndex expected (object) null but got (number) 0
-PASS new RTCIceCandidate({ ... }) with invalid sdpMLineIndex
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/http/tests/devtools/profiler/live-line-level-heap-profile-expected.txt b/third_party/blink/web_tests/http/tests/devtools/profiler/live-line-level-heap-profile-expected.txt
deleted file mode 100644
index 392a6c2..0000000
--- a/third_party/blink/web_tests/http/tests/devtools/profiler/live-line-level-heap-profile-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Tests that the live line-level heap profile is shown in the text editor.
-
-allocator.js
-Memory annotation added to line 12.
-
diff --git a/third_party/blink/web_tests/http/tests/devtools/profiler/live-line-level-heap-profile.js b/third_party/blink/web_tests/http/tests/devtools/profiler/live-line-level-heap-profile.js
deleted file mode 100644
index 09ed03d7..0000000
--- a/third_party/blink/web_tests/http/tests/devtools/profiler/live-line-level-heap-profile.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(async function() {
-  TestRunner.addResult(`Tests that the live line-level heap profile is shown in the text editor.\n`);
-  await self.runtime.loadModulePromise('perf_ui');
-  await PerfUI.LiveHeapProfile.hasStartedForTest();
-  await TestRunner.loadModule('sources_test_runner');
-  await TestRunner.showPanel('sources');
-
-  await TestRunner.evaluateInPagePromise(`
-      let dump = new Array(10000).fill(42).map(x => Date.now() + '42');
-      //# sourceURL=allocator.js`);
-
-  TestRunner.addSniffer(SourceFrame.SourcesTextEditor.prototype, 'setGutterDecoration', decorationAdded, true);
-  SourcesTestRunner.showScriptSource('allocator.js', frameRevealed);
-
-  function decorationAdded(line, type, element) {
-    if (line !== 12 || type !== 'CodeMirror-gutter-memory' || !element.textContent || !element.style.backgroundColor)
-      return;
-    TestRunner.addResult(`Memory annotation added to line ${line}.`);
-    TestRunner.completeTest();
-  }
-
-  function frameRevealed(frame) {
-    TestRunner.addResult(TestRunner.formatters.formatAsURL(frame.uiSourceCode().url()));
-  }
-})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-expected.txt
index 842c89dc..bef9e0b 100644
--- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-expected.txt
@@ -1,11 +1,11 @@
 Tests that a line-level CPU profile is shown in the text editor.
 
 .../devtools/tracing/resources/empty.js
-99 CodeMirror-gutter-performance 10.0ms rgba(255, 187, 0, 0.4)
-101 CodeMirror-gutter-performance 1900.0ms rgba(255, 187, 0, 0.855)
-0 CodeMirror-gutter-performance 100.0ms rgba(255, 187, 0, 0.6)
-1 CodeMirror-gutter-performance 200.0ms rgba(255, 187, 0, 0.66)
-2 CodeMirror-gutter-performance 300.0ms rgba(255, 187, 0, 0.694)
-3 CodeMirror-gutter-performance 400.0ms rgba(255, 187, 0, 0.72)
-54 CodeMirror-gutter-performance 220.0ms rgba(255, 187, 0, 0.67)
+99 CodeMirror-gutter-performance 10.0ms rgba(255, 187, 0, 0.263)
+101 CodeMirror-gutter-performance 1900.0ms rgba(255, 187, 0, 0.718)
+0 CodeMirror-gutter-performance 100.0ms rgba(255, 187, 0, 0.463)
+1 CodeMirror-gutter-performance 200.0ms rgba(255, 187, 0, 0.52)
+2 CodeMirror-gutter-performance 300.0ms rgba(255, 187, 0, 0.557)
+3 CodeMirror-gutter-performance 400.0ms rgba(255, 187, 0, 0.58)
+54 CodeMirror-gutter-performance 220.0ms rgba(255, 187, 0, 0.53)
 
diff --git a/third_party/blink/web_tests/media/controls-drag-timebar-rendering.html b/third_party/blink/web_tests/media/controls-drag-timebar-rendering.html
index 9c53639..2c37f38 100644
--- a/third_party/blink/web_tests/media/controls-drag-timebar-rendering.html
+++ b/third_party/blink/web_tests/media/controls-drag-timebar-rendering.html
@@ -17,14 +17,26 @@
             {
                 video.play();
 
-                if (window.eventSender) {
-                    var coords = mediaControlsButtonCoordinates(video, "timeline");
-                    eventSender.mouseMoveTo(coords[0], coords[1]);
-                    eventSender.mouseDown();
-                }
+                // Hover the mouse over the timeline so it doesn't fade out
+                // while we wait for the video to play the first couple frames.
+                var coords = mediaControlsButtonCoordinates(video, "timeline");
+                eventSender.mouseMoveTo(coords[0], coords[1]);
+            });
 
-                if (window.testRunner)
-                    testRunner.notifyDone();
+            var timeupdateCalls = 0;
+            video.addEventListener("timeupdate", function() {
+                timeupdateCalls++;
+
+                // Let the timeupdate event occur at least twice to ensure the
+                // video has rendered a couple frames.
+                if (timeupdateCalls > 1) {
+                    if (window.eventSender) {
+                        eventSender.mouseDown();
+                    }
+
+                    if (window.testRunner)
+                        testRunner.notifyDone();
+                }
             });
         </script>
     </body>
diff --git a/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt b/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
index 9f880cef..4ab9a280 100644
--- a/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
+++ b/third_party/blink/web_tests/paint/invalidation/video-paint-invalidation-expected.txt
@@ -24,7 +24,7 @@
       "drawsContent": false
     },
     {
-      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small test-mode phase-ready state-stopped'",
+      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small test-mode phase-ready state-scrubbing'",
       "position": [8, 8],
       "bounds": [320, 240]
     },
diff --git a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
index e90e866..a2be4ec 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
@@ -76,7 +76,7 @@
       "drawsContent": false
     },
     {
-      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-stopped'",
+      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-scrubbing'",
       "position": [8, 8],
       "bounds": [352, 288]
     },
diff --git a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
index 1737809..fd66c2f 100644
--- a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
@@ -76,7 +76,7 @@
       "drawsContent": false
     },
     {
-      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-stopped'",
+      "name": "LayoutFlexibleBox (relative positioned) DIV class='sizing-small phase-ready state-scrubbing'",
       "position": [8, 8],
       "bounds": [352, 288]
     },
diff --git a/third_party/webrtc_overrides/BUILD.gn b/third_party/webrtc_overrides/BUILD.gn
index 049ef18..c0de0b91 100644
--- a/third_party/webrtc_overrides/BUILD.gn
+++ b/third_party/webrtc_overrides/BUILD.gn
@@ -110,7 +110,7 @@
   configs += [ "//third_party/webrtc:library_impl_config" ]
   deps = [
     ":task_queue_factory",
-    "//third_party/webrtc/api/task_queue:global_task_queue_factory",
+    "//third_party/webrtc/api/task_queue",
   ]
 }
 
@@ -122,6 +122,5 @@
   deps = [
     "//base",
     "//third_party/webrtc/api/task_queue",
-    "//third_party/webrtc/api/task_queue:task_queue_factory",
   ]
 }
diff --git a/third_party/webrtc_overrides/task_queue_impl.cc b/third_party/webrtc_overrides/task_queue_impl.cc
index dbd09da..0d9b158f 100644
--- a/third_party/webrtc_overrides/task_queue_impl.cc
+++ b/third_party/webrtc_overrides/task_queue_impl.cc
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+
+#include "third_party/webrtc/api/task_queue/task_queue_factory.h"
 #include "third_party/webrtc_overrides/task_queue_factory.h"
 
 namespace webrtc {
diff --git a/tools/cygprofile/OWNERS b/tools/cygprofile/OWNERS
index 3301555..d45b803a 100644
--- a/tools/cygprofile/OWNERS
+++ b/tools/cygprofile/OWNERS
@@ -1,2 +1,3 @@
 lizeb@chromium.org
+mattcary@chromium.org
 pasko@chromium.org
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index d990102..1300dfe 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -46827,6 +46827,10 @@
   <int value="97" label="IDC_CONTENT_CONTEXT_START_SMART_SELECTION_ACTION5"/>
   <int value="98" label="IDC_CONTENT_CONTEXT_LOOK_UP"/>
   <int value="99" label="IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE"/>
+  <int value="100"
+      label="IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE_ONCE"/>
+  <int value="101" label="IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS"/>
+  <int value="102" label="IDC_SEND_TO_MY_DEVICES"/>
 </enum>
 
 <enum name="ReopenTabPromoStepAtDismissal">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 522cea84..6690a38 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -480,7 +480,7 @@
 </histogram>
 
 <histogram base="true" name="Accessibility.ScreenReader.Image.MinSize"
-    units="px" expires_after="2019-04-01">
+    units="px" expires_after="M76">
 <!-- Name completed by histogram_suffixes
        name="AccessibilityScreenReaderImage" -->
 
@@ -494,7 +494,7 @@
 </histogram>
 
 <histogram base="true" name="Accessibility.ScreenReader.Image.SizeRatio"
-    units="%" expires_after="2019-04-01">
+    units="%" expires_after="M76">
 <!-- Name completed by histogram_suffixes
        name="AccessibilityScreenReaderImage" -->
 
@@ -53581,6 +53581,35 @@
   </summary>
 </histogram>
 
+<histogram name="Memory.Experimental.WMIRefresher.Init.AddEnumDuration"
+    units="ms" expires_after="2019-09-30">
+  <owner>sebmarchand@chromium.org</owner>
+  <summary>
+    The time it takes for the call to |AddEnum| to complete during the
+    initialization of the WMI Refresher.
+  </summary>
+</histogram>
+
+<histogram
+    name="Memory.Experimental.WMIRefresher.Init.CoCreateInstanceDuration"
+    units="ms" expires_after="2019-09-30">
+  <owner>sebmarchand@chromium.org</owner>
+  <summary>
+    The time it takes for the call to |CoCreateInstance| to complete during the
+    initialization of the WMI Refresher.
+  </summary>
+</histogram>
+
+<histogram
+    name="Memory.Experimental.WMIRefresher.Init.CreateLocalWmiConnectionDuration"
+    units="ms" expires_after="2019-09-30">
+  <owner>sebmarchand@chromium.org</owner>
+  <summary>
+    The time it takes for the call to |CreateLocalWmiConnection| to complete
+    during the initialization of the WMI Refresher.
+  </summary>
+</histogram>
+
 <histogram name="Memory.Experimental.WMIRefresher.InitDiskIdleTimeConfigStatus"
     enum="WMIRefresherInitStatus" expires_after="2019-09-30">
   <owner>sebmarchand@chromium.org</owner>
@@ -53590,6 +53619,15 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Memory.Experimental.WMIRefresher.InitializeDiskIdleTimeConfigDuration"
+    units="ms" expires_after="2019-09-30">
+  <owner>sebmarchand@chromium.org</owner>
+  <summary>
+    The time it takes to initialize the disk idle config in the WMI Refresher.
+  </summary>
+</histogram>
+
 <histogram name="Memory.Experimental.WMIRefresher.RefreshDiskIdleTimeDuration"
     units="ms" expires_after="2019-09-30">
   <owner>sebmarchand@chromium.org</owner>
@@ -84482,6 +84520,25 @@
   </summary>
 </histogram>
 
+<histogram name="PerformanceMonitor.SystemMonitor.DiskIdleTime" units="%"
+    expires_after="2019-07-01">
+  <owner>sebmarchand@chromium.org</owner>
+  <summary>
+    Average percentage of time during which the disk has been idle, logged at
+    regular intervals. If the system has multiple disks then this is the average
+    value for all of them. Windows only.
+  </summary>
+</histogram>
+
+<histogram name="PerformanceMonitor.SystemMonitor.FreePhysMemory" units="MB"
+    expires_after="2019-07-01">
+  <owner>sebmarchand@chromium.org</owner>
+  <summary>
+    The amount of free physical memory available, logged at regular intervals.
+    Windows only.
+  </summary>
+</histogram>
+
 <histogram name="Permissions.Action" enum="PermissionAction">
   <owner>dominickn@chromium.org</owner>
   <owner>engedy@chromium.org</owner>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv
index 827e2b3..8baf74f 100644
--- a/tools/perf/benchmark.csv
+++ b/tools/perf/benchmark.csv
@@ -1,6 +1,7 @@
 AUTOGENERATED FILE DO NOT EDIT
 See https://bit.ly/update-benchmarks-info to make changes
 Benchmark name,Individual owners,Component,Documentation,Tags
+UNSCHEDULED_oortonline_tbmv2,ulan@chromium.org,,,
 angle_perftests,"jmadill@chromium.org, chrome-gpu-perf-owners@chromium.org",Internals>GPU>ANGLE,,
 base_perftests,"skyostil@chromium.org, gab@chromium.org",Internals>SequenceManager,https://chromium.googlesource.com/chromium/src/+/HEAD/base/README.md#performance-testing,
 blink_perf.accessibility,dmazzoni@chromium.org,Blink>Accessibility,https://bit.ly/blink-perf-benchmarks,
@@ -33,7 +34,6 @@
 memory.top_10_mobile,perezju@chromium.org,,,
 net_perftests,xunjieli@chromium.org,,,
 octane,hablich@chromium.org,Blink>JavaScript,,
-oortonline_tbmv2,ulan@chromium.org,,,
 passthrough_command_buffer_perftests,"piman@chromium.org, chrome-gpu-perf-owners@chromium.org",Internals>GPU>ANGLE,,
 performance_browser_tests,miu@chromium.org,Internals>Media>ScreenCapture,,
 power.desktop,brucedawson@chromium.org,,https://bit.ly/power-benchmarks,
diff --git a/tools/perf/benchmarks/benchmark_smoke_unittest.py b/tools/perf/benchmarks/benchmark_smoke_unittest.py
index e266306..2fed657 100644
--- a/tools/perf/benchmarks/benchmark_smoke_unittest.py
+++ b/tools/perf/benchmarks/benchmark_smoke_unittest.py
@@ -19,7 +19,6 @@
 from telemetry import decorators
 from telemetry.testing import options_for_unittests
 from telemetry.testing import progress_reporter
-
 from py_utils import discover
 
 from benchmarks import jetstream
@@ -117,7 +116,7 @@
 _BLACK_LIST_TEST_NAMES = [
    'memory.long_running_idle_gmail_background_tbmv2',
    'tab_switching.typical_25',
-   'oortonline_tbmv2',
+   'UNSCHEDULED_oortonline_tbmv2',
    'webrtc',  # crbug.com/932036
 ]
 
diff --git a/tools/perf/benchmarks/oortonline.py b/tools/perf/benchmarks/oortonline.py
index 1b02456..6992961 100644
--- a/tools/perf/benchmarks/oortonline.py
+++ b/tools/perf/benchmarks/oortonline.py
@@ -58,9 +58,10 @@
         chrome_trace_config.MemoryDumpConfig())
     return options
 
+  # TODO(934227): Remove this benchmark now that it's descheduled.
   @classmethod
   def Name(cls):
-    return 'oortonline_tbmv2'
+    return 'UNSCHEDULED_oortonline_tbmv2'
 
   @classmethod
   def ShouldAddValue(cls, name, _):
diff --git a/tools/perf/cli_tools/soundwave/worker_pool_test.py b/tools/perf/cli_tools/soundwave/worker_pool_test.py
index 3e806fe..a0d703f 100644
--- a/tools/perf/cli_tools/soundwave/worker_pool_test.py
+++ b/tools/perf/cli_tools/soundwave/worker_pool_test.py
@@ -15,6 +15,7 @@
 from cli_tools.soundwave import pandas_sqlite
 from cli_tools.soundwave import worker_pool
 from core.external_modules import pandas
+from telemetry import decorators
 
 
 def TestWorker(args):
@@ -30,6 +31,8 @@
 
 @unittest.skipIf(pandas is None, 'pandas not available')
 class TestWorkerPool(unittest.TestCase):
+
+  @decorators.Disabled('all')  # crbug.com/939777
   def testWorkerPoolRun(self):
     tempdir = tempfile.mkdtemp()
     try:
diff --git a/tools/perf/cli_tools/update_wpr/update_wpr_unittest.py b/tools/perf/cli_tools/update_wpr/update_wpr_unittest.py
index ba64cc5..7951dd6 100644
--- a/tools/perf/cli_tools/update_wpr/update_wpr_unittest.py
+++ b/tools/perf/cli_tools/update_wpr/update_wpr_unittest.py
@@ -20,11 +20,6 @@
   def setUp(self):
     self.maxDiff = None
 
-    # TODO(crbug.com/938487): This pattern of mocking leads to double-mocked
-    # functions (when inside a test case we mock something that has already been
-    # mocked), which cannot be reliably unmocked by calling
-    # mock.patch.stopall(), so then the mock leaks to other test cases run
-    # later and breaks them.
     self._check_log = mock.patch('core.cli_helpers.CheckLog').start()
     self._run = mock.patch('core.cli_helpers.Run').start()
     self._check_output = mock.patch('subprocess.check_output').start()
@@ -58,8 +53,8 @@
   def tearDown(self):
     mock.patch.stopall()
 
-  def testMain(self):
-    wpr_updater_cls = mock.patch(WPR_UPDATER + 'WprUpdater').start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater')
+  def testMain(self, wpr_updater_cls):
     update_wpr.Main([
       '-s', 'foo:bar:story:2019',
       '-d', 'H2345234FC33',
@@ -78,18 +73,20 @@
       mock.call().Cleanup(),
     ])
 
-  def testCleanupManual(self):
-    mock.patch('core.cli_helpers.Ask', return_value=False).start()
-    rmtree = mock.patch('shutil.rmtree').start()
+  @mock.patch('shutil.rmtree')
+  @mock.patch('core.cli_helpers.Ask', return_value=False)
+  def testCleanupManual(self, ask, rmtree):
+    del ask  # Unused.
     self.wpr_updater.Cleanup()
     self._comment.assert_called_once_with(
         'No problem. All logs will remain in /tmp/dir - feel free to remove '
         'that directory when done.')
     rmtree.assert_not_called()
 
-  def testCleanupAutomatic(self):
-    mock.patch('core.cli_helpers.Ask', return_value=True).start()
-    rmtree = mock.patch('shutil.rmtree').start()
+  @mock.patch('shutil.rmtree')
+  @mock.patch('core.cli_helpers.Ask', return_value=True)
+  def testCleanupAutomatic(self, ask, rmtree):
+    del ask  # Unused.
     self.wpr_updater.Cleanup()
     rmtree.assert_called_once_with('/tmp/dir', ignore_errors=True)
 
@@ -114,39 +111,35 @@
   @mock.patch('os.dup2')
   @mock.patch('webbrowser.open')
   def testOpenBrowser(self, webbrowser_open, os_dup2, os_close, os_dup):
-    del os_dup2, os_close, os_dup  # unused
+    del os_dup2, os_close, os_dup  # Unused.
     update_wpr._OpenBrowser('<url>')
     webbrowser_open.assert_called_once_with('<url>')
 
-  def testAutoRun(self):
-    # Mock low-level methods tested above.
-    mock.patch(WPR_UPDATER + '_GetBranchName', return_value='HEAD').start()
-    mock.patch(
-        WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl',
-        return_value='<issue-url>').start()
-    mock.patch(WPR_UPDATER + 'WprUpdater._CreateBranch').start()
-    send_cl_for_review = mock.patch(WPR_UPDATER + '_SendCLForReview').start()
-    open_browser = mock.patch(WPR_UPDATER + '_OpenBrowser').start()
-
-    # Mock high-level methods tested below.
-    live_run = mock.patch(WPR_UPDATER + 'WprUpdater.LiveRun').start()
-    record_wpr = mock.patch(WPR_UPDATER + 'WprUpdater.RecordWpr').start()
-    replay_wpr = mock.patch(WPR_UPDATER + 'WprUpdater.ReplayWpr').start()
-    upload_wpr = mock.patch(
-        WPR_UPDATER + 'WprUpdater.UploadWpr', return_value=True).start()
-    upload_cl = mock.patch(
-        WPR_UPDATER + 'WprUpdater.UploadCL', return_value=0).start()
-    start_pinpoint_jobs = mock.patch(
-        WPR_UPDATER + 'WprUpdater.StartPinpointJobs',
-        return_value=(['<url1>', '<url2>', '<url3>'], [])).start()
-
-    # Mock user interaction.
-    mock.patch('core.cli_helpers.Ask', side_effect=[
-        True,        # Should script create a new branch automatically?
-        'continue',  # Should I continue with recording, ...?
-        'continue',  # Should I record and replay again, ...?
-    ]).start()
-
+  # Mock low-level methods tested above.
+  @mock.patch(WPR_UPDATER + '_GetBranchName', return_value='HEAD')
+  @mock.patch(WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl',
+              return_value='<issue-url>')
+  @mock.patch(WPR_UPDATER + 'WprUpdater._CreateBranch')
+  @mock.patch(WPR_UPDATER + '_SendCLForReview')
+  @mock.patch(WPR_UPDATER + '_OpenBrowser')
+  # Mock high-level methods tested below.
+  @mock.patch(WPR_UPDATER + 'WprUpdater.LiveRun')
+  @mock.patch(WPR_UPDATER + 'WprUpdater.RecordWpr')
+  @mock.patch(WPR_UPDATER + 'WprUpdater.ReplayWpr')
+  @mock.patch(WPR_UPDATER + 'WprUpdater.UploadWpr', return_value=True)
+  @mock.patch(WPR_UPDATER + 'WprUpdater.UploadCL', return_value=0)
+  @mock.patch(WPR_UPDATER + 'WprUpdater.StartPinpointJobs',
+              return_value=(['<url1>', '<url2>', '<url3>'], []))
+  # Mock user interaction.
+  @mock.patch('core.cli_helpers.Ask', side_effect=[
+      True,         # Should script create a new branch automatically?
+      'continue',   # Should I continue with recording, ...?
+      'continue'])  # Should I record and replay again, ...?
+  def testAutoRun(
+      self, ask, start_pinpoint_jobs, upload_cl, upload_wpr, replay_wpr,
+      record_wpr, live_run, open_browser, send_cl_for_review, create_branch,
+      get_branch_issue_url, get_branch_name):
+    del ask, create_branch, get_branch_issue_url, get_branch_name  # Unused.
     self.wpr_updater.AutoRun()
 
     # Run once to make sure story works.
@@ -170,18 +163,16 @@
     # Open the CL in browser,
     open_browser.assert_called_once_with('<issue-url>')
 
-  def testLiveRun(self):
-    run_benchmark = mock.patch(
-        WPR_UPDATER + 'WprUpdater._RunSystemHealthMemoryBenchmark',
-        return_value='<out-file>').start()
-    print_run_info = mock.patch(
-        WPR_UPDATER + 'WprUpdater._PrintRunInfo').start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater._RunSystemHealthMemoryBenchmark',
+              return_value='<out-file>')
+  @mock.patch(WPR_UPDATER + 'WprUpdater._PrintRunInfo')
+  def testLiveRun(self, print_run_info, run_benchmark):
     self.wpr_updater.LiveRun()
     run_benchmark.assert_called_once_with(log_name='live', live=True)
     print_run_info.assert_called_once_with('<out-file>')
 
-  def testRunBenchmark(self):
-    rename = mock.patch('os.rename').start()
+  @mock.patch('os.rename')
+  def testRunBenchmark(self, rename):
     self._check_output.return_value = '  <chrome-log>'
 
     self.wpr_updater._RunSystemHealthMemoryBenchmark('<log_name>', True)
@@ -229,10 +220,9 @@
       mock.call('    [console:error:security]: bar')
     ])
 
-  def testPrintRunInfo(self):
-    print_results = mock.patch(
-        WPR_UPDATER + 'WprUpdater._PrintResultsHTMLInfo',
-        side_effect=[Exception()]).start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater._PrintResultsHTMLInfo',
+              side_effect=[Exception()])
+  def testPrintRunInfo(self, print_results):
     self._check_output.return_value = '0\n'
     self.wpr_updater._PrintRunInfo('<outfile>', True)
     print_results.assert_called_once_with('<outfile>')
@@ -251,7 +241,7 @@
 
   @mock.patch('json.load', return_value={'issue_url': '<url>'})
   def testGetBranchIssueUrl(self, json_load):
-    del json_load  # unused
+    del json_load  # Unused.
     self.assertEqual(self.wpr_updater._GetBranchIssueUrl(), '<url>')
     self._check_output.assert_called_once_with([
       'git', 'cl', 'issue', '--json', '/tmp/dir/git_cl_issue.json'])
@@ -266,18 +256,20 @@
       mock.call('.../data/dir/<archive>.sha1'),
     ])
 
-  def testRecordWprDesktop(self):
-    mock.patch(WPR_UPDATER + 'WprUpdater._PrintRunInfo').start()
-    mock.patch(WPR_UPDATER + 'WprUpdater._DeleteExistingWpr').start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater._PrintRunInfo')
+  @mock.patch(WPR_UPDATER + 'WprUpdater._DeleteExistingWpr')
+  def testRecordWprDesktop(self, delete_existing_wpr, print_run_info):
+    del delete_existing_wpr, print_run_info  # Unused.
     self.wpr_updater.RecordWpr()
     self._check_log.assert_called_once_with([
       '.../record_wpr', '--story-filter=^\\<story\\>$',
       '--browser=system', 'desktop_system_health_story_set'
     ], env={'LC_ALL': 'en_US.UTF-8'}, log_path='/tmp/dir/record_<tstamp>')
 
-  def testRecordWprMobile(self):
-    mock.patch(WPR_UPDATER + 'WprUpdater._PrintRunInfo').start()
-    mock.patch(WPR_UPDATER + 'WprUpdater._DeleteExistingWpr').start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater._PrintRunInfo')
+  @mock.patch(WPR_UPDATER + 'WprUpdater._DeleteExistingWpr')
+  def testRecordWprMobile(self, delete_existing_wpr, print_run_info):
+    del delete_existing_wpr, print_run_info  # Unused.
     self.wpr_updater.device_id = '<serial>'
     self.wpr_updater.RecordWpr()
     self._check_log.assert_called_once_with([
@@ -286,20 +278,18 @@
       'mobile_system_health_story_set'
     ], env={'LC_ALL': 'en_US.UTF-8'}, log_path='/tmp/dir/record_<tstamp>')
 
-  def testReplayWpr(self):
-    print_run_info = mock.patch(
-        WPR_UPDATER + 'WprUpdater._PrintRunInfo').start()
-    run_benchmark = mock.patch(
-        WPR_UPDATER + 'WprUpdater._RunSystemHealthMemoryBenchmark',
-        return_value='<out-file>').start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater._PrintRunInfo')
+  @mock.patch(WPR_UPDATER + 'WprUpdater._RunSystemHealthMemoryBenchmark',
+              return_value='<out-file>')
+  def testReplayWpr(self, run_benchmark, print_run_info):
     self.wpr_updater.ReplayWpr()
     run_benchmark.assert_called_once_with(log_name='replay', live=False)
     print_run_info.assert_called_once_with('<out-file>')
 
-  def testUploadWPR(self):
-    mock.patch(
-        WPR_UPDATER + 'WprUpdater._ExistingWpr',
-        return_value='<archive>').start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater._ExistingWpr',
+              return_value='<archive>')
+  def testUploadWPR(self, existing_wpr):
+    del existing_wpr  # Unused.
     self.wpr_updater.UploadWpr()
     self.assertListEqual(self._run.mock_calls, [
       mock.call(['upload_to_google_storage.py',
@@ -321,13 +311,12 @@
       ], ok_fail=True),
     ])
 
-  def testStartPinPointJobsDesktop(self):
-    mock.patch(
-        WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl',
-        return_value='<issue-url>').start()
-    new_job = mock.patch(
-        'core.services.pinpoint_service.NewJob',
-        return_value={'jobUrl': '<url>'}).start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl',
+              return_value='<issue-url>')
+  @mock.patch('core.services.pinpoint_service.NewJob',
+              return_value={'jobUrl': '<url>'})
+  def testStartPinPointJobsDesktop(self, new_job, get_branch_issue_url):
+    del get_branch_issue_url  # Unused.
     self.assertEqual(
         self.wpr_updater.StartPinpointJobs(),
         (['<url>', '<url>', '<url>'], []))
@@ -343,15 +332,14 @@
         benchmark='system_health.common_desktop')
     self.assertEqual(new_job.call_count, 3)
 
-  def testStartPinPointJobsMobileFail(self):
-    mock.patch(
-        WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl',
-        return_value='<issue-url>').start()
+  @mock.patch(WPR_UPDATER + 'WprUpdater._GetBranchIssueUrl',
+              return_value='<issue-url>')
+  @mock.patch('core.services.pinpoint_service.NewJob',
+              side_effect=request.ServerError(
+                  mock.Mock(), mock.Mock(status=500), ''))
+  def testStartPinPointJobsMobileFail(self, new_job, get_branch_issue_url):
+    del get_branch_issue_url  # Unused.
     self.wpr_updater.device_id = '<serial>'
-    new_job = mock.patch(
-        'core.services.pinpoint_service.NewJob',
-        side_effect=request.ServerError(
-            mock.Mock(), mock.Mock(status=500), '')).start()
     self.assertEqual(
         self.wpr_updater.StartPinpointJobs(['<config>']), ([], ['<config>']))
     new_job.assert_called_once_with(
diff --git a/tools/perf/core/undocumented_benchmarks.py b/tools/perf/core/undocumented_benchmarks.py
index 3bb142b0..9f1ea240 100644
--- a/tools/perf/core/undocumented_benchmarks.py
+++ b/tools/perf/core/undocumented_benchmarks.py
@@ -22,7 +22,7 @@
   'memory.top_10_mobile',
   'net_perftests',
   'octane',
-  'oortonline_tbmv2',
+  'UNSCHEDULED_oortonline_tbmv2',
   'passthrough_command_buffer_perftests',
   'performance_browser_tests',
   'rasterize_and_record_micro.partial_invalidation',
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index eba2829..58ad981 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -256,7 +256,6 @@
 crbug.com/896851 [ Android ] system_health.common_mobile/background:tools:gmail [ Skip ]
 crbug.com/896871 [ Android ] system_health.common_mobile/load:tools:gmail [ Skip ]
 crbug.com/923116 [ Android ] system_health.common_mobile/browse:shopping:avito [ Skip ]
-crbug.com/923517 [ Android_Go ] system_health.common_mobile/browse:social:tumblr_infinite_scroll:2018 [ Skip ]
 crbug.com/923527 [ Android_Webview ] system_health.common_mobile/load:media:soundcloud:2018 [ Skip ]
 
 # Benchmark: system_health.memory_desktop
@@ -318,7 +317,6 @@
 crbug.com/893873 [ Nexus_5X ] system_health.memory_mobile/load:news:washingtonpost [ Skip ]
 crbug.com/896851 [ Android ] system_health.memory_mobile/background:tools:gmail [ Skip ]
 crbug.com/892704 [ Android_Webview ] system_health.memory_mobile/browse:tech:discourse_infinite_scroll:2018 [ Skip ]
-crbug.com/923517 [ Android_Go ] system_health.memory_mobile/browse:social:tumblr_infinite_scroll:2018 [ Skip ]
 crbug.com/923527 [ Android_Webview ] system_health.memory_mobile/load:media:soundcloud:2018 [ Skip ]
 
 # Benchmark: tab_switching.typical_25
@@ -379,7 +377,6 @@
 crbug.com/877648 [ Android_Go ] v8.browsing_mobile/browse:news:cnn [ Skip ]
 crbug.com/901967 [ Nexus6_Webview ] v8.browsing_mobile/browse:news:toi [ Skip ]
 crbug.com/923116 [ Android ] v8.browsing_mobile/browse:shopping:avito [ Skip ]
-crbug.com/923517 [ Android_Go ] v8.browsing_mobile/browse:social:tumblr_infinite_scroll:2018 [ Skip ]
 crbug.com/929839 [ Android_Go ] v8.browsing_mobile/browse:chrome:newtab [ Skip ]
 
 # Benchmark: v8.browsing_mobile-future
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 0fd8739a..17425dba 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -1141,6 +1141,45 @@
                                              end_offset);
 }
 
+int AXPlatformNodeAuraLinux::GetCaretOffset() {
+  if (!HasCaret())
+    return -1;
+
+  int selection_start, selection_end;
+  GetSelectionOffsets(&selection_start, &selection_end);
+  return UTF16ToUnicodeOffsetInText(selection_end);
+}
+
+bool AXPlatformNodeAuraLinux::SetCaretOffset(int offset) {
+  int character_count = atk_text_get_character_count(ATK_TEXT(atk_object_));
+  if (offset < 0 || offset > character_count)
+    offset = character_count;
+
+  offset = UnicodeToUTF16OffsetInText(offset);
+  if (!SetTextSelection(offset, offset))
+    return false;
+
+  OnTextSelectionChanged();
+  return true;
+}
+
+static gint AXPlatformNodeAuraLinuxGetCaretOffset(AtkText* atk_text) {
+  AXPlatformNodeAuraLinux* obj =
+      AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(atk_text));
+  if (!obj)
+    return -1;
+  return obj->GetCaretOffset();
+}
+
+static gboolean AXPlatformNodeAuraLinuxSetCaretOffset(AtkText* atk_text,
+                                                      gint offset) {
+  AXPlatformNodeAuraLinux* obj =
+      AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(atk_text));
+  if (!obj)
+    return FALSE;
+  return obj->SetCaretOffset(offset);
+}
+
 #if ATK_CHECK_VERSION(2, 10, 0)
 static char* AXPlatformNodeAuraLinuxGetStringAtOffset(
     AtkText* atk_text,
@@ -1177,6 +1216,8 @@
   iface->get_text_after_offset = AXPlatformNodeAuraLinuxGetTextAfterOffset;
   iface->get_text_before_offset = AXPlatformNodeAuraLinuxGetTextBeforeOffset;
   iface->get_text_at_offset = AXPlatformNodeAuraLinuxGetTextAtOffset;
+  iface->get_caret_offset = AXPlatformNodeAuraLinuxGetCaretOffset;
+  iface->set_caret_offset = AXPlatformNodeAuraLinuxSetCaretOffset;
 
 #if ATK_CHECK_VERSION(2, 10, 0)
   iface->get_string_at_offset = AXPlatformNodeAuraLinuxGetStringAtOffset;
@@ -2756,6 +2797,13 @@
   return false;
 }
 
+void AXPlatformNodeAuraLinux::OnTextSelectionChanged() {
+  if (HasCaret()) {
+    g_signal_emit_by_name(atk_object_, "text-caret-moved",
+                          atk_text_get_caret_offset(ATK_TEXT(atk_object_)));
+  }
+}
+
 bool AXPlatformNodeAuraLinux::SupportsSelectionWithAtkSelection() {
   return SupportsToggle(GetData().role) ||
          GetData().role == ax::mojom::Role::kListBoxOption;
@@ -2817,6 +2865,9 @@
     case ax::mojom::Event::kSelectedChildrenChanged:
       OnSelectedChildrenChanged();
       break;
+    case ax::mojom::Event::kTextSelectionChanged:
+      OnTextSelectionChanged();
+      break;
     case ax::mojom::Event::kValueChanged:
       OnValueChanged();
       break;
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h
index 63caa6e..5dc6341 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -88,6 +88,7 @@
   void OnMenuPopupEnd();
   void OnSelected();
   void OnSelectedChildrenChanged();
+  void OnTextSelectionChanged();
   void OnValueChanged();
 
   bool SupportsSelectionWithAtkSelection();
@@ -111,9 +112,10 @@
   void SetEmbeddedDocument(AtkObject* new_document);
   void SetEmbeddingWindow(AtkObject* new_embedding_window);
 
- protected:
-  AXHypertext hypertext_;
+  int GetCaretOffset();
+  bool SetCaretOffset(int offset);
 
+ protected:
   // Offsets for the AtkText API are calculated in UTF-16 code point offsets,
   // but the ATK APIs want all offsets to be in "characters," which we
   // understand to be Unicode character offsets. We keep a lazily generated set
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
index 4dae5a9..141be84d 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -1202,6 +1202,52 @@
   g_object_unref(root_obj);
 }
 
+TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkTextCaretMoved) {
+  Init(BuildTextField());
+
+  AtkObject* root_atk_object(GetRootAtkObject());
+  EXPECT_TRUE(ATK_IS_OBJECT(root_atk_object));
+  g_object_ref(root_atk_object);
+
+  ASSERT_TRUE(ATK_IS_TEXT(root_atk_object));
+  AtkText* atk_text = ATK_TEXT(root_atk_object);
+
+  int caret_position_from_event = -1;
+  g_signal_connect(atk_text, "text-caret-moved",
+                   G_CALLBACK(+[](AtkText*, int new_position, gpointer data) {
+                     int* caret_position_from_event = static_cast<int*>(data);
+                     *caret_position_from_event = new_position;
+                   }),
+                   &caret_position_from_event);
+
+  atk_text_set_caret_offset(atk_text, 4);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), 4);
+  ASSERT_EQ(caret_position_from_event, 4);
+
+  caret_position_from_event = -1;
+  int character_count = atk_text_get_character_count(atk_text);
+  atk_text_set_caret_offset(atk_text, -1);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
+  ASSERT_EQ(caret_position_from_event, character_count);
+
+  caret_position_from_event = -1;
+  atk_text_set_caret_offset(atk_text, -1000);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
+  ASSERT_EQ(caret_position_from_event, character_count);
+
+  caret_position_from_event = -1;
+  atk_text_set_caret_offset(atk_text, 1000);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count);
+  ASSERT_EQ(caret_position_from_event, character_count);
+
+  caret_position_from_event = -1;
+  atk_text_set_caret_offset(atk_text, character_count - 1);
+  ASSERT_EQ(atk_text_get_caret_offset(atk_text), character_count - 1);
+  ASSERT_EQ(caret_position_from_event, character_count - 1);
+
+  g_object_unref(root_atk_object);
+}
+
 class ActivationTester {
  public:
   explicit ActivationTester(AtkObject* target) : target_(target) {
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc
index 335dec19f..12225ee6 100644
--- a/ui/accessibility/platform/ax_platform_node_base.cc
+++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -1084,6 +1084,260 @@
   return result;
 }
 
+AXPlatformNodeBase* AXPlatformNodeBase::GetHyperlinkFromHypertextOffset(
+    int offset) {
+  std::map<int32_t, int32_t>::iterator iterator =
+      hypertext_.hyperlink_offset_to_index.find(offset);
+  if (iterator == hypertext_.hyperlink_offset_to_index.end())
+    return nullptr;
+
+  int32_t index = iterator->second;
+  DCHECK_GE(index, 0);
+  DCHECK_LT(index, static_cast<int32_t>(hypertext_.hyperlinks.size()));
+  int32_t id = hypertext_.hyperlinks[index];
+  auto* hyperlink = static_cast<AXPlatformNodeBase*>(GetFromUniqueId(id));
+  if (!hyperlink)
+    return nullptr;
+  return hyperlink;
+}
+
+bool AXPlatformNodeBase::IsEmbeddedByParentObjectHypertext() {
+  int32_t hyperlink_index = -1;
+  AXPlatformNodeBase* parent =
+      static_cast<AXPlatformNodeBase*>(FromNativeViewAccessible(GetParent()));
+  if (parent) {
+    hyperlink_index = parent->GetHyperlinkIndexFromChild(this);
+  }
+
+  if (hyperlink_index >= 0)
+    return true;
+  return false;
+}
+
+int32_t AXPlatformNodeBase::GetHyperlinkIndexFromChild(
+    AXPlatformNodeBase* child) {
+  if (hypertext_.hyperlinks.empty())
+    return -1;
+
+  auto iterator = std::find(hypertext_.hyperlinks.begin(),
+                            hypertext_.hyperlinks.end(), child->GetUniqueId());
+  if (iterator == hypertext_.hyperlinks.end())
+    return -1;
+
+  return static_cast<int32_t>(iterator - hypertext_.hyperlinks.begin());
+}
+
+int32_t AXPlatformNodeBase::GetHypertextOffsetFromHyperlinkIndex(
+    int32_t hyperlink_index) {
+  for (auto& offset_index : hypertext_.hyperlink_offset_to_index) {
+    if (offset_index.second == hyperlink_index)
+      return offset_index.first;
+  }
+  return -1;
+}
+
+int32_t AXPlatformNodeBase::GetHypertextOffsetFromChild(
+    AXPlatformNodeBase* child) {
+  // TODO(dougt) DCHECK(child.owner()->PlatformGetParent() == owner());
+
+  // Handle the case when we are dealing with a text-only child.
+  // Note that this object might be a platform leaf, e.g. an ARIA searchbox.
+  // Also, text-only children should not be present at tree roots and so no
+  // cross-tree traversal is necessary.
+  if (child->IsTextOnlyObject()) {
+    int32_t hypertext_offset = 0;
+    int32_t index_in_parent = child->GetDelegate()->GetIndexInParent();
+    DCHECK_GE(index_in_parent, 0);
+    DCHECK_LT(index_in_parent,
+              static_cast<int32_t>(GetDelegate()->GetChildCount()));
+    for (uint32_t i = 0; i < static_cast<uint32_t>(index_in_parent); ++i) {
+      auto* sibling = static_cast<AXPlatformNodeBase*>(
+          FromNativeViewAccessible(GetDelegate()->ChildAtIndex(i)));
+      DCHECK(sibling);
+      if (sibling->IsTextOnlyObject()) {
+        hypertext_offset += (int32_t)sibling->GetText().size();
+      } else {
+        ++hypertext_offset;
+      }
+    }
+    return hypertext_offset;
+  }
+
+  int32_t hyperlink_index = GetHyperlinkIndexFromChild(child);
+  if (hyperlink_index < 0)
+    return -1;
+
+  return GetHypertextOffsetFromHyperlinkIndex(hyperlink_index);
+}
+
+int32_t AXPlatformNodeBase::GetHypertextOffsetFromDescendant(
+    AXPlatformNodeBase* descendant) {
+  auto* parent_object = static_cast<AXPlatformNodeBase*>(
+      FromNativeViewAccessible(descendant->GetDelegate()->GetParent()));
+  while (parent_object && parent_object != this) {
+    descendant = parent_object;
+    parent_object = static_cast<AXPlatformNodeBase*>(
+        FromNativeViewAccessible(descendant->GetParent()));
+  }
+  if (!parent_object)
+    return -1;
+
+  return parent_object->GetHypertextOffsetFromChild(descendant);
+}
+
+int AXPlatformNodeBase::GetHypertextOffsetFromEndpoint(
+    AXPlatformNodeBase* endpoint_object,
+    int endpoint_offset) {
+  // There are three cases:
+  // 1. Either the selection endpoint is inside this object or is an ancestor
+  // of of this object. endpoint_offset should be returned.
+  // 2. The selection endpoint is a pure descendant of this object. The offset
+  // of the character corresponding to the subtree in which the endpoint is
+  // located should be returned.
+  // 3. The selection endpoint is in a completely different part of the tree.
+  // Either 0 or text_length should be returned depending on the direction
+  // that one needs to travel to find the endpoint.
+
+  // Case 1.
+  //
+  // IsDescendantOf includes the case when endpoint_object == this.
+  if (IsDescendantOf(endpoint_object))
+    return endpoint_offset;
+
+  AXPlatformNodeBase* common_parent = this;
+  int32_t index_in_common_parent = GetDelegate()->GetIndexInParent();
+  while (common_parent && !endpoint_object->IsDescendantOf(common_parent)) {
+    index_in_common_parent = common_parent->GetDelegate()->GetIndexInParent();
+    common_parent = static_cast<AXPlatformNodeBase*>(
+        FromNativeViewAccessible(common_parent->GetParent()));
+  }
+  if (!common_parent)
+    return -1;
+
+  DCHECK_GE(index_in_common_parent, 0);
+  DCHECK(!(common_parent->IsTextOnlyObject()));
+
+  // Case 2.
+  //
+  // We already checked in case 1 if our endpoint is inside this object.
+  // We can safely assume that it is a descendant or in a completely different
+  // part of the tree.
+  if (common_parent == this) {
+    int32_t hypertext_offset =
+        GetHypertextOffsetFromDescendant(endpoint_object);
+    auto* parent = static_cast<AXPlatformNodeBase*>(
+        FromNativeViewAccessible(endpoint_object->GetParent()));
+    if (parent == this && endpoint_object->IsTextOnlyObject()) {
+      hypertext_offset += endpoint_offset;
+    }
+
+    return hypertext_offset;
+  }
+
+  // Case 3.
+  //
+  // We can safely assume that the endpoint is in another part of the tree or
+  // at common parent, and that this object is a descendant of common parent.
+  int32_t endpoint_index_in_common_parent = -1;
+  for (int i = 0; i < common_parent->GetDelegate()->GetChildCount(); ++i) {
+    auto* child =
+        FromNativeViewAccessible(common_parent->GetDelegate()->ChildAtIndex(i));
+    DCHECK(child);
+    if (endpoint_object->IsDescendantOf(child)) {
+      endpoint_index_in_common_parent =
+          child->GetDelegate()->GetIndexInParent();
+      break;
+    }
+  }
+  DCHECK_GE(endpoint_index_in_common_parent, 0);
+
+  if (endpoint_index_in_common_parent < index_in_common_parent)
+    return 0;
+  if (endpoint_index_in_common_parent > index_in_common_parent)
+    return (int32_t)GetText().size();
+
+  NOTREACHED();
+  return -1;
+}
+
+int AXPlatformNodeBase::GetSelectionAnchor() {
+  int32_t anchor_id = GetDelegate()->GetTreeData().sel_anchor_object_id;
+  AXPlatformNodeBase* anchor_object =
+      static_cast<AXPlatformNodeBase*>(GetDelegate()->GetFromNodeID(anchor_id));
+  if (!anchor_object)
+    return -1;
+
+  int anchor_offset = int{GetDelegate()->GetTreeData().sel_anchor_offset};
+  return GetHypertextOffsetFromEndpoint(anchor_object, anchor_offset);
+}
+
+int AXPlatformNodeBase::GetSelectionFocus() {
+  int32_t focus_id = GetDelegate()->GetTreeData().sel_focus_object_id;
+  AXPlatformNodeBase* focus_object =
+      static_cast<AXPlatformNodeBase*>(GetDelegate()->GetFromNodeID(focus_id));
+  if (!focus_object)
+    return -1;
+
+  int focus_offset = int{GetDelegate()->GetTreeData().sel_focus_offset};
+  return GetHypertextOffsetFromEndpoint(focus_object, focus_offset);
+}
+
+void AXPlatformNodeBase::GetSelectionOffsets(int* selection_start,
+                                             int* selection_end) {
+  DCHECK(selection_start && selection_end);
+
+  if (IsPlainTextField() &&
+      GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
+                      selection_start) &&
+      GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, selection_end)) {
+    return;
+  }
+
+  *selection_start = GetSelectionAnchor();
+  *selection_end = GetSelectionFocus();
+  if (*selection_start < 0 || *selection_end < 0)
+    return;
+
+  // There are three cases when a selection would start and end on the same
+  // character:
+  // 1. Anchor and focus are both in a subtree that is to the right of this
+  // object.
+  // 2. Anchor and focus are both in a subtree that is to the left of this
+  // object.
+  // 3. Anchor and focus are in a subtree represented by a single embedded
+  // object character.
+  // Only case 3 refers to a valid selection because cases 1 and 2 fall
+  // outside this object in their entirety.
+  // Selections that span more than one character are by definition inside
+  // this object, so checking them is not necessary.
+  if (*selection_start == *selection_end && !HasCaret()) {
+    *selection_start = -1;
+    *selection_end = -1;
+    return;
+  }
+
+  // The IA2 Spec says that if the largest of the two offsets falls on an
+  // embedded object character and if there is a selection in that embedded
+  // object, it should be incremented by one so that it points after the
+  // embedded object character.
+  // This is a signal to AT software that the embedded object is also part of
+  // the selection.
+  int* largest_offset =
+      (*selection_start <= *selection_end) ? selection_end : selection_start;
+  AXPlatformNodeBase* hyperlink =
+      GetHyperlinkFromHypertextOffset(*largest_offset);
+  if (!hyperlink)
+    return;
+
+  int hyperlink_selection_start, hyperlink_selection_end;
+  hyperlink->GetSelectionOffsets(&hyperlink_selection_start,
+                                 &hyperlink_selection_end);
+  if (hyperlink_selection_start >= 0 && hyperlink_selection_end >= 0 &&
+      hyperlink_selection_start != hyperlink_selection_end) {
+    ++(*largest_offset);
+  }
+}
+
 void AXPlatformNodeBase::AddAttributeToList(const char* name,
                                             const char* value,
                                             PlatformAttributeList* attributes) {
diff --git a/ui/accessibility/platform/ax_platform_node_base.h b/ui/accessibility/platform/ax_platform_node_base.h
index d7fd18f..69164dc6 100644
--- a/ui/accessibility/platform/ax_platform_node_base.h
+++ b/ui/accessibility/platform/ax_platform_node_base.h
@@ -306,6 +306,58 @@
   // embedded element character.
   AXHypertext ComputeHypertext();
 
+  // These protected methods are still used by BrowserAccessibilityComWin. At
+  // some point post conversion, we can probably move these to be private
+  // methods.
+  //
+  //
+  // Selection helper functions.
+  // The following functions retrieve the endpoints of the current selection.
+  // First they check for a local selection found on the current control, e.g.
+  // when querying the selection on a textarea.
+  // If not found they retrieve the global selection found on the current frame.
+  int GetSelectionAnchor();
+  int GetSelectionFocus();
+
+  // Retrieves the selection offsets in the way required by the IA2 APIs.
+  // selection_start and selection_end are -1 when there is no selection active
+  // on this object.
+  // The greatest of the two offsets is one past the last character of the
+  // selection.)
+  void GetSelectionOffsets(int* selection_start, int* selection_end);
+
+  //
+  // Helper methods for IA2 and ATK hyperlinks.
+  //
+  // Embedded objects are those objects which are embedded within other
+  // objects, such as a numbered list within a contenteditable div. Also, in
+  // IA2 and ATK, text that includes embedded objects is called hypertext.
+  // Returns true if the current object is an IA2 or ATK hyperlink.
+  bool IsEmbeddedByParentObjectHypertext();
+
+  // Returns the hyperlink at the given text position, or nullptr if no
+  // hyperlink can be found.
+  AXPlatformNodeBase* GetHyperlinkFromHypertextOffset(int offset);
+
+  // Functions for retrieving offsets for hyperlinks and hypertext.
+  // Return -1 in case of failure.
+  int32_t GetHyperlinkIndexFromChild(AXPlatformNodeBase* child);
+  int32_t GetHypertextOffsetFromHyperlinkIndex(int32_t hyperlink_index);
+  int32_t GetHypertextOffsetFromChild(AXPlatformNodeBase* child);
+  int32_t GetHypertextOffsetFromDescendant(AXPlatformNodeBase* descendant);
+
+  // If the selection endpoint is either equal to or an ancestor of this object,
+  // returns endpoint_offset.
+  // If the selection endpoint is a descendant of this object, returns its
+  // offset. Otherwise, returns either 0 or the length of the hypertext
+  // depending on the direction of the selection.
+  // Returns -1 in case of unexpected failure, e.g. the selection endpoint
+  // cannot be found in the accessibility tree.
+  int GetHypertextOffsetFromEndpoint(AXPlatformNodeBase* endpoint_object,
+                                     int endpoint_offset);
+
+  AXHypertext hypertext_;
+
   int32_t GetPosInSet() const;
   int32_t GetSetSize() const;
 
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 763b3bd2..184b701 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -6354,183 +6354,6 @@
   return parent->IsAncestorComboBox();
 }
 
-bool AXPlatformNodeWin::IsHyperlink() {
-  int32_t hyperlink_index = -1;
-  AXPlatformNodeWin* parent =
-      static_cast<AXPlatformNodeWin*>(FromNativeViewAccessible(GetParent()));
-  if (parent) {
-    hyperlink_index = parent->GetHyperlinkIndexFromChild(this);
-  }
-
-  if (hyperlink_index >= 0)
-    return true;
-  return false;
-}
-
-AXPlatformNodeWin* AXPlatformNodeWin::GetHyperlinkFromHypertextOffset(
-    int offset) {
-  std::map<int32_t, int32_t>::iterator iterator =
-      hypertext_.hyperlink_offset_to_index.find(offset);
-  if (iterator == hypertext_.hyperlink_offset_to_index.end())
-    return nullptr;
-
-  int32_t index = iterator->second;
-  DCHECK_GE(index, 0);
-  DCHECK_LT(index, static_cast<int32_t>(hypertext_.hyperlinks.size()));
-  int32_t id = hypertext_.hyperlinks[index];
-  auto* hyperlink =
-      static_cast<AXPlatformNodeWin*>(AXPlatformNodeWin::GetFromUniqueId(id));
-  if (!hyperlink)
-    return nullptr;
-  return hyperlink;
-}
-
-int32_t AXPlatformNodeWin::GetHyperlinkIndexFromChild(
-    AXPlatformNodeWin* child) {
-  if (hypertext_.hyperlinks.empty())
-    return -1;
-
-  auto iterator = std::find(hypertext_.hyperlinks.begin(),
-                            hypertext_.hyperlinks.end(), child->GetUniqueId());
-  if (iterator == hypertext_.hyperlinks.end())
-    return -1;
-
-  return static_cast<int32_t>(iterator - hypertext_.hyperlinks.begin());
-}
-
-int32_t AXPlatformNodeWin::GetHypertextOffsetFromHyperlinkIndex(
-    int32_t hyperlink_index) {
-  for (auto& offset_index : hypertext_.hyperlink_offset_to_index) {
-    if (offset_index.second == hyperlink_index)
-      return offset_index.first;
-  }
-  return -1;
-}
-
-int32_t AXPlatformNodeWin::GetHypertextOffsetFromChild(
-    AXPlatformNodeWin* child) {
-  // TODO(dougt) DCHECK(child.owner()->PlatformGetParent() == owner());
-
-  // Handle the case when we are dealing with a text-only child.
-  // Note that this object might be a platform leaf, e.g. an ARIA searchbox.
-  // Also, text-only children should not be present at tree roots and so no
-  // cross-tree traversal is necessary.
-  if (child->IsTextOnlyObject()) {
-    int32_t hypertext_offset = 0;
-    int32_t index_in_parent = child->GetDelegate()->GetIndexInParent();
-    DCHECK_GE(index_in_parent, 0);
-    DCHECK_LT(index_in_parent,
-              static_cast<int32_t>(GetDelegate()->GetChildCount()));
-    for (uint32_t i = 0; i < static_cast<uint32_t>(index_in_parent); ++i) {
-      auto* sibling = static_cast<AXPlatformNodeWin*>(
-          FromNativeViewAccessible(GetDelegate()->ChildAtIndex(i)));
-      DCHECK(sibling);
-      if (sibling->IsTextOnlyObject()) {
-        hypertext_offset += (int32_t)sibling->GetText().size();
-      } else {
-        ++hypertext_offset;
-      }
-    }
-    return hypertext_offset;
-  }
-
-  int32_t hyperlink_index = GetHyperlinkIndexFromChild(child);
-  if (hyperlink_index < 0)
-    return -1;
-
-  return GetHypertextOffsetFromHyperlinkIndex(hyperlink_index);
-}
-
-int32_t AXPlatformNodeWin::GetHypertextOffsetFromDescendant(
-    AXPlatformNodeWin* descendant) {
-  auto* parent_object = static_cast<AXPlatformNodeWin*>(
-      FromNativeViewAccessible(descendant->GetDelegate()->GetParent()));
-  while (parent_object && parent_object != this) {
-    descendant = parent_object;
-    parent_object = static_cast<AXPlatformNodeWin*>(
-        FromNativeViewAccessible(descendant->GetParent()));
-  }
-  if (!parent_object)
-    return -1;
-
-  return parent_object->GetHypertextOffsetFromChild(descendant);
-}
-
-int AXPlatformNodeWin::GetHypertextOffsetFromEndpoint(
-    AXPlatformNodeWin* endpoint_object,
-    int endpoint_offset) {
-  // There are three cases:
-  // 1. Either the selection endpoint is inside this object or is an ancestor
-  // of of this object. endpoint_offset should be returned.
-  // 2. The selection endpoint is a pure descendant of this object. The offset
-  // of the character corresponding to the subtree in which the endpoint is
-  // located should be returned.
-  // 3. The selection endpoint is in a completely different part of the tree.
-  // Either 0 or text_length should be returned depending on the direction
-  // that one needs to travel to find the endpoint.
-
-  // Case 1.
-  //
-  // IsDescendantOf includes the case when endpoint_object == this.
-  if (IsDescendantOf(endpoint_object))
-    return endpoint_offset;
-
-  AXPlatformNodeWin* common_parent = this;
-  int32_t index_in_common_parent = GetDelegate()->GetIndexInParent();
-  while (common_parent && !endpoint_object->IsDescendantOf(common_parent)) {
-    index_in_common_parent = common_parent->GetDelegate()->GetIndexInParent();
-    common_parent = static_cast<AXPlatformNodeWin*>(
-        FromNativeViewAccessible(common_parent->GetParent()));
-  }
-  if (!common_parent)
-    return -1;
-
-  DCHECK_GE(index_in_common_parent, 0);
-  DCHECK(!(common_parent->IsTextOnlyObject()));
-
-  // Case 2.
-  //
-  // We already checked in case 1 if our endpoint is inside this object.
-  // We can safely assume that it is a descendant or in a completely different
-  // part of the tree.
-  if (common_parent == this) {
-    int32_t hypertext_offset =
-        GetHypertextOffsetFromDescendant(endpoint_object);
-    auto* parent = static_cast<AXPlatformNodeWin*>(
-        FromNativeViewAccessible(endpoint_object->GetParent()));
-    if (parent == this && endpoint_object->IsTextOnlyObject()) {
-      hypertext_offset += endpoint_offset;
-    }
-
-    return hypertext_offset;
-  }
-
-  // Case 3.
-  //
-  // We can safely assume that the endpoint is in another part of the tree or
-  // at common parent, and that this object is a descendant of common parent.
-  int32_t endpoint_index_in_common_parent = -1;
-  for (int i = 0; i < common_parent->GetDelegate()->GetChildCount(); ++i) {
-    auto* child = static_cast<AXPlatformNodeWin*>(
-        common_parent->GetDelegate()->ChildAtIndex(i));
-    DCHECK(child);
-    if (endpoint_object->IsDescendantOf(child)) {
-      endpoint_index_in_common_parent =
-          child->GetDelegate()->GetIndexInParent();
-      break;
-    }
-  }
-  DCHECK_GE(endpoint_index_in_common_parent, 0);
-
-  if (endpoint_index_in_common_parent < index_in_common_parent)
-    return 0;
-  if (endpoint_index_in_common_parent > index_in_common_parent)
-    return (int32_t)GetText().size();
-
-  NOTREACHED();
-  return -1;
-}
-
 bool AXPlatformNodeWin::IsSameHypertextCharacter(size_t old_char_index,
                                                  size_t new_char_index) {
   if (old_char_index >= old_hypertext_.hypertext.size() ||
@@ -6645,80 +6468,4 @@
   *new_len = new_text.size() - common_prefix - common_suffix;
 }
 
-int AXPlatformNodeWin::GetSelectionAnchor() {
-  int32_t anchor_id = GetDelegate()->GetTreeData().sel_anchor_object_id;
-  AXPlatformNodeWin* anchor_object =
-      static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(anchor_id));
-  if (!anchor_object)
-    return -1;
-
-  int anchor_offset = int{GetDelegate()->GetTreeData().sel_anchor_offset};
-  return GetHypertextOffsetFromEndpoint(anchor_object, anchor_offset);
-}
-
-int AXPlatformNodeWin::GetSelectionFocus() {
-  int32_t focus_id = GetDelegate()->GetTreeData().sel_focus_object_id;
-  AXPlatformNodeWin* focus_object =
-      static_cast<AXPlatformNodeWin*>(GetDelegate()->GetFromNodeID(focus_id));
-  if (!focus_object)
-    return -1;
-
-  int focus_offset = int{GetDelegate()->GetTreeData().sel_focus_offset};
-  return GetHypertextOffsetFromEndpoint(focus_object, focus_offset);
-}
-
-void AXPlatformNodeWin::GetSelectionOffsets(int* selection_start,
-                                            int* selection_end) {
-  DCHECK(selection_start && selection_end);
-
-  if (IsPlainTextField() &&
-      GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
-                      selection_start) &&
-      GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, selection_end)) {
-    return;
-  }
-
-  *selection_start = GetSelectionAnchor();
-  *selection_end = GetSelectionFocus();
-  if (*selection_start < 0 || *selection_end < 0)
-    return;
-
-  // There are three cases when a selection would start and end on the same
-  // character:
-  // 1. Anchor and focus are both in a subtree that is to the right of this
-  // object.
-  // 2. Anchor and focus are both in a subtree that is to the left of this
-  // object.
-  // 3. Anchor and focus are in a subtree represented by a single embedded
-  // object character.
-  // Only case 3 refers to a valid selection because cases 1 and 2 fall
-  // outside this object in their entirety.
-  // Selections that span more than one character are by definition inside
-  // this object, so checking them is not necessary.
-  if (*selection_start == *selection_end && !HasCaret()) {
-    *selection_start = -1;
-    *selection_end = -1;
-    return;
-  }
-
-  // The IA2 Spec says that if the largest of the two offsets falls on an
-  // embedded object character and if there is a selection in that embedded
-  // object, it should be incremented by one so that it points after the
-  // embedded object character.
-  // This is a signal to AT software that the embedded object is also part of
-  // the selection.
-  int* largest_offset =
-      (*selection_start <= *selection_end) ? selection_end : selection_start;
-  AXPlatformNodeWin* hyperlink =
-      GetHyperlinkFromHypertextOffset(*largest_offset);
-  if (!hyperlink)
-    return;
-
-  LONG n_selections = 0;
-  HRESULT hr = hyperlink->get_nSelections(&n_selections);
-  DCHECK(SUCCEEDED(hr));
-  if (n_selections > 0)
-    ++(*largest_offset);
-}
-
 }  // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index b2076fd..90d874e 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -929,57 +929,7 @@
   std::vector<Microsoft::WRL::ComPtr<AXPlatformRelationWin>> relations_;
 
   AXHypertext old_hypertext_;
-  AXHypertext hypertext_;
 
-  // These protected methods are still used by BrowserAccessibilityComWin. At
-  // some point post conversion, we can probably move these to be private
-  // methods.
-  //
-  //
-  // Selection helper functions.
-  // The following functions retrieve the endpoints of the current selection.
-  // First they check for a local selection found on the current control, e.g.
-  // when querying the selection on a textarea.
-  // If not found they retrieve the global selection found on the current frame.
-  int GetSelectionAnchor();
-  int GetSelectionFocus();
-
-  // Retrieves the selection offsets in the way required by the IA2 APIs.
-  // selection_start and selection_end are -1 when there is no selection active
-  // on this object.
-  // The greatest of the two offsets is one past the last character of the
-  // selection.)
-  void GetSelectionOffsets(int* selection_start, int* selection_end);
-
-  //
-  // Helper methods for IA2 hyperlinks.
-  //
-  // Hyperlink is an IA2 misnomer. It refers to objects embedded within other
-  // objects, such as a numbered list within a contenteditable div.
-  // Also, in IA2, text that includes embedded objects is called hypertext.
-  // Returns true if the current object is an IA2 hyperlink.
-  bool IsHyperlink();
-
-  // Returns the hyperlink at the given text position, or nullptr if no
-  // hyperlink can be found.
-  AXPlatformNodeWin* GetHyperlinkFromHypertextOffset(int offset);
-
-  // Functions for retrieving offsets for hyperlinks and hypertext.
-  // Return -1 in case of failure.
-  int32_t GetHyperlinkIndexFromChild(AXPlatformNodeWin* child);
-  int32_t GetHypertextOffsetFromHyperlinkIndex(int32_t hyperlink_index);
-  int32_t GetHypertextOffsetFromChild(AXPlatformNodeWin* child);
-  int32_t GetHypertextOffsetFromDescendant(AXPlatformNodeWin* descendant);
-
-  // If the selection endpoint is either equal to or an ancestor of this object,
-  // returns endpoint_offset.
-  // If the selection endpoint is a descendant of this object, returns its
-  // offset. Otherwise, returns either 0 or the length of the hypertext
-  // depending on the direction of the selection.
-  // Returns -1 in case of unexpected failure, e.g. the selection endpoint
-  // cannot be found in the accessibility tree.
-  int GetHypertextOffsetFromEndpoint(AXPlatformNodeWin* endpoint_object,
-                                     int endpoint_offset);
   bool IsSameHypertextCharacter(size_t old_char_index, size_t new_char_index);
   void ComputeHypertextRemovedAndInserted(size_t* start,
                                           size_t* old_len,
diff --git a/ui/android/java/src/org/chromium/ui/base/Clipboard.java b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
index e3d2b767..55c2209f 100644
--- a/ui/android/java/src/org/chromium/ui/base/Clipboard.java
+++ b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
@@ -5,10 +5,12 @@
 package org.chromium.ui.base;
 
 import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.ClipboardManager;
 import android.content.Context;
+import android.os.Build;
 import android.text.Html;
 import android.text.Spanned;
 import android.text.style.CharacterStyle;
@@ -16,6 +18,7 @@
 import android.text.style.UpdateAppearance;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.BuildInfo;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
@@ -37,6 +40,8 @@
 
     private final ClipboardManager mClipboardManager;
 
+    private long mNativeClipboard;
+
     /**
      * Get the singleton Clipboard instance (creating it if needed).
      */
@@ -177,6 +182,11 @@
         }
     }
 
+    @CalledByNative
+    private void setNativePtr(long nativeClipboard) {
+        mNativeClipboard = nativeClipboard;
+    }
+
     /**
      * Tells the C++ Clipboard that the clipboard has changed.
      *
@@ -185,8 +195,7 @@
     @Override
     public void onPrimaryClipChanged() {
         RecordUserAction.record("MobileClipboardChanged");
-        long nativeClipboardAndroid = nativeInit();
-        if (nativeClipboardAndroid != 0) nativeOnPrimaryClipChanged(nativeClipboardAndroid);
+        if (mNativeClipboard != 0) nativeOnPrimaryClipChanged(mNativeClipboard);
     }
 
     /**
@@ -199,6 +208,23 @@
         Toast.makeText(mContext, R.string.url_copied, Toast.LENGTH_SHORT).show();
     }
 
-    private native long nativeInit();
+    /**
+     * Because Android may not notify apps in the background that the content of clipboard has
+     * changed, this method proactively considers clipboard invalidated, when the app loses focus.
+     * @param hasFocus Whether or not {@code activity} gained or lost focus.
+     */
+    public void onWindowFocusChanged(boolean hasFocus) {
+        if (mNativeClipboard == 0 || !hasFocus || !BuildInfo.isAtLeastQ()) return;
+        onPrimaryClipTimestampInvalidated();
+    }
+
+    @TargetApi(Build.VERSION_CODES.O)
+    private void onPrimaryClipTimestampInvalidated() {
+        long timestamp = mClipboardManager.getPrimaryClipDescription().getTimestamp();
+        nativeOnPrimaryClipTimestampInvalidated(mNativeClipboard, timestamp);
+    }
+
     private native void nativeOnPrimaryClipChanged(long nativeClipboardAndroid);
+    private native void nativeOnPrimaryClipTimestampInvalidated(
+            long nativeClipboardAndroid, long timestamp);
 }
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc
index 40730c1..4f6fc493 100644
--- a/ui/base/clipboard/clipboard_android.cc
+++ b/ui/base/clipboard/clipboard_android.cc
@@ -47,12 +47,14 @@
  public:
   ClipboardMap();
   void SetModifiedCallback(ClipboardAndroid::ModifiedCallback cb);
+  void SetJavaSideNativePtr(Clipboard* clipboard);
   std::string Get(const std::string& format);
   uint64_t GetSequenceNumber() const;
   base::Time GetLastModifiedTime() const;
   void ClearLastModifiedTime();
   bool HasFormat(const std::string& format);
   void OnPrimaryClipboardChanged();
+  void OnPrimaryClipTimestampInvalidated(int64_t timestamp_ms);
   void Set(const std::string& format, const std::string& data);
   void CommitToAndroidClipboard();
   void Clear();
@@ -96,6 +98,12 @@
   modified_cb_ = std::move(cb);
 }
 
+void ClipboardMap::SetJavaSideNativePtr(Clipboard* clipboard) {
+  JNIEnv* env = AttachCurrentThread();
+  Java_Clipboard_setNativePtr(env, clipboard_manager_,
+                              reinterpret_cast<intptr_t>(clipboard));
+}
+
 std::string ClipboardMap::Get(const std::string& format) {
   base::AutoLock lock(lock_);
   UpdateFromAndroidClipboard();
@@ -127,6 +135,15 @@
   map_state_ = MapState::kOutOfDate;
 }
 
+void ClipboardMap::OnPrimaryClipTimestampInvalidated(int64_t timestamp_ms) {
+  base::Time timestamp = base::Time::FromJavaTime(timestamp_ms);
+  if (GetLastModifiedTime() < timestamp) {
+    sequence_number_++;
+    UpdateLastModifiedTime(timestamp);
+    map_state_ = MapState::kOutOfDate;
+  }
+}
+
 void ClipboardMap::Set(const std::string& format, const std::string& data) {
   base::AutoLock lock(lock_);
   map_[format] = data;
@@ -243,6 +260,13 @@
   g_map.Get().OnPrimaryClipboardChanged();
 }
 
+void ClipboardAndroid::OnPrimaryClipTimestampInvalidated(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& obj,
+    const jlong j_timestamp_ms) {
+  g_map.Get().OnPrimaryClipTimestampInvalidated(j_timestamp_ms);
+}
+
 void ClipboardAndroid::SetModifiedCallback(ModifiedCallback cb) {
   g_map.Get().SetModifiedCallback(std::move(cb));
 }
@@ -254,6 +278,7 @@
 
 ClipboardAndroid::ClipboardAndroid() {
   DCHECK(CalledOnValidThread());
+  g_map.Get().SetJavaSideNativePtr(this);
 }
 
 ClipboardAndroid::~ClipboardAndroid() {
@@ -463,11 +488,4 @@
   g_map.Get().Set(format.ToString(), std::string(data_data, data_len));
 }
 
-// Returns a pointer to the current ClipboardAndroid object.
-static jlong JNI_Clipboard_Init(
-    JNIEnv* env,
-    const base::android::JavaParamRef<jobject>& obj) {
-  return reinterpret_cast<intptr_t>(Clipboard::GetForCurrentThread());
-}
-
-} // namespace ui
+}  // namespace ui
diff --git a/ui/base/clipboard/clipboard_android.h b/ui/base/clipboard/clipboard_android.h
index aaa1019..ca4539f 100644
--- a/ui/base/clipboard/clipboard_android.h
+++ b/ui/base/clipboard/clipboard_android.h
@@ -30,6 +30,15 @@
   void OnPrimaryClipChanged(JNIEnv* env,
                             const base::android::JavaParamRef<jobject>& obj);
 
+  // Called by Java when the Java Clipboard is notified that the window focus
+  // has changed. Since Chrome will not receive OnPrimaryClipChanged call from
+  // Android if Chrome is in background,Clipboard handler needs to check the
+  // content of clipboard didn't change, when Chrome is back in foreground.
+  void OnPrimaryClipTimestampInvalidated(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& obj,
+      const jlong j_timestamp_ms);
+
   // Sets the callback called whenever the clipboard is modified.
   COMPONENT_EXPORT(BASE_CLIPBOARD)
   void SetModifiedCallback(ModifiedCallback cb);
diff --git a/ui/compositor/compositor_switches.cc b/ui/compositor/compositor_switches.cc
index 842a3dc..dfedaea 100644
--- a/ui/compositor/compositor_switches.cc
+++ b/ui/compositor/compositor_switches.cc
@@ -9,12 +9,6 @@
 
 namespace switches {
 
-// Enable compositing individual elements via hardware overlays when
-// permitted by device.
-// Setting the flag to "single-fullscreen" will try to promote a single
-// fullscreen overlay and use it as main framebuffer where possible.
-const char kEnableHardwareOverlays[] = "enable-hardware-overlays";
-
 // Forces tests to produce pixel output when they normally wouldn't.
 const char kEnablePixelOutputInTests[] = "enable-pixel-output-in-tests";
 
diff --git a/ui/compositor/compositor_switches.h b/ui/compositor/compositor_switches.h
index d1abbfe..c1a67ec 100644
--- a/ui/compositor/compositor_switches.h
+++ b/ui/compositor/compositor_switches.h
@@ -10,7 +10,6 @@
 
 namespace switches {
 
-COMPOSITOR_EXPORT extern const char kEnableHardwareOverlays[];
 COMPOSITOR_EXPORT extern const char kEnablePixelOutputInTests[];
 COMPOSITOR_EXPORT extern const char kUIEnableRGBA4444Textures[];
 COMPOSITOR_EXPORT extern const char kUIEnableZeroCopy[];
diff --git a/ui/shell_dialogs/BUILD.gn b/ui/shell_dialogs/BUILD.gn
index b12b525..935723a2 100644
--- a/ui/shell_dialogs/BUILD.gn
+++ b/ui/shell_dialogs/BUILD.gn
@@ -82,27 +82,6 @@
   }
 }
 
-if (is_mac) {
-  mac_xib_bundle_data("shell_dialogs_unittests_xibs") {
-    testonly = true
-    sources = [
-      "//chrome/app/nibs/SaveAccessoryView.xib",
-    ]
-  }
-
-  mac_framework_bundle("shell_dialogs_unittests_bundle") {
-    testonly = true
-    framework_version = "S"
-    framework_contents = [ "Resources" ]
-    info_plist = "//ui/base/test/framework-Info.plist"
-    deps = [
-      ":shell_dialogs_unittests_xibs",
-      "//ui/resources:ui_test_pak_bundle_data",
-    ]
-    extra_substitutions = [ "CHROMIUM_BUNDLE_ID=$target_name" ]
-  }
-}
-
 test("shell_dialogs_unittests") {
   testonly = true
   sources = [
@@ -122,8 +101,4 @@
     "//ui/resources:ui_test_pak_data",
     "//ui/strings",
   ]
-
-  if (is_mac) {
-    deps += [ ":shell_dialogs_unittests_bundle" ]
-  }
 }
diff --git a/ui/shell_dialogs/run_all_unittests.cc b/ui/shell_dialogs/run_all_unittests.cc
index f5d80c1..e3c12ce5 100644
--- a/ui/shell_dialogs/run_all_unittests.cc
+++ b/ui/shell_dialogs/run_all_unittests.cc
@@ -13,8 +13,6 @@
 #include "ui/base/ui_base_paths.h"
 
 #if defined(OS_MACOSX)
-#include "base/files/file_path.h"
-#include "base/mac/bundle_locations.h"
 #include "base/test/mock_chrome_application_mac.h"
 #endif
 
@@ -41,13 +39,6 @@
 
 #if defined(OS_MACOSX)
   mock_cr_app::RegisterMockCrApp();
-
-  // Set up framework bundle so that tests on Mac can access nib files.
-  base::FilePath path;
-  base::PathService::Get(base::DIR_EXE, &path);
-  path = path.Append(
-      FILE_PATH_LITERAL("shell_dialogs_unittests_bundle.framework"));
-  base::mac::SetOverrideFrameworkBundlePath(path);
 #endif
 
   // Setup resource bundle.
@@ -62,9 +53,6 @@
 void ShellDialogsTestSuite::Shutdown() {
   ui::ResourceBundle::CleanupSharedInstance();
 
-#if defined(OS_MACOSX)
-  base::mac::SetOverrideFrameworkBundle(NULL);
-#endif
   base::TestSuite::Shutdown();
 }
 
diff --git a/ui/shell_dialogs/select_file_dialog_mac.mm b/ui/shell_dialogs/select_file_dialog_mac.mm
index 4851a771..5d888a5 100644
--- a/ui/shell_dialogs/select_file_dialog_mac.mm
+++ b/ui/shell_dialogs/select_file_dialog_mac.mm
@@ -12,13 +12,12 @@
 #include "base/files/file_util.h"
 #include "base/i18n/case_conversion.h"
 #include "base/logging.h"
-#include "base/mac/bundle_locations.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
-#import "ui/base/cocoa/nib_loading.h"
+#import "ui/base/cocoa/controls/textfield_utils.h"
 #include "ui/base/cocoa/remote_views_window.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "ui/shell_dialogs/select_file_policy.h"
@@ -50,6 +49,42 @@
                                  base::i18n::ToUpper(ext_name), ext_name);
 }
 
+base::scoped_nsobject<NSView> CreateAccessoryView() {
+  static constexpr CGFloat kControlPadding = 2;
+
+  base::scoped_nsobject<NSView> view(
+      [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 350, 60)]);
+
+  // Create the label and center it vertically.
+  NSTextField* label = [TextFieldUtils
+      labelWithString:l10n_util::GetNSString(
+                          IDS_SAVE_PAGE_FILE_FORMAT_PROMPT_MAC)];
+  [label sizeToFit];
+  NSRect label_frame = [label frame];
+  label_frame.origin =
+      NSMakePoint(kControlPadding, NSMidY([view frame]) - NSMidY(label_frame));
+  [label setFrame:label_frame];
+  [view addSubview:label];
+
+  // Create the pop-up button, positioning it to the right of the label.
+  // Its X position needs to be slightly below the label's, so that the text
+  // baselines are aligned.
+  base::scoped_nsobject<NSPopUpButton> pop_up_button([[NSPopUpButton alloc]
+      initWithFrame:NSMakeRect(NSWidth(label_frame) + kControlPadding,
+                               NSMinY(label_frame) - 5, 230, 25)
+          pullsDown:NO]);
+  [pop_up_button setTag:kFileTypePopupTag];
+  [view addSubview:pop_up_button.get()];
+
+  // Resize the containing view to fit the controls.
+  CGFloat total_width = NSMaxX([pop_up_button frame]);
+  NSRect view_frame = [view frame];
+  view_frame.size.width = total_width + kControlPadding;
+  [view setFrame:view_frame];
+
+  return view;
+}
+
 }  // namespace
 
 // A bridge class to act as the modal delegate to the save/open sheet and send
@@ -305,10 +340,8 @@
     int file_type_index,
     const base::FilePath::StringType& default_extension) {
   DCHECK(file_types);
-  NSView* accessory_view = ui::GetViewFromNib(@"SaveAccessoryView");
-  if (!accessory_view)
-    return base::scoped_nsobject<ExtensionDropdownHandler>();
-  [dialog setAccessoryView:accessory_view];
+  base::scoped_nsobject<NSView> accessory_view = CreateAccessoryView();
+  [dialog setAccessoryView:accessory_view.get()];
 
   NSPopUpButton* popup = [accessory_view viewWithTag:kFileTypePopupTag];
   DCHECK(popup);
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd
index bcedfbf..1b1cccc3 100644
--- a/ui/strings/ui_strings.grd
+++ b/ui/strings/ui_strings.grd
@@ -335,6 +335,9 @@
       </message>
 
       <if expr="is_macosx">
+        <message name="IDS_SAVE_PAGE_FILE_FORMAT_PROMPT_MAC" desc="The title of the File Format label for saving a page.">
+          Format:
+        </message>
         <message name="IDS_SELECT_FOLDER_BUTTON_TITLE" desc="The name of the Select button in the folder selection dialog.">
           Select
         </message>